HTML里的Event模型

当一个事件(Event)在浏览器发生的时候——比如发生在一个链接<a>上的时候。

从该节点往上追溯其父节点,构成一个链条。

Event Capture

事件先从该链条的顶部往下逐层传递,触发相应的事件监听函数,即所谓的Capture.

Event Bubbling

事件然后再从该节点开始逐层往上传递,触发相应的监听函数,即所谓的Bubbling.

stopProgagation

任何事件监听函数都可以调用 stopProgagation()方法终止事件的传递。

preventDefault

浏览器可能对所发生的事件有默认的处理动作。对于链接来说,就是打开这个链接。

在事件逐层传递过程中,监听函数有机会通过调用preventDefault()方法来阻止这种默认行为的发生。

addEventListener

典型的事件监听函数注册通过addEventListener来完成

  • 第一个参数是事件名称
  • 第二个参数是回调函数
  • 第三个参数useCapture指定是在Capture阶段还是Bubbling阶段
var callback = function(evt){
}

element.addEventListener('click', callback, false);

this指向哪里

回调函数被调用时指针this指向哪里,也是一个常见的问题。

element.addEvenetListener('click', function(evt){
  // this 指向当前 element
  // 即 this = evt.currentTarget
}, false);

element.onclick = function(evt){
  // this 指向当前 element
}

对事件的相应代码也可以通过在HTML代码里通过类似于onclick这样的属性来指定。

<a href="#" onclick="alert(this.tagName)">this 指向当前Element</a>

这种情况实际上相当于系统自动wrap了一个function并通过addEventListener进行注册。

改变this的指向

一种办法时通过Function.prototype.bind()来实现。

另一种办法时利用addEveentListener(type, listener)中的listener既可以时一个function,也可以时一个Object——只要该Object实现了handleEvent(evt)接口。

function SomeObject(element){
  var self = this;
  this.handleEvent = function(evt){
    switch(evt.type){
      case "click" :
        // this = self
        break;
    }
  };

  element.addEventListener('click', this, false);
}

参考资料