【问题标题】:stopPropagation and startPropagationstopPropagation 和 startPropagation
【发布时间】:2013-07-17 09:04:57
【问题描述】:

我想制作一个额外的点击处理程序(客户端页面,不能修改他的 js/html),它应该在我的脚本中像这样工作:

1) event.stopPropagation(暂停客户端点击传播)
2)我的功能(做我的功能,当一切都完成后做下一步)
3)event.startPropagation(继续标准客户端操作)

现在,第一部和第二部作品。第三个是问题。
我知道event.startPropagation 不存在,但我想要这样的东西。 有什么提示吗?

【问题讨论】:

    标签: javascript jquery stoppropagation


    【解决方案1】:

    您可以在父节点 f.ex (jQuery) 上重新触发相同的事件对象。您需要先复制事件对象并将其传递到触发器中,以便在气泡中捕获相同的事件属性(f.ex e.pageX):

    var copy = $.extend(true, {}, e);
    setTimeout(function() {
        $(copy.target.parentNode).trigger(copy);
    },500);
    e.stopPropagation();
    

    演示:http://jsfiddle.net/GKkth/

    编辑

    根据您的评论,我认为您正在寻找类似的东西:

    $.fn.bindFirst = function(type, handler) {
        return this.each(function() {
            var elm = this;
            var evs = $._data(this).events;
            if ( type in evs ) {
                var handlers = evs[type].map(function(ev) {
                    return ev.handler;
                });
                $(elm).unbind(type).on(type, function(e) {
                    handler.call(elm, e, function() {
                        handlers.forEach(function(fn) {
                            fn.call(elm);
                        });
                    });
                });
            }
        });
    };
    

    此原型允许您绑定一个“高级处理程序”,该处理程序包含一个next 函数,该函数将在您需要时将所有先前的处理程序执行到同一元素。 像这样使用它

    $('button').click(function() {
        console.log('first');
    }).click(function() {
        console.log('second');
    }).bindFirst('click', function(e, next) {
        console.log('do something first');
        setTimeout(next, 1000); // holds the other handlers for 1sec
    });
    

    演示:http://jsfiddle.net/BGuU3/1/

    【讨论】:

    • 好的,我尝试了很多方法都没有好的结果。也许我做错了什么。例如://客户端,他自己的点击处理程序 $('p').click(function(e) { document.location = 'onet.pl'; }); //我的脚本 $('p').click(function(e) { e.stopPropagation(); e.preventDefault(); $.get( ...., ...., function(){ //如果可以,然后执行类似 startPropagation } ) });
    • @PiotrWójcik 听起来您正在寻找stopImmediatePropagation(),因为处理程序附加到同一元素:api.jquery.com/event.stopImmediatePropagation。请记住,它不会阻止先前绑定的处理程序被执行。或者也许您只需要找到已经绑定的处理程序,保存它们并稍后在您自己的触发器中执行它们。
    • @PiotrWójcik 我用一个可能的解决方案编辑了我的答案,这是你需要的吗?
    • 不错的答案!这非常适合我想要的 - 很遗憾它显然依赖于 JQuery 的内部结构,即$._data(this) - 这可能会在版本之间发生变化。但真的很好 - 只是赞成 - 顺便说一句,大卫,如果你有一个不依赖于我认为是内部调用的版本 - 即 $._data(this) 请告诉我们:)
    • 好吧@DavidHellsing - 再次 - 可爱的答案 - 我确实有一个“骨头”可供选择 - 那是 - 我会将行 fn.call(elm); 更改为 fn.call(elm,e); - 以保留访问原始事件的其他处理程序:)如果您可以编辑上面的代码,那就太好了;)
    【解决方案2】:

    一开始就不要停止传播。

    测试my function 是否按照您的意愿执行,然后决定是否停止传播。

    【讨论】:

    • 当我点击锚点时,我的函数(GET to DB)没有时间执行。我认为有必要在开始时停止传播
    • 您应该考虑那里可能对用户体验造成的损害:用户单击某物,但在数据库调用完成之前什么都没有发生。最坏的情况是,这可能会导致很长一段时间都没有反应。
    • 这是一个糟糕的答案,因为当您有多个事件在同一个元素上冒泡时,通常需要停止传播。这是该方法存在的全部原因。
    【解决方案3】:

    如果要分别启用/禁用单击事件,请添加和删除单击处理程序。因为event.stopPropagation() 会阻止事件向上传播 dom 树。

    更新:

    如果您使用 jQuery,请使用 .trigger() 函数。

    http://api.jquery.com/trigger/

    【讨论】:

      猜你喜欢
      • 2013-05-02
      • 1970-01-01
      • 2016-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2011-07-15
      相关资源
      最近更新 更多