点击同div内收藏按钮触发所有内容?JavaScript问题排查
问题原因分析与解决方案
为什么点击一个按钮会输出所有div的内容?
你当前的代码存在两个核心问题:
- 重复绑定事件:在遍历每个
.ais-infinite-hits--item时,你每次都用document.querySelectorAll(".toggle-icon-fav")获取页面所有的收藏按钮,然后给它们绑定点击事件。假设页面有N个item,每个按钮就会被绑定N次点击事件——点击一次按钮,就会触发N次事件回调,自然会输出所有item的内容。 - 目标元素匹配错误:你在事件回调里使用的是当前遍历的
hitsItem(循环到的某个item),而不是点击按钮所在的那个item。这就导致每次触发事件时,都会用循环过程中保存的不同hitsItem去获取内容。
另外还有一个小bug:HTML里的内容类名是cote-actual-chf(短横线分隔),但你代码里写成了cote_actual_chf(下划线),这会导致无法正确获取内容,必须修正这个拼写。
解决方案一:针对每个item绑定专属事件
修改代码,在遍历item时,只获取当前item内部的收藏按钮,避免全局重复绑定:
function pushDb() { let hitsItems = document.querySelectorAll('.ais-infinite-hits--item') if (hitsItems) { hitsItems.forEach(hitsItem => { // 只查找当前item内的收藏按钮,而非全局所有 let likeButton = hitsItem.querySelector(".toggle-icon-fav"); if (likeButton) { likeButton.addEventListener("click", () => { // 修正类名的拼写错误 let coteChfSave = hitsItem.querySelector('.cote-actual-chf').textContent.trim(); const dataPush = { coteChfSave: coteChfSave } console.log(dataPush) }) } }) } } pushDb()
解决方案二:事件委托(更推荐)
如果你的列表是动态加载的(比如无限滚动加载更多item),上面的方案需要在新item加载后重新绑定事件,而事件委托只需要给父容器绑定一次事件,就能处理所有现有和未来的按钮点击,更高效:
function pushDb() { const hitsContainer = document.querySelector('.ais-infinite-hits'); if (hitsContainer) { hitsContainer.addEventListener('click', (e) => { // 判断点击的元素是否是收藏按钮 if (e.target.classList.contains('toggle-icon-fav')) { // 找到按钮所在的父item const hitsItem = e.target.closest('.ais-infinite-hits--item'); if (hitsItem) { // 修正类名拼写 let coteChfSave = hitsItem.querySelector('.cote-actual-chf').textContent.trim(); const dataPush = { coteChfSave: coteChfSave }; console.log(dataPush); } } }); } } pushDb()
这个方案利用事件冒泡机制,点击按钮时事件会冒泡到父容器,我们通过e.target判断点击的是收藏按钮,再用closest()方法找到对应的item,最后获取内容即可。
内容的提问来源于stack exchange,提问作者lf_celine
相关产品推荐
相关产品推荐

