CSS 点击 div 到底层元素

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3680429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:44:51  来源:igfitidea点击:

Click through div to underlying elements

css

提问by Ryan

I have a divthat has background:transparent, along with border. Underneath this div, I have more elements.

我有一个div具有background:transparent,沿border。在这之下div,我有更多的元素。

Currently, I'm able to click the underlying elements when I click outside of the overlay div. However, I'm unable to click the underlying elements when clicking directly on the overlay div.

目前,当我在 overlay 之外单击时,我可以单击底层元素div。但是,当直接单击 overlay 时,我无法单击底层元素div

I want to be able to click through this divso that I can click on the underlying elements.

我希望能够点击它,div以便我可以点击底层元素。

My Problem

我的问题

回答by LawrenceKSRealEstate

Yes, you CANdo this.

是的,你CAN做到这一点。

Using pointer-events: nonealong with CSS conditional statements for IE11 (does not work in IE10 or below), you can get a cross browser compatible solution for this problem.

使用pointer-events: none与IE11 CSS条件语句一起(在IE10或低于不工作),就可以得到这个问题的跨浏览器兼容的解决方案。

Using AlphaImageLoader, you can even put transparent .PNG/.GIFs in the overlay divand have clicks flow through to elements underneath.

使用AlphaImageLoader,您甚至可以将透明的.PNG/.GIFs 放在叠加层中,div并让点击流到下面的元素。

CSS:

CSS:

pointer-events: none;
background: url('your_transparent.png');

IE11 conditional:

IE11 条件:

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='your_transparent.png', sizingMethod='scale');
background: none !important;

Here is a basic example pagewith all the code.

这是一个包含所有代码的基本示例页面

回答by Allisone

Also nice to know...
You can disable pointer-events in a parent element (probably transparent div) but have it still enabled for its child elements.
This is helpful if you work with multiple overlapping div layers, where you want to be able to click child elements, while having the parent layers not react on any mouse events at all.

也很高兴知道...
您可以在父元素(可能是透明 div)中禁用指针事件,但仍为其子元素启用它。
如果您使用多个重叠的 div 层,您希望能够单击子元素,同时让父层根本不对任何鼠标事件做出反应,这将很有帮助。

For this all parenting divs get pointer-events: noneand its clickable children get pointer-events reenabled by pointer-events: auto

为此,所有育儿 divpointer-events: none及其可点击的孩子都可以通过以下方式重新启用指针事件pointer-events: auto

.parent {
    pointer-events:none;        
}
.child {
    pointer-events:auto;
}

<div class="some-container">
   <ul class="layer-0 parent">
     <li class="click-me child"></li>
     <li class="click-me child"></li>
   </ul>

   <ul class="layer-1 parent">
     <li class="click-me-also child"></li>
     <li class="click-me-also child"></li>
   </ul>
</div>

回答by Vladimir Prodan

Allowing the user to click through a divto the underlying element depends on the browser. All modern browsers, including Firefox, Chrome, Safari, and Opera, understand pointer-events:none.

允许用户点击div底层元素取决于浏览器。所有现代浏览器,包括 Firefox、Chrome、Safari 和 Opera,都可以理解pointer-events:none.

For IE, it depends on the background. If the background is transparent, clickthrough works without you needing to do anything. On the other hand, for something like background:white; opacity:0; filter:Alpha(opacity=0);, IE needs manual event forwarding.

对于 IE,这取决于背景。如果背景是透明的,则无需执行任何操作即可进行点击。另一方面,对于像background:white; opacity:0; filter:Alpha(opacity=0);,IE 需要手动事件转发。

See a JSFiddle testand CanIUse pointer events.

请参阅JSFiddle 测试CanIUse 指针事件

回答by Tim

I'm adding this answer because I didn't see it here in full. I was able to do this using elementFromPoint. So basically:

我添加这个答案是因为我没有在这里完整地看到它。我能够使用 elementFromPoint 做到这一点。所以基本上:

  • attach a click to the div you want to be clicked through
  • hide it
  • determine what element the pointer is on
  • fire the click on the element there.
  • 将点击附加到您想要点击的 div
  • 把它藏起来
  • 确定指针所在的元素
  • 点击那里的元素。
var range-selector= $("")
    .css("position", "absolute").addClass("range-selector")
    .appendTo("")
    .click(function(e) {
        _range-selector.hide();

        $(document.elementFromPoint(e.clientX,e.clientY)).trigger("click");
    });

In my case the overlaying div is absolutely positioned—I am not sure if this makes a difference. This works on IE8/9, Safari Chrome and Firefox at least.

在我的例子中,覆盖的 div 是绝对定位的——我不确定这是否有区别。这至少适用于 IE8/9、Safari Chrome 和 Firefox。

回答by wcloister

  1. Hide overlaying the element
  2. Determine cursor coordinates
  3. Get element on those coordinates
  4. Trigger click on element
  5. Show overlaying element again
  1. 隐藏覆盖元素
  2. 确定光标坐标
  3. 获取这些坐标上的元素
  4. 触发元素点击
  5. 再次显示叠加元素
$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});

回答by Matthew Grima

I needed to do this and decided to take this route:

我需要这样做并决定采取这条路线:

$('.overlay').click(function(e){
    var left = $(window).scrollLeft();
    var top = $(window).scrollTop();

    //hide the overlay for now so the document can find the underlying elements
    $(this).css('display','none');
    //use the current scroll position to deduct from the click position
    $(document.elementFromPoint(e.pageX-left, e.pageY-top)).click();
    //show the overlay again
    $(this).css('display','block');
});

回答by B.F.

I currently work with canvas speech balloons. But because the balloon with the pointer is wrapped in a div, some links under it aren't click able anymore. I cant use extjs in this case. See basic example for my speech balloon tutorialrequires HTML5

我目前使用画布语音气球。但是因为带有指针的气球被包裹在一个 div 中,所以它下面的一些链接不再能够点击。在这种情况下我不能使用 extjs。 请参阅我的语音气球教程的基本示例需要 HTML5

So I decided to collect all link coordinates from inside the balloons in an array.

所以我决定从一个数组中的气球内部收集所有链接坐标。

var clickarray=[];
function getcoo(thatdiv){
         thatdiv.find(".link").each(function(){
                 var offset=$(this).offset();           
                 clickarray.unshift([(offset.left),
                                     (offset.top),
                                     (offset.left+$(this).width()),
                                     (offset.top+$(this).height()),
                                     ($(this).attr('name')),
                                     1]);
                                     });
         }

I call this function on each (new) balloon. It grabs the coordinates of the left/top and right/down corners of a link.class - additionally the name attribute for what to do if someone clicks in that coordinates and I loved to set a 1 which means that it wasn't clicked jet. And unshift this array to the clickarray. You could use push too.

我在每个(新)气球上调用这个函数。它获取链接的左/上角和右/下角的坐标。另外还有 name 属性,如果有人点击该坐标,我喜欢设置一个 1 这意味着它没有被点击 jet . 并将此数组取消移动到 clickarray。你也可以使用推送。

To work with that array:

要使用该数组:

$("body").click(function(event){
          event.preventDefault();//if it is a a-tag
          var x=event.pageX;
          var y=event.pageY;
          var job="";
          for(var i in clickarray){
              if(x>=clickarray[i][0] && x<=clickarray[i][2] && y>=clickarray[i][1] && y<=clickarray[i][3] && clickarray[i][5]==1){
                 job=clickarray[i][4];
                 clickarray[i][5]=0;//set to allready clicked
                 break;
                }
             }
          if(job.length>0){   
             // --do some thing with the job --
            }
          });

This function proofs the coordinates of a body click event or whether it was already clicked and returns the name attribute. I think it is not necessary to go deeper, but you see it is not that complicate. Hope in was enlish...

这个函数证明一个身体点击事件的坐标或者它是否已经被点击并返回 name 属性。我认为没有必要更深入,但你看它并没有那么复杂。希望是英文...

回答by Adam

Another idea to try (situationally) would be to:

尝试(在特定情况下)的另一个想法是:

  1. Put the content you want in a div;
  2. Put the non-clicking overlay over the entire page with a z-index higher,
  3. make another cropped copy of the original div
  4. overlay and abs position the copy div in the same place as the original content you want to be clickable with an even higher z-index?
  1. 把你想要的内容放在一个div里;
  2. 将非点击覆盖放在整个页面上,z-index 更高,
  3. 制作原始 div 的另一个裁剪副本
  4. 覆盖和 abs 将复制 div 放置在与您希望使用更高 z-index 可点击的原始内容相同的位置?

Any thoughts?

有什么想法吗?

回答by lincolnk

it doesn't work that way. the work around is to manually check the coordinates of the mouse click against the area occupied by each element.

它不会那样工作。解决方法是手动检查鼠标单击每个元素所占区域的坐标。

area occupied by an element can found found by 1. getting the location of the element with respect to the top left of the page, and 2. the width and the height. a library like jQuery makes this pretty simple, although it can be done in plain js. adding an event handler for mousemoveon the documentobject will provide continuous updates of the mouse position from the top and left of the page. deciding if the mouse is over any given object consists of checking if the mouse position is between the left, right, top and bottom edges of an element.

元素占用的区域可以通过 1. 获取元素相对于页面左上角的位置,以及 2. 宽度和高度找到。像 jQuery 这样的库使这变得非常简单,尽管它可以在普通的 js 中完成。mousemovedocument对象上添加事件处理程序将从页面的顶部和左侧提供鼠标位置的连续更新。决定鼠标是否在任何给定对象上包括检查鼠标位置是否在元素的左、右、上和下边缘之间。

回答by bobince

Nope, you can't click ‘through' an element. You can get the co-ordinates of the click and try to work out what element was underneath the clicked element, but this is really tedious for browsers that don't have document.elementFromPoint. Then you still have to emulate the default action of clicking, which isn't necessarily trivial depending on what elements you have under there.

不,你不能点击“通过”一个元素。您可以获取点击的坐标并尝试找出被点击元素下方的元素,但这对于没有document.elementFromPoint. 然后你仍然需要模拟点击的默认动作,这不一定是微不足道的,这取决于你在那里有什么元素。

Since you've got a fully-transparent window area, you'll probably be better off implementing it as separate border elements around the outside, leaving the centre area free of obstruction so you can really just click straight through.

因为你有一个完全透明的窗口区域,你可能最好将它作为外部的单独边框元素来实现,让中心区域没有障碍物,这样你就可以直接点击。