jQuery 鼠标事件阻止默认传播
jQuery mouse event blocks default propagation
我在点击任何 link 时遇到全身叠加效果的问题。
想要的效果是:
- 当页面的任意link"pushed"(mousedown或touchstart)时,图像叠加出现在整个正文的顶部(隐藏页面的完整内容)
- 当 link 是(或应该是)"released"(mouseup 或 touchend)时,叠加层应该消失并且原始点击的 link 目标应该发生("href" 属性必须遵循例如)。
第一部分没问题:我添加了一个事件处理程序,每 link 秒监听一次 "mousedown touchstart" 事件。第二部分更复杂,因为叠加层不会触发 link 的 "release" 操作(叠加层位于 link 的内容之上)。所以我在整个文档上附加了一个 "mousedown touchend" 事件处理程序,它有效,但是点击的 link 的默认行为(例如转到它的 "href" 属性)永远不会被触发:(
这是我的 JS:
$(document).ready(function(){
// the full-page overlay selector
var $overlay = $('.body-overlay');
// a flag to keep a trace of clicked element
var overlay_triggered = false;
// the "mousedown" event handler
function show_overlay(evt)
{
var $target = $(evt.target);
if (overlay_triggered === false) {
$overlay.show();
overlay_triggered = $target;
$(document).on('mouseup touchend', hide_overlay);
}
return true;
}
// the "mouseup" event handler
function hide_overlay(evt)
{
if (overlay_triggered !== false) {
$(document).off('mouseup touchend', hide_overlay);
$overlay.hide();
// !!! - here I try to trigger a classic click but it never works
$(overlay_triggered).click();
overlay_triggered = false;
}
return true;
}
// attachment of the mousedown handler on all links
$(document).on('mousedown touchstart', 'a', show_overlay);
});
我做了一个JS Fiddle来展示的更清楚
有人知道这里有什么错误吗?我的逻辑错了吗?
我不太确定为什么这行不通,但我通过将 $(overlay_triggered).click();
更改为 window.location = $(overlay_triggered).attr("href");
使其工作
我稍微修改了你的JS部分,现在一切正常
我所做的是将目标的 href 值保存在一个变量中(我将目标的 href 值存储在下面代码中的 'href' vaiable 中),然后 "window.location = href;" 在 'hide_overlay' 函数中执行技巧.
<script>
$(document).ready(function(){
// the full-page overlay selector
var $overlay = $('.body-overlay');
// a flag to keep a trace of clicked element
var overlay_triggered = false;
var href = false;
// the "mousedown" event handler
function show_overlay(evt)
{
var $target = $(evt.target);
href = evt.target.href;
if (overlay_triggered === false) {
$overlay.show();
overlay_triggered = $target;
$(document).on('mouseup touchend', hide_overlay);
}
return true;
}
// the "mouseup" event handler
function hide_overlay(evt)
{
if (overlay_triggered !== false) {
$(document).off('mouseup touchend', hide_overlay);
$overlay.hide();
// !!! - here I try to trigger a classic click but it never works
if( href ) {
window.location = href;
}
overlay_triggered = false;
}
return true;
}
// attachment of the mousedown handler on all links
$(document).on('mousedown touchstart', 'a', show_overlay);
});
</script>
问题是由 jQuery 执行 .click()
的方式引起的。它是 jQuery 的 trigger('click')
方法的快捷方式,这就是 documentation 所说的:
Although .trigger()
simulates an event activation, complete with a synthesized event object, it does not perfectly replicate a naturally-occurring event.
解决方案是在 DOM 元素本身上调用 click
方法。 MDN documentation 似乎宣布了适用于该方法的相同限制:
The HTMLElement.click()
method simulates a mouse click on an element.
However, the click()
method will not initiate navigation on an <a>
element.
...但是在使用当前版本的 Firefox Chrome 和 Edge 进行尝试时,DOM click
方法 确实 启动 <a>
导航(当 href
有 http
URL 时也是如此)。
所以,改变这个:
overlay_triggered = $target;
至:
overlay_triggered = evt.target;
并更改此设置(无论如何都太过分了):
$(overlay_triggered).click();
至:
overlay_triggered.click();
我在点击任何 link 时遇到全身叠加效果的问题。
想要的效果是:
- 当页面的任意link"pushed"(mousedown或touchstart)时,图像叠加出现在整个正文的顶部(隐藏页面的完整内容)
- 当 link 是(或应该是)"released"(mouseup 或 touchend)时,叠加层应该消失并且原始点击的 link 目标应该发生("href" 属性必须遵循例如)。
第一部分没问题:我添加了一个事件处理程序,每 link 秒监听一次 "mousedown touchstart" 事件。第二部分更复杂,因为叠加层不会触发 link 的 "release" 操作(叠加层位于 link 的内容之上)。所以我在整个文档上附加了一个 "mousedown touchend" 事件处理程序,它有效,但是点击的 link 的默认行为(例如转到它的 "href" 属性)永远不会被触发:(
这是我的 JS:
$(document).ready(function(){
// the full-page overlay selector
var $overlay = $('.body-overlay');
// a flag to keep a trace of clicked element
var overlay_triggered = false;
// the "mousedown" event handler
function show_overlay(evt)
{
var $target = $(evt.target);
if (overlay_triggered === false) {
$overlay.show();
overlay_triggered = $target;
$(document).on('mouseup touchend', hide_overlay);
}
return true;
}
// the "mouseup" event handler
function hide_overlay(evt)
{
if (overlay_triggered !== false) {
$(document).off('mouseup touchend', hide_overlay);
$overlay.hide();
// !!! - here I try to trigger a classic click but it never works
$(overlay_triggered).click();
overlay_triggered = false;
}
return true;
}
// attachment of the mousedown handler on all links
$(document).on('mousedown touchstart', 'a', show_overlay);
});
我做了一个JS Fiddle来展示的更清楚
有人知道这里有什么错误吗?我的逻辑错了吗?
我不太确定为什么这行不通,但我通过将 $(overlay_triggered).click();
更改为 window.location = $(overlay_triggered).attr("href");
我稍微修改了你的JS部分,现在一切正常 我所做的是将目标的 href 值保存在一个变量中(我将目标的 href 值存储在下面代码中的 'href' vaiable 中),然后 "window.location = href;" 在 'hide_overlay' 函数中执行技巧.
<script>
$(document).ready(function(){
// the full-page overlay selector
var $overlay = $('.body-overlay');
// a flag to keep a trace of clicked element
var overlay_triggered = false;
var href = false;
// the "mousedown" event handler
function show_overlay(evt)
{
var $target = $(evt.target);
href = evt.target.href;
if (overlay_triggered === false) {
$overlay.show();
overlay_triggered = $target;
$(document).on('mouseup touchend', hide_overlay);
}
return true;
}
// the "mouseup" event handler
function hide_overlay(evt)
{
if (overlay_triggered !== false) {
$(document).off('mouseup touchend', hide_overlay);
$overlay.hide();
// !!! - here I try to trigger a classic click but it never works
if( href ) {
window.location = href;
}
overlay_triggered = false;
}
return true;
}
// attachment of the mousedown handler on all links
$(document).on('mousedown touchstart', 'a', show_overlay);
});
</script>
问题是由 jQuery 执行 .click()
的方式引起的。它是 jQuery 的 trigger('click')
方法的快捷方式,这就是 documentation 所说的:
Although
.trigger()
simulates an event activation, complete with a synthesized event object, it does not perfectly replicate a naturally-occurring event.
解决方案是在 DOM 元素本身上调用 click
方法。 MDN documentation 似乎宣布了适用于该方法的相同限制:
The
HTMLElement.click()
method simulates a mouse click on an element.However, the
click()
method will not initiate navigation on an<a>
element.
...但是在使用当前版本的 Firefox Chrome 和 Edge 进行尝试时,DOM click
方法 确实 启动 <a>
导航(当 href
有 http
URL 时也是如此)。
所以,改变这个:
overlay_triggered = $target;
至:
overlay_triggered = evt.target;
并更改此设置(无论如何都太过分了):
$(overlay_triggered).click();
至:
overlay_triggered.click();