jQuery循环绑定事件仅对最后一个元素生效,是什么原因?
问题根因
你第二个绑定事件的循环里,i_sel、pic_element_id、input_element_id三个变量都没有用let/const声明,默认成为了全局变量,每次循环都会覆盖上一次的变量值。而按钮的点击回调函数是异步执行的,触发时循环早就跑完了,三个变量里存储的都是最后一次循环的赋值,所以所有按钮点击都会触发最后一个input的点击。
修复方案
方案1:直接给变量加块级作用域声明
给所有循环内的变量加上let/const声明,限定每个循环迭代的变量独立存在,不会被后续循环覆盖:
const pix = $("button[id*='picture-add-']") for (let i = 0; i < pix.length; ++i){ const i_selector = i+1 const new_input = $('<input>', { id:"file-input-" + i_selector.toString(), type:"file", name:"name", style:"display: none;", accept:"image/gif, image/jpeg, image/png, image/jpeg" }).appendTo('#addNew') } for (let i = 0; i < pix.length; ++i){ const i_sel = i+1 const pic_element_id = pix[i].id const input_element_id = $('#file-input-' + i_sel.toString())[0].id $('#' + pic_element_id).click(function(){ $('#' + input_element_id).trigger('click') console.log(pic_element_id, 'pic_element_id') console.log(input_element_id) }) }
方案2:合并两个循环优化逻辑
直接用jQuery的each方法遍历按钮,创建input的同时绑定事件,不需要额外维护索引和选择器,更不容易出作用域问题:
const pix = $("button[id*='picture-add-']") pix.each(function(index){ const i_selector = index + 1 // 创建对应input const $input = $('<input>', { id:"file-input-" + i_selector, type:"file", name:"name", style:"display: none;", accept:"image/gif, image/jpeg, image/png, image/jpeg" }).appendTo('#addNew') // 直接给当前按钮绑定事件 $(this).click(function(){ $input.trigger('click') console.log($(this).attr('id'), 'pic_element_id') console.log($input.attr('id')) }) })
内容的提问来源于stack exchange,提问作者Pavel Pereverzev
相关产品推荐
相关产品推荐

