Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 即使某个元素停止传播,我如何处理页面中任意位置的单击?_Javascript_Jquery_Events_Jquery Events - Fatal编程技术网

Javascript 即使某个元素停止传播,我如何处理页面中任意位置的单击?

Javascript 即使某个元素停止传播,我如何处理页面中任意位置的单击?,javascript,jquery,events,jquery-events,Javascript,Jquery,Events,Jquery Events,我们正在开发一个JavaScript工具,其中包含较旧的代码, 因此,我们无法重新编写整个工具 现在,在底部添加了一个固定位置的菜单,客户非常希望它有一个切换按钮来打开和关闭菜单, 但当用户开始在菜单外执行操作时(例如,当用户返回页面并选择某个内容或单击表单字段时),需要自动关闭 这在技术上可以与正文上的点击事件一起工作,任何点击都会触发, 但是,旧代码中有许多项,其中在内部链接上处理了单击事件,并将返回false添加到单击功能中,以使站点不继续使用链接的href标记 很明显,像这样的通用函数确

我们正在开发一个JavaScript工具,其中包含较旧的代码, 因此,我们无法重新编写整个工具

现在,在底部添加了一个固定位置的菜单,客户非常希望它有一个切换按钮来打开和关闭菜单, 但当用户开始在菜单外执行操作时(例如,当用户返回页面并选择某个内容或单击表单字段时),需要自动关闭

这在技术上可以与
正文
上的
点击
事件一起工作,任何点击都会触发, 但是,旧代码中有许多项,其中在内部链接上处理了单击事件,并将
返回false
添加到单击功能中,以使站点不继续使用链接的
href
标记

很明显,像这样的通用函数确实可以工作,但当单击返回false停止传播的内部链接时就不行了

$('body').click(function(){
  console.log('clicked');
});
我有没有办法强制身体点击事件, 或者有没有其他方法可以让菜单显示出来,使用一些全局单击事件或类似的事件?

无需重写应用程序中多年前创建的所有其他单击。
这将是一项艰巨的任务,特别是因为我不知道如何重写它们,而不返回false,但仍然不让它们转到它们的
href

我想这就是您需要的:

$("body").trigger("click");

这将允许您从任何位置触发body click事件。

您真正想要做的是为事件的捕获阶段绑定事件处理程序。然而,据我所知,IE中不支持这一点,所以这可能没有多大用处

相关问题:


如果您确保这是第一个事件处理程序工作,类似这样的操作可能会奏效:

$('*').click(function(event) {
    if (this === event.target) { // only fire this handler on the original element
        alert('clicked');
    }
});

请注意,如果您的页面中有很多元素,那么这将非常缓慢,而且对于动态添加的任何内容都不起作用。

现代DOM实现中的事件有两个阶段,捕获和冒泡。捕获阶段是第一阶段,从文档的
defaultView
流到事件目标,然后是冒泡阶段,从事件目标流回到
defaultView
。有关详细信息,请参阅

要处理事件的捕获阶段,需要将
addEventListener
的第三个参数设置为
true

document.body.addEventListener('click', fn, true); 
不幸的是,正如Wesley提到的,事件的捕获阶段无法可靠地处理,或者根本无法在旧浏览器中处理

一种可能的解决方案是处理
mouseup
事件,因为单击的事件顺序是:

  • 穆斯敦
  • 鼠标
  • 点击
  • 如果您可以确定没有处理程序取消
    mouseup
    事件,那么这是一种方法(可以说是更好的方法)。另一件需要注意的事情是,许多(如果不是大多数的话)(如果不是全部的话)UI菜单在鼠标按下时消失。

    与Andy E合作,这就是原力的黑暗面:

    var _old = jQuery.Event.prototype.stopPropagation;
    
    jQuery.Event.prototype.stopPropagation = function() {
        this.target.nodeName !== 'SPAN' && _old.apply( this, arguments );
    };     
    
    示例

    记住,如果所有事件都是通过jQuery绑定的,那么您可以在这里处理这些情况。在本例中,如果不处理
    ,我们只调用原始的
    .stopPropagation()


    你不能阻止阻止,不

    您可以做的是,在代码中手动重写这些事件处理程序。这是一项棘手的工作,但如果您知道如何访问存储的处理程序方法,您可以解决这个问题。我玩了一会儿,结果是:

    $( document.body ).click(function() {
        alert('Hi I am bound to the body!');
    });
    
    $( '#bar' ).click(function(e) {
        alert('I am the span and I do prevent propagation');
        e.stopPropagation();
    });
    
    $( '#yay' ).click(function() {
        $('span').each(function(i, elem) {
            var events        = jQuery._data(elem).events,
                oldHandler    = [ ],
                $elem         = $( elem );
    
            if( 'click' in events ) {                        
                [].forEach.call( events.click, function( click ) {
                    oldHandler.push( click.handler );
                });
    
                $elem.off( 'click' );
            }
    
            if( oldHandler.length ) {
                oldHandler.forEach(function( handler ) {
                    $elem.bind( 'click', (function( h ) {
                        return function() {
                            h.apply( this, [{stopPropagation: $.noop}] );
                        };
                    }( handler )));
                });
            }
        });
    
        this.disabled = 1;
        return false;
    });
    
    示例

    注意,上面的代码只适用于jQuery1.7。如果这些单击事件与早期jQuery版本或“内联”绑定,您仍然可以使用代码,但需要以不同的方式访问“旧处理程序”

    我知道我在这里假设了很多“完美世界”场景,例如,这些句柄显式调用
    .stopPropagation()
    ,而不是返回
    false
    。因此,这可能仍然是一个无用的学术例子,但我觉得要说出来:——)


    编辑:嘿,
    返回false
    可以很好地工作,事件对象也是以同样的方式访问的。

    您可以使用jQuery在文档DOM上添加事件侦听器

    $(文档)。在(“单击”)上,函数(){
    console.log('clicked');
    });
    
    这是关键(vs.evt.target)。参见示例

    document.body.addEventListener(“单击”,函数(evt){
    console.dir(this);
    //注:evt.target可以是嵌套元素,而不是主体元素,从而导致缺火
    console.log(evt.target);
    警报(“身体点击”);
    });
    
    这是一个标题。
    这是一段。

    演示


    如果dom中嵌套得更深的东西阻止了事件传播,会不会触发这种情况?我认为问题在于,单击事件被某些链接上的事件处理程序返回false吞没了,而不是一开始就无法生成单击事件。通过$(“*”)可以很容易地修复动态问题,函数(){});但无论如何,这是一个坏主意。对于任何想知道是否可以使用它的人,这里是caniuse页面:简短的回答是可以的,只要你不关心IE8
    document.body.addEventListener("keyup", function(event) {
      if (event.keyCode === 13) {
      event.preventDefault();
      console.log('clicked ;)');
    }
    });