addEventListener绑定点击事件仅执行一次,点击circulo类元素二次无响应
问题根因
你遇到的问题核心是两个常见的前端DOM操作问题:
- 原有绑定事件的元素被销毁:你在展开逻辑里用了
block.innerHTML += 额外HTML内容的写法,如果你的.circulo元素是.quedadas-content-body-p的子元素,这个操作会把.quedadas-content-body-p内部所有原有DOM节点全部删除后再重建,你之前绑定在原.circulo元素上的点击事件会随着原元素被销毁而失效,新渲染出来的.circulo元素没有绑定点击事件,自然第二次点击没有反应。 - 事件重复绑定+状态隔离:
showTexto函数每次执行都会给.circulo新增一个点击监听,且状态变量status是定义在showTexto内部的,每次调用都会生成独立的status变量。如果responsiveHtml在窗口resize时重建了DOM、你又多次调用了showTexto,会导致同一个元素绑定多个重复事件,不同事件 handler 操作各自的status变量,逻辑完全混乱。 - 额外隐藏问题:代码里的
block、tostyle没有用let/const声明,会变成全局变量,容易被其他逻辑篡改导致异常。
解决方案
- 把
innerHTML +=追加改为DOM节点插入操作,避免销毁原有节点 - 抽离事件绑定逻辑,保证只绑定一次,状态变量全局共享
- 补上变量声明,避免全局污染
修改后代码
点击逻辑改造
// 抽离状态和DOM查询,只执行一次,避免重复查询和绑定 let toggleStatus = 1; let textoCache = ''; const circuloEl = document.querySelector('.circulo'); const contentEl = document.querySelector('.quedadas-content-body-p'); const svgEl = contentEl.querySelector('svg'); // 点击事件只绑定一次 circuloEl.addEventListener('click', function() { console.log("hola") if (toggleStatus == 1) { const tostyle = contentEl.style; tostyle.minHeight = "100%"; tostyle.background = "#222"; tostyle.display = "block"; // 用createElement创建节点插入,不会销毁原有DOM const extraP = document.createElement('p'); extraP.className = 'text-extra'; extraP.innerText = textoCache; extraP.style.margin = "0 10px"; contentEl.appendChild(extraP); svgEl.style.transform = "rotate(180deg)"; toggleStatus = 0; } else { console.log("status = 0"); contentEl.removeAttribute("style"); document.querySelector('.text-extra')?.remove(); svgEl.removeAttribute("style"); toggleStatus = 1; } console.log(toggleStatus); }); // showTexto只负责更新文本缓存,不处理事件绑定 function showTexto(texto) { textoCache = texto; }
接口调用部分保持原有逻辑即可
axios("json/").then(res=>{ responsiveHtml(res.data); window.addEventListener('resize', _=> responsiveHtml(res.data)); showTexto( res.data.quedadas[3].texto); })
补充说明
如果你的.circulo元素会在responsiveHtml执行时被重建,推荐改用事件委托的方式绑定事件,不用每次重建DOM后重复绑定:
// 绑定在不会被销毁的父元素上,比如body document.body.addEventListener('click', function(e) { if (e.target.closest('.circulo')) { // 把上面的点击逻辑直接放这里即可 } })
内容的提问来源于stack exchange,提问作者David Florez
相关产品推荐
相关产品推荐

