jQuery:如何停止传播到同一个处理程序?

时间:2012-01-17 14:12:19

标签: jquery events

请考虑以下代码:

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p')).click(function onceHandler(event) {
  console.log('Clicked.');
});

我想在点击“p”时只运行onceHandler一次,因此每个处理程序应该运行一次而不是第二次运行,因为点击从p传播到文档。

event.stopPropagation()将破坏第一个处理程序,因此我无法使用它。我也试过了:

$(document).add($('p')).click(function(event) {
  if (event.stopDoingThat) return;
  console.log('Clicked.');
  event.stopDoingThat = true;
});

哪个不起作用。所以基本上没有改变任何东西,我得到2“点击”和一个“确定”。点击“stopPropagation - 1”,我需要的是“点击”1和“确定”

5 个答案:

答案 0 :(得分:2)

这似乎是jQuery中one函数的完美用例:

  

描述:将处理程序附加到元素的事件。该   每个元素最多执行一次处理程序。

在您的情况下,这将转换为类似以下代码:

$(document).add($('p')).one('click', function onceHandler(event) {
    console.log('Clicked.');
});

有关详情,请参阅jQuery docs

答案 1 :(得分:1)

你试过了吗?

var firstRun = true;

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p')).click(function onceHandler(event) {
  if(firstRun) {
    console.log('Clicked.');
    firstRun = false;
  }
});

可能有更优雅的解决方案。有点像:

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p')).on("click.runonce", function(event) {
    console.log('Clicked.');
    $(document).off("click.runonce");
  }
});

参考此other SO question

答案 2 :(得分:1)

不确定这是否适用于所有浏览器,但我在Chrome中进行了测试。

$(document).click(function (event) {
  console.log("ok");
});

$(document).add($('p')).click(function onceHandler(event) {
    if(!event.originalEvent.myClickDone){
        console.log("click");    
    }

    event.originalEvent.myClickDone = true;
});

基本上,两个event个对象共享一个公共originalEvent

答案 3 :(得分:0)

问题是你在document-object上使用apply函数两次而不是在paragraph-object上。更改最后一行,使其如下所示:

$(document).click(function (event) {
  console.log("Ok");
});

$(document).add($('p').click(function onceHandler(event) {
    console.log('Clicked.');
    $('p').off('click');
  }
}));

答案 4 :(得分:0)

这不能胜任这项工作吗?我认为你可以通过单个事件处理程序和目标元素的测试来简化:

$(document).click(function(event) {
    if(event.target.tagName.toLowerCase() === "p") {
       console.log("clicked");
    }
    console.log("ok");
});

Demo.