我可以在某些功能上停止事件传播吗?

时间:2013-12-06 01:45:47

标签: javascript jquery stoppropagation

我有一些DIV,其他开发人员将点击事件名称fn_propagation绑定到它们。

现在我想为他们添加一个名为fn_stoppropagation的新功能。

问题是当我在e.stopPropagation()中呼叫fn_stoppropagation时,它也会在fn_propagation中停止事件传播。

如何在fn_propagation中保持事件传播,但在我添加的功能中停止传播? (我知道通过ID向每个DIV添加事件并停止使用stopPropagation()可以做到这一点,但我不认为这是一个好方法。)

小提琴:http://jsfiddle.net/android/3GurB/2/

HTML:

<div id='div1'>
    <div id='div2'>
        <div id='div3'>
            Click Me
        </div>
    </div>
</div>

JS:

$('div').click(fn_propagation)      // Other developer add this event
        .click(fn_stoppropagation); // What I going to add.

// I want to keep propagation of this function 
function fn_propagation(){
    alert('propagation '+$(this).attr('id')+' called');
    $(this).toggleClass('green');
}

// But stop propagation of this function
function fn_stoppropagation(e){
    alert('stoppropagation '+$(this).attr('id')+' called');
    e.stopPropagation();
}

单击Click Me时,请输出:

   propagation div3 called     // called
   stoppropagation div3 called // called
   propagation div2 called     // expected, but NOT called, 
   propagation div1 called     // expected, but NOT called, 

谢谢。

3 个答案:

答案 0 :(得分:2)

传播发生在DOM中,它只能在整个元素上打开或关闭,而不能用于特定的事件处理程序。

我的建议:将当前元素与click target进行比较:

function fn_stoppropagation(e){
  if (this===e.target) {
    // the following will only run for the target, not its ancestors
    alert('stoppropagation '+$(this).attr('id')+' called');
  }
}

答案 1 :(得分:1)

你拥有的是嵌套的div,每次处理点击。因为它们是嵌套的,所以事件起泡 - 从最里面的div开始。所以你不能stopPropogation并期望它传播泡沫。 stopPropogation正是为了那个 - 停止将事件冒泡到其他处理程序。

答案 2 :(得分:0)

您的方法是错误的,因为事件传播独立于事件处理程序,因此您无法为某些事件停止事件而不会停止其他事件。

您可能认为能够仅针对某些人停止它是有意义的,但这是因为您的案例是特殊的:目标及其祖先具有相同的处理程序。

但是在更一般的情况下,冒泡事件会触发事件处理程序,每个元素的事件处理程序可能不同,因此仅针对某些处理程序停止事件传播没有任何意义。

然后,正确的方法是修改事件处理程序而不是事件。 例如:

var stopped = false;
function fn_stoppropagation(e){
    if(stopped !== (stopped=true)){
        /* Code here */
    }
}

Demo