jQuery 鼠标事件阻止默认传播

jQuery mouse event blocks default propagation

我在点击任何 link 时遇到全身叠加效果的问题。

想要的效果是:

  1. 当页面的任意link"pushed"(mousedown或touchstart)时,图像叠加出现在整个正文的顶部(隐藏页面的完整内容)
  2. 当 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> 导航(当 hrefhttp URL 时也是如此)。

所以,改变这个:

overlay_triggered = $target;

至:

overlay_triggered = evt.target;

并更改此设置(无论如何都太过分了):

$(overlay_triggered).click();

至:

overlay_triggered.click();

参见updated jsfiddle