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});