jQuery - 触发位于元素后面的点击事件

5
我的问题是我有一个盒子,里面有用户可以点击的盒子。
为了帮助用户,我制作了灰色的覆盖盒子,告诉他们可以在这里使用盒子。
但我的问题是,点击事件是在覆盖盒子后面的盒子上。
所以有没有一种方法可以忽略元素的.click()并使用下一个目标?

1
你不能只使用选择器来定位小方块吗? - Cranio
我不理解为什么需要使用覆盖框,当你可以给实际的框分配一个“禁用”类来将其样式设置为禁用元素。这样,您的点击功能就不会受到影响。 - David Barker
3个回答

8
你可以使用CSS pointer-events 属性:

CSS属性 pointer-events 允许作者控制在什么情况下(如果有的话)特定的图形元素可以成为鼠标事件的目标。

#element {
  pointer-events: none;
}

或者您可以 触发 click 事件:

$('#box').click(function(){
   $('#target').trigger('click')
})

3
注意!我认为你会发现pointer-events在IE中不受支持 - 例如,可以在这里查看。 - Beetroot-Beetroot
@Beetroot-Beetroot 是的,IE8不支持 pointer-events 属性。 - Ram
第二篇帖子在这里表明,即使在moz浏览器中,pointer-events对于所有非SVG元素目前都不可靠。就我个人而言,除了用于SVG工作之外,我看不到自己很快会使用它。 - Beetroot-Beetroot

1
避免使用CSS的pointer-events...
首先,确保所有包含的盒子都有类名box(或类似名称)。
其次,使用.addClass('inactive')使盒子变为不活动状态(在样式表中相应地设置背景颜色和边框)。要重新激活盒子,只需使用.removeClass('inactive')即可。
第三,将对盒子的点击处理委托给容器,如下所示:
$('#container').on('click', '.box', function() {
    //common behaviour (pre)
    if($(this).hasClass("inactive")) {
        //inactive box behaviour
    }
    else {
        //active box behaviour
    }
    //common behaviour (post)
});

我遇到的问题是,我正在使用JavaScript(jQuery)的fullcalendar插件。因此,我制作了一个自定义事件,使框的宽度为原始宽度的100%,而不是较小百分比的宽度。尽管我一直在寻找一种将点击事件从我的框元素重定向到其后面的元素以触发时间的方法,但我什么也没找到。所以现在我想pointer-events是我的唯一选择,直到我幸运地在fullcalendar源中找到我需要的部分。但还是谢谢 :) - danniehansenweb
@danniehansenweb,您似乎在描述“事件冒泡”,这正是jQuery语句$('#container').on('click', '.box', function() {...});所利用的。我相信这或类似的方法是前进的方向,但如果没有看到您的HTML,我无法提供更多建议。 - Beetroot-Beetroot
您能详细解释一下为什么要避免使用 pointer-events 吗?它的支持似乎相当稳定。 - Charles Stover

0

您可以使用Ivan Castellanos开发的即时调用函数表达式(IIFE),它将检测您鼠标指针的位置(x,y),并在您选择的元素上评估该元素是否被鼠标覆盖。利用Ivan的代码,我能够创建这个概念验证,其产生的结果与pointer-events:none;相同,但在各种浏览器中略微更兼容。 它使用jQuery的.offset()方法。 在jsFiddle中,有一个页面有3个元素,其中包括两个<button>和一个<div>,该<div>以50%透明度重叠在按钮上。 在正常情况下,您将无法单击这些元素,除非调整z-index。

jsFiddle示例

//CSS Hitbox Solution 08-26-2015
//StackOverflow - https://stackoverflow.com/questions/32233084/show-an-element-without-hitbox-does-not-take-mouse-touch-input
//Detect MouseOver https://dev59.com/2XM_5IYBdhLWcg3wrFMt
//Source: https://dev59.com/vG865IYBdhLWcg3wLrhE
//https://css-tricks.com/snippets/jquery/get-x-y-mouse-coordinates/
(function($) {
  $.mlp = {
    x: 0,
    y: 0
  }; // Mouse Last Position
  function documentHandler() {
    var $current = this === document ? $(this) : $(this).contents();
    $current.mousemove(function(e) {
      jQuery.mlp = {
        x: e.pageX,
        y: e.pageY
      };
    });
    $current.find("iframe").load(documentHandler);
  }
  $(documentHandler);
  $.fn.ismouseover = function(overThis) {
    var result = false;
    this.eq(0).each(function() {
      var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
      var offset = $current.offset();
      result = offset.left <= $.mlp.x && offset.left + $current.outerWidth() > $.mlp.x && offset.top <= $.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
    });
    return result;
  };
})(jQuery);
$('.notification-box').on("click", function() {
  $("button").each(function(i) {
    var iteratedButton = $('button:eq(' + i + ')');
    var buttonID = iteratedButton.attr("id");
    if (iteratedButton.ismouseover()) {
      iteratedButton.toggleClass(buttonID);
    }
  });
});
.notification-box {
  position: absolute;
  height: 100vw;
  width: 100vw;
  background-color: black;
  opacity: 0.5;
  /*pointer-events: none;*/
  z-index: -10;
  overflow: visible;
}
button {
  position: absolute;
  top: absolute;
  width: 50px;
  z-index: -10;
}
button#no {
  margin-top: 25px;
}
.yes {
  color: red;
  font-weight: bold;
}
.no {
  color: blue;
  font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button id='yes'>Yes</button>
<button id='no'>No</button>
<div id='no' class="notification-box" />


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接