如何在触发jQuery事件前配置其不向目标元素外传播?
如何在jQuery新版本中触发事件时阻止传播(由调度器控制)
我完全懂你的困扰——这个调度器在jQuery 1.5.1里能好好阻止事件冒泡,但升级新版本后就失效了,而且你还没法直接在子元素的事件绑定里加stopPropagation(),必须由调度器来掌控是否允许事件传播。
问题根源
jQuery从1.6版本开始对事件触发机制做了调整,原来在jQuery.Event上调用stopPropagation()再用trigger()触发的方式,已经不能可靠地阻止事件冒泡了,这就是旧代码失效的原因。
解决方案:改用triggerHandler()代替trigger()
最直接且贴合你需求的方法是切换到triggerHandler(),这个方法本身就不会触发事件冒泡,也不会执行元素的默认行为,完美匹配你“仅触发子元素事件”的要求。
修改你的调度器代码如下:
var eventDispatcher = { trigger: function(targetElement, eventName) { jQuery(targetElement).triggerHandler(eventName); } }
完整修改后的代码示例
<!DOCTYPE html> <html> <head> <style> body { background: #333; padding: 20px; font-family: Helvetica; } #parent { background: #0c0; padding: 20px; font-size: 25px; text-align: center; margin: 0 auto; width: 300px; } button { background: #fff; border: none; border-radius: 5px; padding: 8px 14px; font-size: 15px; color: #333; /* 调整了文字颜色,避免白色按钮上看不见文字 */ } </style> </head> <body> <div id="parent"> <p id="version">jQuery Version</p> <button>Change text</button> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script> <script> // 元素获取 var parent = $("#parent"); var button = $("button"); var version = $('#version'); version.text('jQuery ' + jQuery.fn.jquery); // 事件调度器 var eventDispatcher = { trigger: function(targetElement, eventName) { jQuery(targetElement).triggerHandler(eventName); } } // 事件绑定 version.bind('custom', function(){ button.text('version custom'); }); parent.bind('custom', function(){ button.text('parent custom'); }); button.bind("click", function(){ eventDispatcher.trigger(version, 'custom'); }); </script> </body> </html>
为什么这个方法可行?
triggerHandler()和trigger()的核心差异在于:
trigger()会触发事件冒泡,还会执行元素的默认行为(比如点击a标签会跳转)triggerHandler()仅触发目标元素上绑定的事件,不会冒泡到父元素,也不会触发默认行为
这完全满足你“由调度器决定是否传播”的需求——如果后续需要允许事件传播,只需要把调度器里的triggerHandler改回trigger就可以了。
内容的提问来源于stack exchange,提问作者Daniel Santos
相关产品推荐
相关产品推荐

