如何从HTML字符串模板字面量中获取data属性并绑定事件处理程序
问题核心原因
- 属性挂载与查询目标不匹配:
data-id属性写在父元素.game__container上,但你绑定点击事件的是它的子元素a.game__container_game-link,点击时e.target指向的是没有data-id的a标签,所以返回null。 - 可选优化点:逐一对动态生成的元素绑定事件,后续新增元素时需要重复绑定,使用事件委托的方案会更稳定。
- 额外注意:你原模板字符串中写的
${id}没有关联遍历的game对象,要修正为${game.id},否则id变量未定义也会导致属性值异常。
解决方案
方案1:使用事件委托(推荐)
仅需给固定存在的父容器绑定一次事件,后续新增的元素也能自动触发回调,不需要重复绑定:
// 提前获取页面初始就存在的父容器 const gameContainer = document.getElementById('empty_container'); // 全局绑定一次事件即可 gameContainer.addEventListener('click', (e) => { // 仅匹配点击的是游戏卡片链接的场景 if (e.target.classList.contains('game__container_game-link')) { // 向上查找最近的携带data-id的卡片容器 const targetCard = e.target.closest('.game__container'); const dataId = targetCard.dataset.id; console.log('ok!', dataId); } }); // 原来的渲染逻辑不需要再保留绑定事件的循环 const showGame = async function(){ try{ // 注意修正模板字符串的id取值为game.id const markUp = results.map((game) => ` <div class="game__container" data-id="${game.id}"> <a href="javascript:;" class="game__container_game-link" ></a> </div> `).join(''); gameContainer.insertAdjacentHTML('afterbegin',markUp); } catch(err){ console.log(err); } };
方案2:修正原有绑定逻辑
如果不需要用事件委托,调整原有逻辑的属性查询逻辑和DOM查询时机即可:
const showGame = async function(){ try{ const markUp = results.map((game) => ` <div class="game__container" data-id="${game.id}"> <a href="javascript:;" class="game__container_game-link" ></a> </div> `).join(''); gameContainer.insertAdjacentHTML('afterbegin',markUp); // 插入DOM后再查询所有卡片链接,不要提前在全局作用域查询 const cardContainer = document.getElementsByClassName('game__container_game-link'); for (let i = 0; i < cardContainer.length; i++) { cardContainer[i].addEventListener('click',(e)=>{ // 从父元素获取data-id const dataId = e.target.closest('.game__container').dataset.id; console.log('ok!', dataId); }) } } catch(err){ console.log(err); } };
内容的提问来源于stack exchange,提问作者user14868233
相关产品推荐
相关产品推荐

