鼠标悬停嵌套元素时避免事件重复触发的解决方案
解决鼠标悬停多次触发事件绑定导致重复执行的问题
嘿,我看出来你遇到的问题了——每次鼠标悬停到目标div上,都会给编辑按钮多绑定一次click事件,悬停次数越多,点击按钮时执行的次数就越多对吧?这是因为你把click事件的绑定逻辑放在了mouseover回调里,每次悬停都会重复绑定。
给你几个实用的解决办法,从简单到优雅都有:
方法1:让鼠标悬停事件只触发一次
最简单的办法就是把on('mouseover')换成one('mouseover'),这样每个.user-notation-block-online元素只会响应一次鼠标悬停,自然不会重复绑定事件了:
$('.user-notation-block-online').one({ mouseover: function (e) { e.preventDefault(); let target = $(this).attr('data-comment'); let regex = /\d+/; let match = target.match(regex); let uniqueId = match[0]; $('#js-action-edit-' + uniqueId).click(function (e) { // 你的原有编辑逻辑... }) } })
方法2:绑定前先解绑旧事件
如果需要允许用户多次悬停,但不想重复绑定事件,可以在绑定新的click事件前,先移除之前的绑定:
$('.user-notation-block-online').on({ mouseover: function (e) { e.preventDefault(); let target = $(this).attr('data-comment'); let regex = /\d+/; let match = target.match(regex); let uniqueId = match[0]; // 先解绑所有已绑定的click事件,再重新绑定 $('#js-action-edit-' + uniqueId) .off('click') .click(function (e) { // 你的原有编辑逻辑... }) } })
方法3:用事件委托从根源解决(推荐)
其实最好的做法是把click事件委托到父容器上,根本不需要在mouseover里绑定事件。这样不管鼠标悬停多少次,事件只绑定一次,甚至动态生成的按钮也能生效:
假设你的所有评论元素都在一个固定的父容器里(比如#comments-container),可以这么写:
// 一次性绑定事件委托,处理所有编辑按钮的点击 $('#comments-container').on('click', '[id^="js-action-edit-"]', function(e) { e.preventDefault(); // 从按钮ID里提取uniqueId let uniqueId = this.id.split('-').pop(); // 下面是你的原有编辑逻辑 let $textareaContent = $("#js-content-comment-" + uniqueId); let $titleContent = $('#js-content-title-'+uniqueId); let exValue = $textareaContent.text().trim(); let exTitle = $titleContent.text().trim(); textAreaContentInitial = exValue; titleContentInitial = exTitle; $('#js-user-block-' + uniqueId).prepend('<h1 class="edit-header" id="edition-header-' + uniqueId + '">Formulaire d\'édition</h1>'); $('#js-action-block-' + uniqueId).html(''); $('#js-button-block-' + uniqueId).prepend('<button class="btn-primary btn user-save" id="js-action-save-' + uniqueId + '">Sauvegarder</button>\n' + '<button class="btn-danger btn user-save" id="js-action-cancel-'+ uniqueId +'">Anuler</button>'); $textareaContent.replaceWith('<textarea class="edit-text-area">' + exValue + '</textarea>'); $titleContent.replaceWith('<input class="edit-input-title" type="text" value="' + exTitle + '">'); }); // 如果mouseover不需要做其他操作,这个绑定甚至可以删掉 $('.user-notation-block-online').on({ mouseover: function (e) { e.preventDefault(); // 这里只保留mouseover需要的其他逻辑(如果有的话) } })
方法4:给元素加标记避免重复执行
还可以给编辑按钮加个自定义数据属性,标记是否已经绑定过事件,这样每次悬停时先检查标记,只有未绑定过才执行绑定逻辑:
$('.user-notation-block-online').on({ mouseover: function (e) { e.preventDefault(); let target = $(this).attr('data-comment'); let regex = /\d+/; let match = target.match(regex); let uniqueId = match[0]; let $editBtn = $('#js-action-edit-' + uniqueId); // 检查是否已经绑定过事件 if (!$editBtn.data('is-bound')) { $editBtn.click(function (e) { // 你的原有编辑逻辑... }).data('is-bound', true); // 标记为已绑定 } } })
内容的提问来源于stack exchange,提问作者Sunrider
相关产品推荐
相关产品推荐

