如何在JS模板字面量的onclick事件中将对象传递给其他函数
问题根因
你尝试的写法失败,核心原因是将对象直接嵌入模板字面量生成HTML字符串时,JavaScript会自动调用对象的toString()方法,得到的是无实际意义的[object Object]字符串,自然无法传递完整对象结构。单属性可以传递是因为字符串、数字等基础类型转成字符串后可以直接被内联事件识别。
解决方案
方案1:JSON序列化转义(快速适配现有写法)
将对象序列化为JSON字符串后,替换JSON里的双引号为HTML实体",避免和onclick属性的双引号产生语法冲突,修改renderCar函数即可:
function renderCar(car) { // 序列化对象并转义双引号,避免和onclick属性引号冲突 const carStr = JSON.stringify(car).replace(/"/g, '"'); return `<div> <div data-type="color">${car.color}</div> <div data-type="type">${car.type}</div> <div data-type="capacity">${car.capacity}</div> <button onclick="makeEditable(${carStr})">Edit</button> </div>` }
方案2:事件委托(更推荐的工程化写法)
放弃内联onclick写法,通过事件委托实现对象传递,彻底避免字符串拼接带来的语法问题,性能和可维护性更好:
修改后的完整JS代码
let cars = [ { "color": "purple", "type": "minivan", "capacity": 7 }, { "color": "red", "type": "station wagon", "capacity": 5 } ] // 渲染列表,给编辑按钮加索引标识 cars.map((car, index) => { root.innerHTML += renderCar(car, index) }); function renderCar(car, index) { // 只加自定义属性存索引,不写内联事件 return `<div> <div data-type="color">${car.color}</div> <div data-type="type">${car.type}</div> <div data-type="capacity">${car.capacity}</div> <button class="edit-btn" data-car-index="${index}">Edit</button> </div>` } // 给根节点绑定全局点击事件,做事件委托 root.addEventListener('click', e => { // 仅点击编辑按钮时触发逻辑 if (e.target.classList.contains('edit-btn')) { const carIndex = Number(e.target.dataset.carIndex); // 直接从原数组取完整对象,无需序列化/反序列化 makeEditable(cars[carIndex]); } }) function makeEditable(car){ console.log(car) }
该方案仅需要给根节点绑定1个事件监听器,不需要给每个按钮单独绑定事件,后续修改事件逻辑也不需要调整渲染函数的代码。
内容的提问来源于stack exchange,提问作者Kyle Teeter
相关产品推荐
相关产品推荐

