同一NodeList节点点击事件重复触发的解决方法咨询
解决点击元素时事件多次触发的问题
问题根源
你遇到的情况大概率是事件被重复绑定导致的:比如绑定事件的代码被执行了多次(比如页面动态渲染后重复调用),使得第一个(或多个).product_color元素上挂载了多个相同的click事件监听,点击时就会多次触发。
解决方案
方案1:避免重复绑定事件
在绑定新事件前,先移除元素上已有的同事件监听,确保每个元素只绑定一次:
act.product_color = document.querySelectorAll(".product_color"); act.product_color.forEach(function (element) { // 先移除旧监听,再添加新监听,防止重复绑定 element.removeEventListener("click", product_preview_color); element.addEventListener("click", product_preview_color); });
方案2:改用事件委托(更推荐)
放弃给每个元素单独绑定事件,转而在父元素上绑定一次事件,通过事件目标判断触发源。这种方式不仅能避免重复绑定,还能支持动态新增的.product_color元素:
// 替换成实际包含所有.product_color元素的父元素选择器 const parentContainer = document.querySelector('.product-colors-container'); // 绑定一次事件委托 parentContainer.addEventListener('click', function(e) { // 找到真正触发事件的.product_color元素 const targetColor = e.target.closest('.product_color'); if (!targetColor) return; // 调用原事件处理函数,修正this指向为当前触发元素 product_preview_color.call(targetColor, e); // 按需阻止事件冒泡 e.stopPropagation(); });
额外优化:简化事件函数代码
原代码中可以用dataset替代getAttribute让代码更简洁,同时清理冗余的冒泡判断:
function product_preview_color(e){ // 用dataset替代getAttribute,语法更简洁 const image = this.dataset.productImage; const colorId = this.dataset.colorId; const attrId = this.dataset.id; e.stopPropagation(); act.product_preview_status = false; if(act.hasOwnProperty('product_size_attr')){ act.product_color_id = colorId; } act.product_attr_id = attrId; condition.color.condition_value = act.product_color_id; act.product_preview.innerHTML = ` <div class="product__media--preview__items"> <a class="product__media--preview__items--link glightbox" data-gallery="product-media-preview" href="http://127.0.0.1:8000/storage/media/attr_image/${image}"> <img class="product__media--preview__items--img" src="http://127.0.0.1:8000/storage/media/attr_image/${image}"> </a> <div class="product__media--view__icon"> <a class="product__media--view__icon--link glightbox" href="http://127.0.0.1:8000/storage/media/product/1686117526.png" data-gallery="product-media-preview"> <svg class="product__items--action__btn--svg" xmlns="http://www.w3.org/2000/svg" width="22.51" height="22.443" viewBox="0 0 512 512"> <path d="M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"></path> <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M338.29 338.29L448 448"></path> </svg> <span class="visually-hidden">product view</span> </a> </div> </div> `; }
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

