您所说的区别在于“捕获”事件模型或“冒泡”事件模型之间。 jQuery 的触发器在 Bubble 模型上运行可能是因为这是更受支持的事件模型——主要归功于 Internet Explorer。 Bubble 模型仅通过父元素向后向上传播...这就是为什么您的事件在从 div1 触发时不会在 div2 上触发的原因,因为它总是在冒泡而不是向下。
我之前没有尝试过使用原生函数自定义事件,但大多数现代浏览器允许您在设置事件侦听器时决定使用哪种类型的模型:
addEventListener (type, listener[, useCapture])
https://developer.mozilla.org/en-US/docs/DOM/element.addEventListener
基本上,如果您使用true 作为最后一个参数,则事件侦听器应在捕获阶段触发(当事件沿着 dom 树传播时)。如果设置为 false,则事件将在返回 dom 树时发生的冒泡阶段触发。
这里已经讨论过了:
Event Capturing vs Event Bubbling
正如我所说,这是否适用于定制活动,我不确定。我很确定你不能用 jQuery (到目前为止) 做到这一点,这可能是由于旧浏览器缺乏支持。
更正
看来我在上面的猜测不起作用。由于“捕获”一词使您考虑捕获用户输入,因此我想了很多-当涉及定制事件时,无法定义一种新的用户输入。所以考虑到这一点,我把这个快速的 jQuery 插件放在一起......它只是经过粗略测试,但逻辑应该是合理的 - 希望它有用:
/**
* unbubble v0.2
*
* trigger an event down through the children of a collection,
* rather than up through it's parents
*
* @update 2013/03/18 - fixed the problem of triggering bubble phase each
* step down the element tree as pointed out by @vine.
*/
$.fn.unbubble = function( eventNames ){
var names = eventNames.split(' '),
non = names.length,
args = Array.prototype.slice.call(arguments);
/// our own trigger function designed to bubble down... not up!
var trigger = function(){
var i, events, elm = $(this);
/// make sure we can read the events array
if ( $._data ) {
/// make sure events is defined
if ( (events = $._data(this, 'events')) ) {
/// do a quick check, saves firing trigger on every element found
for ( i=0; i<non; i++ ) {
/// make sure our eventName appears in the event list
if ( names[i] && ( names[i] in events ) ) {
/// trigger the standard jQuery trigger function
elm.triggerHandler.apply(elm, args);
/// escape as trigger should fire for multiple names
break;
}
}
}
}
/// if we can't access the events array, just trigger and hope
else {
/// trigger the standard jQuery trigger function
elm.triggerHandler.apply(elm, args);
}
/// trigger for all the children, and on, and on...
elm.children().each(trigger);
};
/// foreach element trigger now...
this.each(trigger);
}
/**
* Example usage
*/
$(function(){
/// bind our event as usual
$('.div2').bind('customEvent', function(){
alert('I should trigger!');
});
/// rather than use trigger, fire with unbubble
$('#div1').unbubble( 'customEvent' );
});