循环内模板字面量中的按钮onclick事件如何正确传递参数
报错原因
你原来的写法有两个核心问题:
- 模板字符串插值
${item}时,如果item是对象类型,会默认转成字符串[object Object],拼到onclick属性里之后,浏览器执行内联脚本时会把这串内容当成未定义的变量标识符查找,直接抛标识符不存在的错误。 - 循环内给所有按钮设置了相同的id
add_deposit,违反了DOM id全局唯一的规范,后续如果通过id选元素会出现匹配异常。
另外内联onclick默认在全局作用域查找执行函数,如果show函数没有挂载到window对象下,就算传参正确也可能报函数未定义。
推荐实现方案
优先用事件监听器绑定的写法,完全规避字符串转义、序列化、全局作用域的坑,通过闭包直接拿到当前循环的item,稳定性最高:
function show(x){ console.log(x) } users.forEach(item => { const content = document.createElement("div") content.classList.add("content") // 单独创建按钮元素,不要靠innerHTML硬拼字符串 const addBtn = document.createElement("input") addBtn.type = "button" addBtn.value = "add" // 直接绑定点击事件,闭包天然持有当前循环的item引用 addBtn.addEventListener('click', () => { show(item) }) content.append(addBtn) list.append(content) })
兼容innerHTML写法的方案
如果你非要用innerHTML拼接内联onclick的写法,必须先把item序列化成合法的JSON字符串,同时转义引号避免破坏HTML属性结构:
function show(x){ console.log(x) } users.forEach(item => { const content = document.createElement("div") content.classList.add("content") // 序列化item,转义双引号适配HTML属性 const serializedItem = JSON.stringify(item).replaceAll('"', '"') content.innerHTML = ` <input type="button" value="add" onclick='show(${serializedItem})' /> `; list.append(content) })
注意:这种写法要求
show函数必须挂载到全局window作用域下,否则内联onclick无法找到对应函数。
内容的提问来源于stack exchange,提问作者GeekyMoktan
相关产品推荐
相关产品推荐

