ChatGPT解决这个技术问题 Extra ChatGPT

单击 div 到底层元素

我有一个具有 background:transparentborderdiv。在这个 div 下,我有更多元素。

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

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

https://i.stack.imgur.com/VDlDa.png


T
TylerH

是的,你可以这样做。

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

使用 AlphaImageLoader,您甚至可以在叠加层 div 中放置透明的 .PNG/.GIF,并让点击流向下方的元素。

CSS:

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

IE11 条件:

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

这是包含所有代码的 basic example page


IE11 完全支持指针事件。这意味着所有现代浏览器都支持它。截至 2014 年底,这是一个可行的解决方案。caniuse.com/#search=pointer-events
我认为这种通过效果也适用于完全不透明的图像。
O
OfirD

是的,您可以强制重叠图层通过(忽略)点击事件。另外,您可以将特定儿童排除在此行为之外...

您可以使用 pointer-events

指针事件影响对单击、点击、滚动和悬停事件的反应。

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

pointer-events: none; 

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

pointer-events: auto; 

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

示例用法:

.parent { 指针事件:无; } .child { 指针事件:自动; }


当有一个超级简单的解决方案时,我爱的人
Here's a more colorful version of this code,它还使用子 div 进行了演示 :)
像一个魅力... <3
M
MultiplyByZer0

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

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

请参阅 a JSFiddle testCanIUse pointer events


Safari 中同样的问题。如果底层 div 具有非透明背景,则指针事件是错误的。
j
jsea

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


L
LayneTheEpic

隐藏覆盖元素 确定光标坐标 在这些坐标上获取元素 触发点击元素 再次显示覆盖元素

$('#elementontop').click(e => {
    $('#elementontop').hide();
    $(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
    $('#elementontop').show();
});

N
Nathan Arthur

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

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

B
B.F.

我目前使用帆布语音气球。但是由于带有指针的气球被包裹在一个div中,它下面的一些链接不再可以点击了。在这种情况下我不能使用 extjs。 See basic example for my speech balloon tutorial 需要 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,这意味着它没有被点击jet .并将此数组移至 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 --
            }
          });

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


A
Adam

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

将你想要的内容放在一个div中;将非点击覆盖层放在整个页面上,z-index 更高,制作原始 div 覆盖层的另一个裁剪副本,并将复制 div 放置在与您希望以更高 z 可点击的原始内容相同的位置-指数?

有什么想法吗?


I
Ilyas karim

例如,只需将 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>

在我的示例中,我的标题类具有悬停效果,带有指针事件:无;你只会输

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


M
MathuSum Mut

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

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

b
bobince

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

由于您有一个完全透明的窗口区域,您最好将其实现为围绕外部的单独边框元素,使中心区域没有障碍物,这样您就可以直接点击。


j
julianm

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

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

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

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

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


k
kenny

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

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


I
Igor Ivancha

您可以放置一个 AP 覆盖,如...

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

把它放在你不想要的地方,即点击。在所有工作。


D
David Crawford

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

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

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

我尝试了所有隐藏图像的方法,包括 CSS display=none/block、opacity=0、用 hidden=true 隐藏图像。所有这些都导致我的图像被隐藏,但它显示的区域就像下面的东西有一个覆盖物一样,因此点击等不会作用于底层对象。一旦图像在一个小 DIV 内并且我隐藏了这个小 DIV,图像占据的整个区域都很清晰,只有我隐藏的 DIV 下的小区域受到影响,但是当我把它做得足够小(10x10 像素)时,问题是固定的(有点)。

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


D
Daniel Veihelmann

我不能总是在我的场景中使用 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 canvas
        const 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';
});

需要明确的是,这里的“画布”与 HTML5 <canvas> 无关,对吗?
l
lincolnk

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

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


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