通过div单击底层元素

我有一个div,它有background:transparentborder。在这个div下面,我有更多的元素。

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

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

我的问题

928908 次浏览

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

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

不,您不能单击“通过”元素。您可以获取单击的坐标并尝试找出单击元素下方的元素,但这对于没有document.elementFromPoint的浏览器来说真的很乏味。然后您仍然必须模拟单击的默认操作,这并不一定是微不足道的,具体取决于您在那里有什么元素。

由于你有一个完全透明的窗口区域,你可能会更好地将其实现为外部的单独边界元素,使中心区域不受阻碍,这样你就可以直接点击。

是的,你可以这样做。

使用pointer-events: none以及IE11的CSS条件语句(在IE10或更低版本中不起作用),您可以为此问题获得跨浏览器兼容的解决方案。

使用AlphaImageLoader,您甚至可以将透明的.PNG/.GIF放在叠加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;

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

我认为您可以考虑更改您的标记。如果我没有错,您想在文档上方放置一个不可见层,并且您的不可见标记可能在您的文档图像之前(这是正确的吗?)。

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

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

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

希望这有帮助。有关CSS定位的更多信息,请参阅这里

我目前使用画布语音气球。但是因为带有指针的气球被包裹在一个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的左/上角和右/下角的坐标——另外还有name属性,用于如果有人点击该坐标,我喜欢设置1,这意味着它不是点击的喷气式飞机。并将此数组撤消到点击数组。你也可以使用推送。

要使用该数组:

$("body").click(function(event){event.preventDefault();//if it is a a-tagvar 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 clickedbreak;}}if(job.length>0){// --do some thing with the job --}});

此函数证明主体单击事件的坐标或是否已经单击并返回name属性。我认为没有必要深入,但你看它并没有那么复杂。希望在英国…

我添加这个答案是因为我没有在这里完整地看到它。我可以使用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,SafariChrome和Firefox。

我需要这样做,并决定走这条路:

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

允许用户通过div单击底层元素取决于浏览器。所有现代浏览器,包括Firefox、Chrome、Safari和Opera,都理解#1

对于IE来说,这取决于背景。如果背景是透明的,你无需做任何事情就可以点击通过。另一方面,对于background:white; opacity:0; filter:Alpha(opacity=0);之类的东西,IE需要手动事件转发。

jsfiddle测试可以使用指针事件

您可以放置AP覆盖,例如…

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

只要把它放在你不想夹的地方就行了。

  1. 隐藏覆盖元素
  2. 确定光标坐标
  3. 找到坐标上的元素
  4. 触发单击元素
  5. 再次显示覆盖元素
$('#elementontop').click(e => {$('#elementontop').hide();$(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");$('#elementontop').show();});

另一个尝试(情境)的想法是:

  1. 将您想要的内容放在div中;
  2. 将非点击覆盖在整个页面上,并将z索引提高,
  3. 制作原始div的另一个裁剪副本
  4. 叠加和abs将复制div放置在与原始内容相同的位置,您希望使用更高的z索引可点击?

有什么想法吗?

例如,只需将a标记围绕所有超文本标记语言提取

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

在我的例子中,我的标题类有悬停效果,使用指针事件:无;你就会输

包装内容将保留您的悬停效果,您可以单击所有图片,包括div,问候!

是的,您可以强制重叠层通过(忽略)单击事件。
加上你可以有特定的孩子被排除在这种行为之外…

你可以这样做,使用pointer-events

pointer-events影响对click-、tab、scroll-und hover事件的反应。


在一个应该忽略/传递你设置的提到的事件的层中

pointer-events: none;

需要再次响应鼠标/点击事件的无响应层的子级需要:

pointer-events: auto;

如果您使用多个重叠的div层(可能有些父层是透明的),第二部分非常有用,您需要能够单击子元素并且仅单击该子元素。

示例用法:

.parent {pointer-events:none;}.child {pointer-events:auto;}
<div class="parent"><a href="#">I'm unresponsive</a><a href="#" class="child">I'm clickable again, wohoo !</a></div>

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

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

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

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

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

我有一个图像,我隐藏在页面加载和显示时等待AJAX调用,然后再次隐藏然而…

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

我尝试了所有隐藏图像的方法,包括CSS显示=无/块,不透明度=0,使用隐藏=true隐藏图像。所有这些方法都导致我的图像被隐藏,但显示它的区域就像下面的东西有一个盖子一样,所以点击等不会对底层对象起作用。一旦图像在一个小DIV中,我隐藏了小DIV,图像占据的整个区域都是清晰的,只有我隐藏的DIV下的小区域受到影响,但当我把它做得足够小(10x10像素)时,问题就解决了(某种程度上)。

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

我不能总是在我的场景中使用pointer-events: none,因为我希望覆盖和底层元素都是可点击/可选择的。

DOM结构看起来像这样:

<div id="outerElement"><div id="canvas-wrapper"><canvas id="overlay"></canvas></div><!-- Omitted: element(s) behind canvas that should still be selectable --></div>

outerElementcanvas-wrappercanvas元素具有相同的大小。)

为了使画布后面的元素正常工作(例如可选择、可编辑),我使用了以下代码:

canvasWrapper.style.pointerEvents = 'none';
outerElement.addEventListener('mousedown', event => {const clickedOnElementInCanvas = yourCheck // TODO: check if the event *would* click a canvas element.if (!clickedOnElementInCanvas) {
// if necessary, add logic to deselect your canvas elements ...
wrapper.style.pointerEvents = 'none';return true;}
// Check if we emitted the event ourselves (avoid endless loop)if (event.isTrusted) {// Manually forward element to the canvasconst mouseEvent = new MouseEvent(event.type, event);canvas.dispatchEvent(mouseEvent);mouseEvent.stopPropagation();}return true;});

一些画布对象也带有输入字段,所以我也必须允许键盘事件。为此,我必须根据画布输入字段当前是否聚焦来更新pointerEvents属性:

onCanvasModified(canvas, () => {const inputFieldInCanvasActive = // TODO: Check if an input field of the canvas is active.wrapper.style.pointerEvents = inputFieldInCanvasActive  ? 'auto' : 'none';});