问题 多次绑定事件到jQuery中的元素会产生影响吗?


如果我有以下代码,如果多次按下新的串行按钮,类serial的文本框将被多次绑定到事件。

即使多次调用bind方法,这会阻碍性能还是jQuery只注册事件一次?

$(document).ready(function () {

    MonitorSerialTextBoxes();

    $('#newSerial').click(function () {

       $.tmpl("productTemplate", mymodel).insertAfter($(".entry").last());
       MonitorSerialTextBoxes();

    });

    function MonitorSerialTextBoxes() {
      $('.serial').each(function () {
         // Save current value of element
         $(this).data('oldVal', $(this).val());

         // Look for changes in the value
         $(this).bind("propertychange keyup input paste", function (event) {

         // If value has changed...
         if ($(this).data('oldVal') != $(this).val() && $(this).val().length == 10) {

             // Updated stored value
             $(this).data('oldVal', $(this).val());

             // Do action
         }
      });
    }

});

更新:我相信它会将下面的代码添加到MonitorSerialTextBoxes函数修复thiings? 

$('.serial').unbind("propertychange keyup input paste");

来自jQuery文档:

如果注册了多个处理程序,它们将始终按照绑定的顺序执行


6375
2017-12-02 12:24


起源

我不确定答案而不测试它,但你可以用Visual Event自己测试一下。 sprymedia.co.uk/article/Visual+Event  只需按照页面上的说明操作即可。 - Xyan Ewing


答案:


您可以将多个事件处理程序绑定到单个元素。以下将生成一个包含两个onclick事件的按钮:

$("button").bind("click", myhandler);
$("button").bind("click", myhandler);

一种选择是首先取消绑定事件:

$("button").unbind("click").bind("click", myhandler);
$("button").unbind("click").bind("click", myhandler);

这将导致仅一个绑定的单击事件。

如果您正在重新绑定事件,因为您的表单已动态添加元素,那么您可能需要查看 live() 或新的 on(),可以将事件绑定到可能尚不存在的元素。例:

$("button").live("click", myhandler); // All buttons (now and in 
                                      // the future) have this handler.

在Webkit开发人员工具(Safari和Chrome)中,您可以通过检查元素来查看绑定到元素的事件,然后在“元素”面板的右窗格中向下滚动。它位于一个名为“Event Listeners”的可折叠盒子下面。 Firebug应该具有类似的功能。


12
2017-12-02 12:31



如果您使用的是jQuery 1.7+版本 .live() 方法不赞成使用 .on() (你提到过),但即使从版本1.4+开始也建议使用 .delegate() 而不是 .live()。 - nnnnnn


嗯,我认为这会导致很多开销和一些问题,因为事件被绑定了不止一次。看看这个简单的小提琴: http://jsfiddle.net/nicolapeluchetti/syvDu/

<button id='newSerial'>Button</button>
<div class='serial'>Serial</div>
<div class='serial'>Serial</div>
<div class='serial'>Serial</div>

MonitorSerialTextBoxes();

$('#newSerial').click(function() {
    MonitorSerialTextBoxes();

});

function MonitorSerialTextBoxes() {
    $('.serial').each(function() {


        // Look for changes in the value
        $(this).bind("click", function(event) {
            alert("hi");
        });
    });
}

当您加载页面时,单击div时会显示一个alòert,但每次按下该按钮时都会显示另一个警报,因为附加了一个新事件


2
2017-12-02 12:31