捕获与冒泡

总结就是:先捕获,后冒泡,捕获从上到下,冒泡从下到上(形象点说法:捕获像石头沉入海底,冒泡则像气泡冒出水面)

问:假如去掉注释 event.stopPropagation(); 结果又会输出什么?
答:去掉event.stopPropagation() 之后,由于事件有捕获和冒泡时先执行捕获,捕获到div之后,事件被阻止,后面就不在继续传播了。所以只输出divcallback.

div.addEventListener(‘click’,callbackdiv,true);这一句只能是捕获才执行。

事件不同浏览器处理函数

  • element.addEventListener(type, listener[, useCapture]); // IE6~8不支持(捕获和冒泡通过useCapture,默认false)
  • element.attachEvent(’on’ + type, listener); // IE6~10,IE11不支持(只执行冒泡事件)
  • element[’on’ + type] = function(){} // 所有浏览器(默认执行冒泡事件)
  • 捕获 阶段:在事件对象到达事件目标之前,事件对象必须从window经过目标的祖先节点传播到事件目标。 这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件。
  • 目标 阶段:事件对象到达其事件目标。 这个阶段被我们称为目标阶段。一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。
  • 冒泡 阶段: 事件对象以一个与捕获阶段相反的方向从事件目标传播经过其祖先节点传播到window。这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。

在一个事件完成了所有阶段的传播路径后,它的Event.currentTarget会被设置为null并且Event.eventPhase会被设为0。Event的所有其他属性都不会改变(包括指向事件目标的Event.target属性).
跨浏览器的事件处理函数:

1
var EventUtil = { 
  addHandler: function(element, type, handler) { 
    if (element.addEventListener) { // DOM2 
      element.addEventListener(type, handler, false);
    } else if (element.attachEvent) { // IE 
      element.attachEvent('on' + type, handler);
    } else { // DOM0 
      element['on' + type] = handler;
    }
  }, 
  removeHandler: function(element, type, handler) { 
    if (element.removeEventListener) { 
      element.removeEventListener(type, handler, false);
    } else if (element.detachEvent) { 
      element.detachEvent('on' + type, handler);
    } else { 
      element['on' + type] = null;
    }
  }
};

跨浏览器的事件对象:

1
var EventUtil = { 
  getEvent: function(e) { 
    return e ? e : window.e;
  }, 
  getTarget: function(e) { 
    return e.target || e.srcElement;
  }, 
  preventDefault: function(e) { 
    if (e.preventDefault) { 
      e.preventDefault();
    } else { 
      e.returnValue = false;
    }
  }, 
  stopPropagation: function(e) { 
    if (e.stopPropagation) { 
      e.stopPropagation()
    } else { 
      e.cancelBubble = true;
    }
  }
}