为什么我的jquery委托多次点击火?

时间:2016-03-17 11:31:37

标签: javascript jquery javascript-events delegation

我正在复制一个元素并将其添加到元素列表中。首先,我使用ajax调用获取sonme HTML:

var setButtonClick = function (url, btn) {
    $.ajax(url, $('form').serialize(), 'Html').then(function (data) {
        $(btn).parent().find(sel.addListItem).on('click', function () {
            addListItem(data, this, btn);              
        });

        addListItem(data, btn, btn);          
    });
}

addListItem看起来像这样。

var addListItem = function (data, context, btn) {

    var $template = $(data);
    // stuff not related removed for brevity

    $(btn).before($template);      
}

然后我使用委托来删除函数:

 $(sel.editableList).delegate(sel.removeListItem, 'click', function () {
     // fires once for every element with the sel.removeListItem selector
 }

我需要点击事件才能为点击的元素触发一次。我可以通过插入这样的内容来获得delegate的基本版本:

$( "body" ).delegate( "p", "click", function() {
    $( this ).after( "<p>Another paragraph!</p>" );
});

因此,我认为这可能是因为我正在插入元素的副本,或者它是我一遍又一遍添加的相同元素?在插入之前,我还尝试使用clone创建一个新元素:

 var $template = $(data).clone();

有人能告诉我这出错的地方吗?

由于

1 个答案:

答案 0 :(得分:1)

问题是,每次调用ajax时,都会在元素上附加一个click事件处理程序。它会被重复调用,因为您将它添加到已存在的元素并附加了此处理程序。

您的问题的解决方案是使用off()函数分离以前连接的处理程序。

var setButtonClick = function (url, btn) {
    $.ajax(url, $('form').serialize(), 'Html').then(function (data) {
        $(btn).parent().find(sel.addListItem)
            .off('click')
            .on('click', function () {
                addListItem(data, this, btn);              
            });

        addListItem(data, btn, btn);          
    });
}

将来您可能希望附加不同的单击事件处理程序,或者可能希望关闭特定处理程序,因为您可以使用名称空间。

$(elem).on('event.namespace', function(){});
$(elem).off('event.namespace');

这样你就可以在一个元素上有多个click事件处理程序。如果您有多个单击事件处理程序

,那么这将是代码
var setButtonClick = function (url, btn) {
    $.ajax(url, $('form').serialize(), 'Html').then(function (data) {
        $(btn).parent().find(sel.addListItem)
            .off('click.addItem')
            .on('click.addItem', function () {
                addListItem(data, this, btn);              
            });

        addListItem(data, btn, btn);          
    });
}

以下是这个例子。

&#13;
&#13;
$('.btn').on('click.ns1', function(){
  alert('Hey');
});

$('.btn').on('click.ns2', function(){
  alert('How you doin?');
});


// Comment me out to see the difference
$('.btn').off('click.ns2');
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<button class="btn">Click me</button>
&#13;
&#13;
&#13;