如何用原生JS正确插入链接并解决click事件重复触发失效问题
问题原因与解决方案
问题原因
- 初始页面加载时,你给已存在的
.link-buy元素直接绑定了click事件,但这个事件是绑定在具体的DOM节点上的。 - 触发
mouseout事件后,你通过innerHTML替换了.catalog的内容,这会彻底移除原来的.link-buy节点,同时生成一个全新的.link-buy元素。 - 新生成的元素没有被绑定任何click事件,所以再次点击时不会触发之前的回调逻辑。
解决方法
方法1:事件委托(推荐)
利用事件冒泡机制,把click事件绑定到不会被替换的父级元素上,不管子元素怎么更新,只要点击目标是.link-buy就能触发事件。
修改后的JS代码:
const elCollection = document.getElementsByClassName('wrapper'); const paragraph = document.getElementsByClassName('catalog'); for(var i = 0; i < elCollection.length; i++) { var elem = elCollection[i]; const count = i; // 将事件绑定到父元素.catalog上 paragraph[count].addEventListener('click', function(e) { // 判断点击的目标是否为.link-buy元素 if(e.target.classList.contains('link-buy')) { console.log('qwertty'); } }) elem.addEventListener('mouseout', function(e) { paragraph[count].innerHTML = 'And here the link is no working <a class="link-buy" href="#">link.</a>'; }) }
方法2:更新元素后重新绑定事件
把绑定click事件的逻辑抽成复用函数,每次通过innerHTML更新内容后,重新找到新生成的.link-buy元素并绑定事件。
修改后的JS代码:
const elCollection = document.getElementsByClassName('wrapper'); const paragraph = document.getElementsByClassName('catalog'); // 封装绑定事件的函数 function bindLinkClick(targetEl) { targetEl.querySelector('.link-buy').addEventListener('click', function() { console.log('qwertty'); }) } for(var i = 0; i < elCollection.length; i++) { var elem = elCollection[i]; const count = i; // 初始绑定事件 bindLinkClick(paragraph[count]); elem.addEventListener('mouseout', function(e) { paragraph[count].innerHTML = 'And here the link is no working <a class="link-buy" href="#">link.</a>'; // 更新内容后重新绑定 bindLinkClick(paragraph[count]); }) }
内容的提问来源于stack exchange,提问作者evans
相关产品推荐
相关产品推荐

