孩子们如何倾听/捕捉父母的事件

CLB*_*CLB 9 javascript html5 dom javascript-events

如何激活自定义事件以通知其子/兄弟姐妹?例如:

<div id="div1">
   <div id="div2"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

div2有addEventListener('customEvent2',doSth),然后div1将触发一个自定义事件(customEvnet2).但这永远不会触发div2的"doSth"功能

示例代码:http: //jsfiddle.net/r4tcT/2/

"div 1触发器customEvent 2"按钮永远不会起作用

所以当父级触发自定义事件(dispatchEvent [IE9]/fireEvent [IE9 - ]/trigger [jQuery])时,子级无法捕获事件.

有没有解决方法?

Peb*_*bbl 6

您正在谈论的差异是"捕获"事件模型或"冒泡"事件模型之间.jQuery的触发器在Bubble模型上运行可能是因为这是更受支持的事件模型 - 主要得益于Internet Explorer.泡泡模型只能通过元素父母向后移动......这就是为什么你的事件在被触发div2时不会触发的原因div1,因为它总是冒泡而不是向下.

我之前没有使用本机函数尝试自定义事件,但是大多数现代浏览器允许您决定在设置事件侦听器时使用哪种类型的模型:

addEventListener (type, listener[, useCapture])
Run Code Online (Sandbox Code Playgroud)

https://developer.mozilla.org/en-US/docs/DOM/element.addEventListener

基本上,如果您使用true事件侦听器作为最后一个参数,则应在Capture阶段(即事件沿着dom树向下移动时)触发.如果设置为false,则事件将在冒泡阶段触发,该阶段在向后返回dom树时发生.

这已经在这里讨论过:

事件捕获与事件冒泡

正如我所说,这是否适用于定制活动,我不确定.我很确定你不能用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' );
});
Run Code Online (Sandbox Code Playgroud)