如何从手动触发的 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);
这对 mousedown
和 mouseup
事件很有效,但是 click
事件永远不会发送,当鼠标在不离开元素的情况下按下和释放时会发生。
我怎样才能让点击事件也被发送?
有关图层的示例,请参阅 this fiddle。在菜单打开时单击后面的文本,然后查看控制台。
这个问题很容易理解,但解决方案将取决于您的要求。发送 mousedown
事件后,脚本所做的第一件事就是隐藏 layer
。这意味着它将不再检测鼠标事件。这意味着不会发出 click
事件,无论是 layer
(点击事件需要在同一元素内使用 mouseup
)还是 inside
(mousedown
收到的事件是副本,来自 layer
)。重要的是要注意 click
事件是由浏览器管理的。您不能通过仅发送 mousedown
然后发送 mouseup
来触发 click
。这也解释了为什么 inside
收到 mouseup
事件,因为此事件仅在 layer
消失后发生。
关于如何解决,你可能:
- 设置
layermousedown
函数来处理click
事件。使用此设计,这意味着 mousedown
和 mouseup
不会被捕获。
- 更改设计。这个想法是将
layer
的 pointer-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
.
我目前有一个弹出式上下文菜单。当您在其外部单击时,此弹出窗口将关闭。
这是通过占据整个 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);
这对 mousedown
和 mouseup
事件很有效,但是 click
事件永远不会发送,当鼠标在不离开元素的情况下按下和释放时会发生。
我怎样才能让点击事件也被发送?
有关图层的示例,请参阅 this fiddle。在菜单打开时单击后面的文本,然后查看控制台。
这个问题很容易理解,但解决方案将取决于您的要求。发送 mousedown
事件后,脚本所做的第一件事就是隐藏 layer
。这意味着它将不再检测鼠标事件。这意味着不会发出 click
事件,无论是 layer
(点击事件需要在同一元素内使用 mouseup
)还是 inside
(mousedown
收到的事件是副本,来自 layer
)。重要的是要注意 click
事件是由浏览器管理的。您不能通过仅发送 mousedown
然后发送 mouseup
来触发 click
。这也解释了为什么 inside
收到 mouseup
事件,因为此事件仅在 layer
消失后发生。
关于如何解决,你可能:
- 设置
layermousedown
函数来处理click
事件。使用此设计,这意味着mousedown
和mouseup
不会被捕获。 - 更改设计。这个想法是将
layer
的pointer-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
.