通过div单击底层元素


1590

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

目前,当我在叠加层外部单击时,我可以单击基础元素div。但是,当直接在叠加层上单击时,我无法单击基础元素div

我希望能够单击此按钮,div以便可以单击基础元素。

我的问题

Answers:


2612

是的,你CAN做到这一点。

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

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

CSS:

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

IE11条件:

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

这是带有所有代码的基本示例页面


7
如果我在该div上使用过渡或悬停状态怎么办?
Manticore

2
@Manticore简短答案:不能。在这种情况下,提供的答案无效。
Niels Abildgaard

10
IE11完全支持指针事件。这意味着所有现代浏览器都支持它。截至2014年底,这是一个可行的解决方案。caniuse.com/#search=pointer
Judah Gabriel Himango

如@Andy所指出的,这会中断滚动。我打开了一个单独的问题,看看是否有这个stackoverflow.com/questions/41592349/…
奥利弗·约瑟夫·阿什

1
@Manticore我发现您可以覆盖“指针事件:无;” 对于嵌套元素,因此您可以编写单击操作绕过的单击操作,并获得单击操作和结束操作,对于被覆盖的部分,您可以使用效果并单击
Luca

292

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

为此,所有育儿div pointer-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>

4
完美,这正是我所需要的!
RobbyReindeer

1
超级有帮助,谢谢
SpaceBear

43

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

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

请参阅JSFiddle测试CanIUse指针事件


20

我要添加此答案,因为我在这里没有看到完整的答案。我能够使用elementFromPoint做到这一点。所以基本上:

  • 将点击附加到您要点击的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");
    });

就我而言,覆盖div是绝对定位的-我不确定是否会有所不同。此功能至少适用于IE8 / 9,Safari浏览器和Firefox。


12
  1. 隐藏元素
  2. 确定光标坐标
  3. 在这些坐标上获取元素
  4. 触发元素点击
  5. 再次显示叠加元素
$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});

您是否忘了关闭撇号?也许$('#elementontop)应该是$('#elementontop')
johannchopin

10

我需要这样做,并决定采用以下路线:

$('.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');
});

6

我目前正在使用帆布演讲气球。但是由于带有指针的气球被包装在div中,因此它下面的某些链接不再能单击。在这种情况下,我无法使用extjs。 请参阅我的语音气球教程 需要HTML5的基本示例

因此,我决定从数组的气球中收集所有链接坐标。

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]);
                                     });
         }

我在每个(新)气球上调用此函数。它获取link.class的左/上和右/下角的坐标-另外,如果有人单击该坐标该怎么办,并且我喜欢将其设置为1表示未单击喷气机,该方法的name属性。并将此数组移至clickarray。您也可以使用推。

要使用该数组:

$("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 --
            }
          });

此函数证明正文单击事件的坐标或它是否已被单击,然后返回name属性。我认为没有必要更深入,但是您看到的并不那么复杂。希望在...


4

它不是那样的。解决方法是根据每个元素占用的区域手动检查鼠标单击的坐标。

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


2
如上所述,您可以在透明容器上使用CSS {pointer-events:none;}实现此目标。
Empereol 2012年

4

不,您不能单击“通过”元素。您可以获取点击的坐标,并尝试计算出clicked元素下方的元素,但这对于没有的浏览器来说确实很繁琐document.elementFromPoint。然后,您仍然必须模拟默认的单击操作,这不一定是琐碎的事,具体取决于您在该菜单下拥有的元素。

由于您拥有一个完全透明的窗口区域,因此最好将其实现为围绕外部的单独边框元素,从而使中心区域没有障碍,因此您实际上可以直接单击。


4

尝试(根据情况)尝试的另一种想法是:

  1. 将您想要的内容放入div;
  2. 将非点击重叠式广告放在整个页面上,并将z-index设置为更高,
  3. 再次制作原始div的裁剪副本
  4. overlay和abs将副本div与您希望以更高的z索引单击的原始内容位于同一位置?

有什么想法吗?


2

我认为您可以考虑更改标记。如果我没看错,您想在文档上方放置一个不可见的层,并且您的不可见标记可能位于文档图像的前面(对吗?)。

相反,我建议您将不可见的位置放在文档图像之后,但是将位置更改为绝对位置。

请注意,您需要一个父元素才能具有位置:相对,然后您将能够使用此想法。否则,您的绝对图层将被放置在左上角。

绝对位置元素相对于具有非静态位置的第一个父元素放置。如果找不到这样的元素,则包含的块为html

希望这可以帮助。有关CSS定位的更多信息,请参见此处


2

例如,只需将a标签包装在所有HTML摘录周围

<a href="/categories/1">
  <img alt="test1" class="img-responsive" src="/assets/photo.jpg" />
  <div class="caption bg-orange">
    <h2>
      test1
    </h2>
  </div>
</a>

在我的示例中,我的标题类具有悬停效果,即具有pointer-events:none; 你只会输

包装内容会保持您的悬停效果,您可以单击所有图片(包括div),以示问候!


好点子!thnks
Mr.Vertigo

1

您可以放置​​AP覆盖层,例如...

#overlay {
  position: absolute;
  top: -79px;
  left: -60px;
  height: 80px;
  width: 380px;
  z-index: 2;
  background: url(fake.gif);
}
<div id="overlay"></div>

只是把它放在你不想要的地方,即喜欢。全部适用。


1

一种更简单的方法是使用Data URI内联透明背景图像,如下所示:

.click-through {
    pointer-events: none;
    background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}

0

我认为event.stopPropagation();这里也应该提到。将此添加到您的按钮的单击功能。

防止事件使DOM树冒泡,防止任何父处理程序收到该事件的通知。


0

这不是该问题的精确答案,但可能有助于找到解决方法。

我有一个图像是我在页面加载时隐藏并在等待AJAX​​调用时显示,然后再次隐藏...

我发现加载页面时显示图像然后使其消失并能够在隐藏图像之前单击图像所在位置的唯一方法是将图像放入DIV中,使DIV的大小为10x10像素或更小足以防止它引起问题,然后隐藏包含的div。这使得图像在可见时会溢出div,而当div隐藏时,只有div区域会受到无法单击下方对象的影响,而不会影响DIV包含并显示的图像的整个大小。

我尝试了所有方法来隐藏图像,包括CSS display = none / block,opacity = 0,使用hidden = true隐藏图像。所有这些都导致我的图像被隐藏,但是显示该图像的区域的作用就像是在下面的内容上盖了一层盖,因此单击等操作不会对基础对象起作用。一旦图像位于微小的DIV中并且我隐藏了微小的DIV,图像占据的整个区域就清晰了,只有隐藏在DIV下的微小区域受到了影响,但是当我将其缩小时(10x10像素),问题就解决了是固定的(有点)。

我发现这对于应该是一个简单的问题来说是一个肮脏的解决方法,但是我找不到没有容器就无法以其本机格式隐藏对象的任何方法。我的对象是etc等形式的。如果有人有更好的方法,请告诉我。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.