jQuery鼠标事件阻止默认传播

时间:2017-06-04 11:45:03

标签: javascript jquery event-propagation

单击任何链接时,我遇到全身叠加效果问题。

想要的效果是:

  1. 当页面的任何链接被“推送”(mousedown或touchstart)时,图像叠加显示在整个主体的顶部(隐藏页面的完整内容)
  2. 当链接(或应该)被“释放”(mouseup或touchend)时,叠加层应该消失,并且应该发生原始点击的链接目标(例如,必须遵循“href”属性)。
  3. 第一部分是OK:我添加了一个事件处理程序,在每个链接上监听“mousedown touchstart”事件。第二部分更复杂,因为覆盖不会触发链接的“释放”动作(覆盖在链接的内容上)。所以我在整个文档上附加了一个“mousedown touchend”事件处理程序,它可以工作,但点击链接的默认行为(例如转到它的“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以更清楚地展示它。

    有人知道这里有什么错误吗?我的逻辑错了吗?

3 个答案:

答案 0 :(得分:2)

问题是由jQuery执行.click()的方式引起的。它是jQuery的trigger('click')方法的捷径,这就是documentation所说的:

  

虽然.trigger()模拟事件激活,但是使用合成事件对象,它并不能完美地复制自然发生的事件。

解决方案是在DOM元素本身上调用click方法。似乎MDN documentation宣布同样的限制适用于该方法:

  

HTMLElement.click()方法模拟鼠标单击元素。

     

但是,click()方法不会启动<a>元素的导航。

...但在尝试使用当前版本的Firefox,Chrome和Edge时,DOM click方法启动<a>导航(同时{{} 1}}有一个href网址。

所以,改变一下:

http

为:

overlay_triggered = $target;

并改变这一点(无论如何都是过度杀伤):

overlay_triggered = evt.target;

为:

$(overlay_triggered).click();

请参阅updated jsfiddle

答案 1 :(得分:0)

我不确定为什么这不起作用,但我通过将$(overlay_triggered).click();更改为window.location = $(overlay_triggered).attr("href");来实现它

答案 2 :(得分:0)

我稍微修改了你的JS部分,现在一切都还好 我所做的是将一个目标的href值保存在一个变量中(我将目标的href值存储在下面代码中的'href'变量中),之后是“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>