如何从手动触发的 mousedown 触发点击事件?

How to make click event trigger from a mousedown that was triggered manually?

我目前有一个弹出式上下文菜单。当您在其外部单击时,此弹出窗口将关闭。

这是通过占据整个 window 的弹出窗口后面的 div 完成的,并监听 mousedown 事件。

我需要将此鼠标事件发送到图层后面页面上的元素,所以我在这些元素上调用 trigger()

function onLayerMouseDown(e) {
  layer.hide();
  $("#menu").hide();
  target = document.elementFromPoint(e.pageX - $(window).scrollLeft(), e.pageY - $(window).scrollTop());
  if (target != null)
    $(target).trigger(e);

这对 mousedownmouseup 事件很有效,但是 click 事件永远不会发送,当鼠标在不离开元素的情况下按下和释放时会发生。

我怎样才能让点击事件也被发送?

有关图层的示例,请参阅 this fiddle。在菜单打开时单击后面的文本,然后查看控制台。

这个问题很容易理解,但解决方案将取决于您的要求。发送 mousedown 事件后,脚本所做的第一件事就是隐藏 layer。这意味着它将不再检测鼠标事件。这意味着不会发出 click 事件,无论是 layer(点击事件需要在同一元素内使用 mouseup)还是 insidemousedown 收到的事件是副本,来自 layer)。重要的是要注意 click 事件是由浏览器管理的。您不能通过仅发送 mousedown 然后发送 mouseup 来触发 click。这也解释了为什么 inside 收到 mouseup 事件,因为此事件仅在 layer 消失后发生。

关于如何解决,你可能:

  • 设置layermousedown函数来处理click事件。使用此设计,这意味着 mousedownmouseup 不会被捕获。
  • 更改设计。这个想法是将 layerpointer-events 设置为 none:

$("#inside").on("mousedown", (e) => {
    console.log("inside mousedown (triggered manually from the layer)");
});
$("#inside").on("click", (e) => {
    console.log("inside click (should happen right before mousup, if the mouse stayed inside the element");
});
$("#inside").on("mouseup", (e) => {
    console.log("inside mouseup (triggered automatically when releasing mouse button)");
});

$("#button").click(() => {
    createlayer();
  return false;
});


$(document).on('click', layermousedown);

$("#menu").click(() =>{return false});

function layermousedown(e) {
    $("#layer").hide();
    $("#menu").hide();
    $("#button").prop('disabled', false);
}

function createlayer() {
    $("#button").prop('disabled', true);
  $("#layer").show();
  $("#menu").show();
  console.log("added the invisible layer");
  console.log("_______________________");
}
createlayer();
#layer {
  height: 100vh;
  width: 100vw;
  display: block;
  position: fixed;
  z-index: 1;
  top: 0;
  left: 0;
  opacity: 0;
  filter: alpha(opacity=0);
  background-color: #000;
  pointer-events: none;
}

#menu {
  display: block;
  position: fixed;
  z-index: 2;
  top: 20px;
  left: 50px;
  background-color: #ff5;
  width: 50px;
  height: 100px;
  border: 1px solid black;
  pointer-events: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="outer">
  <span id="inside">click me please</span>
</div>
<div id="layer"></div>
<button id="button">
Add the layer again
</button>
<div id="menu">
<span>this is part of the menu</span>
</div>

思路是响应document事件,拦截元素中不应响应的click事件。这就是为什么一些回调 return false.