点击相同类名元素仅触发一次AJAX,stopPropagation导致图层功能失效如何解决
问题根因分析
- 阻止冒泡方法调用时机错误:
event.stopPropagation()、event.stopImmediatePropagation()必须在点击事件触发的同步执行流程中调用才会生效,你将其放在AJAX的success回调中,此时原生事件的冒泡流程已经执行完毕,这两个方法完全无法起到阻止重复触发的作用,反而会干扰后续图层渲染的事件逻辑,导致打开图层功能异常。 - 重复触发的核心原因:大概率是你的事件绑定代码被重复执行了多次,导致同一个点击事件被绑定了多个相同的回调函数,点击时就会多次触发;也有可能是点击事件冒泡到父元素后,父元素也绑定了同逻辑的点击事件。
- 现有防重复逻辑有漏洞:你通过移除类名避免重复触发的逻辑,跟不上用户短时间快速点击的速度,在AJAX请求返回、类名还没移除时就会触发多次请求。
解决方案
修正后的完整代码
// 绑定前先解绑,避免重复绑定导致的多次触发 $(document).off('click', '.openFieldsButton').on("click", '.openFieldsButton', function(event) { // 开头就调用阻止冒泡,不要放在回调里 event.stopPropagation(); event.stopImmediatePropagation(); // 加执行锁,已经触发过的元素直接返回,防止快速点击重复触发 if ($(this).data('isProcessing')) return; $(this).data('isProcessing', true); var id = $(this).attr('fields_id'); var relid = $(this).attr('relid_to_select'); var this_ = this; var forms_token = $(this).attr('forms_token'); $(this).removeClass('openFieldsButton'); $(this).parent().find('.loadingGif').show(); $(this).parent().find('.openIconToggleBox').hide(); $(this).parent().find('.openIconToggleBox').removeClass('glyphicon-menu-down').addClass('glyphicon-menu-up'); $.ajax({ url: '?isloaded=1&open_id=' + id + '&open_relid=' + relid + forms_token + '', type: 'get', dataType: 'json', async: false, data: {'load_content' : id, 'open_relid': relid, 'isloaded': '1'}, success: function(response) { $(this_).parent().find('.loadingGif').hide(); // 这里的show逻辑不会再被阻止,正常执行 $(this_).parent().find('.openIconToggleBox').show(); $('#fields_' + id + '').html(response.toggleBoxFields); // 如果后续需要支持该按钮重复点击,可打开下方注释移除执行锁 // $(this_).data('isProcessing', false); } }); });
关键修改点说明
- 绑定事件前先调用
off方法解绑原有相同事件,避免重复绑定导致的多次触发 - 把阻止冒泡的逻辑移到点击事件最开始的位置,确保在事件冒泡流程结束前生效
- 新增
data('isProcessing')执行锁,避免用户快速点击导致的重复触发,比单纯移除类名的方案更可靠 - 移除了success回调里的阻止冒泡代码,消除对图层显示逻辑的干扰
内容的提问来源于stack exchange,提问作者sanktusm
相关产品推荐
相关产品推荐

