jQuery:函数被调用两次。传播?为什么会这样?

时间:2014-06-22 05:35:47

标签: jquery stoppropagation

请查看以下小提琴:http://jsfiddle.net/K9NjY/

我在这段代码上花了3-4个小时,我把它缩小到最短的版本,现在我被卡住了。

问题: 1.点击' divOne' 2.单击切换DivNames 3.点击' divTwo'

*为什么divOne仍然会收到警报?我怎么阻止这个? * 逻辑会告诉我,当我们点击divTwo时,我们应该只收到一条提示“divTwo'

请注意,doSomething()有一个由click内部触发的功能。这不能改变,即$("." + divName).click(function(){...});必须保留在doSomething()

我该怎么办?

3 个答案:

答案 0 :(得分:4)

事件绑定到不属于其classNames的元素,无论何时调用该函数,您都将单击处理程序附加到匹配的元素。这就是你看到几个处理程序被调用的原因。您可以使用传递的参数来使用事件委派,也可以使用off方法删除处理程序。

编辑:通常当您将多个处理程序附加到元素时,您做错了什么。在其他处理程序中附加事件处理程序是一种痛苦的处方。应该将逻辑转移到处理程序的主体中。

这是我在这种情况下可能会做的事情:

var $e = $(".action").on('click', function() {
     var action = $(this).data('action');
     // Do something based on the element's current `action` datum
     if (action === 'whatever') {
       // ...
     } else {
       // ...
     }
});

function doSomething(divName) {
    $e.html(divName).data('action', divName);
}

这里action数据可以在处理程序的逻辑中使用。

答案 1 :(得分:1)

使用off删除事件侦听器并再次添加,切换类名称不会取消绑定现有的事件侦听器 -

function doSomething(divName){

    $(".action").off().addClass(divName).html(divName).click(function(){
        alert(divName);
    });
}

FIDDLE

答案 2 :(得分:0)

如果您使用谷歌浏览器,找到这样的东西的最简单方法是使用组件视图。您可以在那里看到,在单击Switch div名称之前,第一个div看起来像这样:

<div class="action divOne">divOne</div>
单击它后,它看起来像这样

<div class="action divOne divTwo">divTwo</div>

意味着你刚刚添加了divTwo,但从未删除过divOne。您还调用了一个在脚本启动时调用的函数。

你在说什么:

doSomething("divOne");//First call on Dom Ready

它已经调用了该函数。这就是为什么你在切换后同时将divOne和divTwo作为响应。

这个更新后的版本将按照您的预期运行。 http://jsfiddle.net/K9NjY/2/