在for循环中分配点击处理程序
我有几个div的#mydiv1
, #mydiv2
, #mydiv3
,…并想分配点击处理程序给他们:
$(document).ready(function(){ for(var i = 0; i < 20; i++) { $('#question' + i).click( function(){ alert('you clicked ' + i); }); } });
但是,当点击#mydiv3
(至于其他点击),而不是显示'you clicked 3'
,我得到'you clicked 20'
。 我究竟做错了什么?
在Javascript 中循环创build闭包是一个常见的错误。 你需要有这样的callback函数:
function createCallback( i ){ return function(){ alert('you clicked' + i); } } $(document).ready(function(){ for(var i = 0; i < 20; i++) { $('#question' + i).click( createCallback( i ) ); } });
更新2016年6月3日:由于这个问题仍然有一些牵引和ES6也越来越stream行,我会build议一个现代化的解决scheme。 如果你编写ES6,你可以使用let
关键字,这个关键字使得i
variables本地变为循环而不是全局的:
for(let i = 0; i < 20; i++) { $('#question' + i).click( function(){ alert('you clicked ' + i); }); }
它更短,更容易理解。
为了澄清,我等于20,因为点击事件将不会启动,直到循环完成后。
$(document).ready(function(){ for(var i = 0; i < 5; i++) { var $li= $('<li>' + i +'</li>'); (function(i) { $li.click( function(){ alert('you clicked ' + i); }); }(i)); $('#ul').append($li); } });
你可以通过分配一次点击处理程序(或者至less不要进行许多不必要的closures)。 把所有的div放在一个类mydivs
,然后:
$(document).ready(function(){ $('.mydivs').click(function(){ // Get the number starting from the ID's 6th character // This assumes that the common prefix is "mydiv" var i = Number(this.id.slice(5)); alert('you clicked ' + i); }); });
这将查看元素的ID以获取其编号,使用slice
string方法剥离closures的首字母。
注意:使用可能会更好
$('#divcontainer').on('click', '.mydivs', function(){
代替
$('.mydivs').click(function(){
一般来说,如果你正在寻找分配大量物品的点击手柄,你需要有一个容器(更高级别的div)来解释你的点击,因为点击会从dom中冒出来。
<div id="bucket"> <span class="decorator-class" value="3"> ... </div> <script> $(document).ready(function(e){ $("#bucket").live('click', function(){ if(e.target).is('span'){ alert("elementid: " + $(e.target).val()); } } } <script>
使用on来附加'click'处理程序,您可以使用事件数据来传递数据,如下所示:
for(var i = 0; i < 20; i++) { $('#question' + i).on('click', {'idx': i}, function(e) { alert('you clicked ' + e.data.idx); }); }
// // let's creat 20 buttons // for(var j = 0; j < 20; j++) { $('body').append($('<button/>', {type: 'button', id: 'question' + j, text: 'Click Me ' + j})) } // // Passing data to the handler // for(var i = 0; i < 20; i++) { $('#question' + i).on('click', {'idx': i}, function(e) { console.log('you clicked ' + e.data.idx); }); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>