jquery .click被多次调用

我在jQuery尝试设置div的“click”方法时得到了意想不到的结果。 请看这个jsfiddle 。 务必打开控制台窗口。 单击几次单词并观察控制台输出。 当只应调用一次时,click函数会被多次调用。

最后注释掉的代码工作得很好。 难道我做错了什么? 我是jQuery的新手。

这是代码:

function toggleDiv(status) { console.log("toggleDiv(" + status + ")"); if (status) { $("#test").html("Goodbye"); } else { $("#test").html("Hello"); } $("#test").click(function() { toggleDiv(!status); }); // Non-jquery method works fine.... //document.getElementById("test").onclick = function () { // toggleDiv(!status); //} }​ 

更新:看起来有很多方法可以为这只猫提供皮肤。 这里真正的问题是我不理解jQuery“click”函数ADDS另一个处理程序。 我以为它替换了当前的处理程序。

每次单击它时,您都会设置一个新的.click() eventHandler(这反过来会创建更多事件)。 另外,请注意不要在DOM元素上使用onclick / onmouseover / onmouseout / etc事件。 在Internet Explorer中,这些创建脚本块(如果您使用Visual Studio,您可以看到它们。有数千个这样的页面会极大地降低性能!

看起来你正试图实现这个目标:

jsFiddle DEMO

 $("#test").on('click', function() { var this$ = $(this), _status = !!this$.data('status'); // force to boolean // ^will default to false since we have no data-status attribute yet this$.html(_status ? 'Hello' : 'Goodbye') .data('status', !_status); });​ 

您将以递归方式重复注册click处理程序。

一个正确的解决方案(许多可能的变化)是这样的:

 $(function() { var status = false; $('#test').click(function() { status = !status; $(this).html(status ? 'Goodbye' : 'Hello'); }); }); 

然后你需要从HTML中删除onclick属性 – 混合DOM0和DOM3事件处理是不好的。

见http://jsfiddle.net/alnitak/8aBxp/

jQuery单击函数不会覆盖先前的单击处理程序,而是将新的单击处理程序添加到队列中。 因此,当再次调用click时,会添加一个新的单击处理程序以及所有旧的单击处理程序。

为了防止这种情况,您只需要在定义新处理程序之前清除旧处理程序。

 function toggleDiv(status) { console.log("toggleDiv(" + status + ")"); if (status) { $("#test").html("Goodbye"); } else { $("#test").html("Hello"); } $("#test").unbind(); $("#test").click(function() { toggleDiv(!status); }); }​ 

您可能还想查看.toggle()事件处理程序 。

更新 :要更清楚.toggle() ,这也将做你想要的:

 $("#test").toggle( function(event) { $(event.target).html("Goodbye"); }, function(event) { $(event.target).html("Hello"); } ); 

很可能你正在运行toggleDiv多次,导致click事件多次绑定。 将click事件绑定到toggleDiv函数之外。

 var status = false; function toggleDiv() { console.log("toggleDiv(" + status + ")"); if (status) { $("#test").html("Goodbye"); } else { $("#test").html("Hello"); } status = !status; }​ $("#test").click(function() { toggleDiv(status); }); 

您应该将click事件绑定到toggleDiv函数之外。 每次click $('#test')的元素时,当前代码将注册新的click事件处理程序,指数增长(因为所有先前的click处理程序将生成新的click处理程序,因此每次单击时处理程序的数量将加倍)。

在你的if之后,你将另一个点击事件添加到#test 。 它会在点击时调用所有点击处理程序。 您可能根本不需要它,因为onclick是在html中定义的。

最干净的解决方案是: http : //jsfiddle.net/kannix/fkMf9/4/

  $("#test").click(function() { $(this).text(($(this).text() == "Hello") ? "Goodbye" : "Hello"); }); 

同样的问题发生在我身上。 约瑟夫埃里克森关于unbind()的答案有效。 如果它有帮助,这里是我的代码中多次调用onclick事件的摘要:

  • AJAX调用正在更新表的tbody。 tbody内容完全是动态的。
  • 表行是按批次检索的(通过服务器端捕获)。
  • 特定的表数据(td)有一个超链接,它有一个与之关联的click事件。(作为AJAX回调函数的一部分添加了click事件)
  • 现在,每次调用AJAX时,一次点击事件都会与td相关联。
  • 因此,多次调用AJAX,许多点击处理程序附加到td。

我按照Joseph Erickson的建议解决了这个问题。 在AJAX回调中,我现在这样做:$(“。msgLinkDiv”)。unbind(); (“。msgLinkDiv”)。click(function(e){do my stuff});