Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOM0、DOM1、DOM2级事件 #13

Open
HarleyWang93 opened this issue Apr 7, 2018 · 0 comments
Open

DOM0、DOM1、DOM2级事件 #13

HarleyWang93 opened this issue Apr 7, 2018 · 0 comments

Comments

@HarleyWang93
Copy link
Owner

DOM(Document Object Model,文档对象模型)是针对HTML文档和XML文档的一个API。DOM描绘了一个层次化的节点树,允许开发人员添加、移出和修改页面的某一部分,DOM 脱胎于Netscape 及微软公司创始的 DHTML(动态HTML)。但现在它已经成为表现和操作页面标记的真正跨平台、语言中立的方式。

Netscape Navigator 4 和 IE4 分别发布于 1997 年的 6 月和 10 月发布的 DHTML,由于 IE4 和 Netscape Navigator4 分别支持不同的 DHTML,为了统一标准,W3C开始制定 DOM。1998 年10 月 W3C 总结了 IE 和 Navigator4 的规范,制定了 DOMLevel 1即 DOM1,之前 IE 与 Netscape 的规范则被称为 DOMLevel 0 即 DOM0 。

DOM0级事件

假设页面中存在一个 btn 的按钮,并且给 btn 添加一个点击事件

btn.onclick = function(){
   console.log('this is a click event')
}

事件就是用户或浏览器自身执行的某种操作,如click、load、mouseover等,都是事件的名字,而响应某个事件的函数就被称为事件处理程序。

click事件过程

在上述的例子中,click 事件并没有像其他函数一样,必须要调用才可以执行,click 事件并不确定什么时候发生,而当浏览器发现用户点击该按钮时,浏览器就检测btn.onclick是否有值,如果有,就会执行btn.onclick.call(btn,event),此时函数执行,call() 方法接收两个参数,第一个指向调用当前方法的对象,也就是this

需要注意的是,指定的 this 值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为 null 和 undefined 的 this 值会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。

另一个参数则是事件对象 event,该对象也可以通过 arguments[0] 来访问,它包含了事件相关的所有信息,如本例子中,则包含了点击事件的全部信息。可以通过给函数传参来获取事件信息。

btn.onclick = function(e){
   console.log('this is a click event');
   console.log(e);  //  事件对象
    
}

但是在 IE 中,在使用 DOM0 级方法添加事件处理程序时,event 是作 window 对象的一个属性而存在的。此时访问事件对象需要通过 window.event

btn.onclick = function(){
   console.log(window.event);  //  IE中事件对象    
}

在 DOM0级中,如果想要实现一个对象绑定多个函数,可以这样实现。

function fn1(){
    // do something
}
function fn2(){
    // do something
}
btn.onclick = function(e){
  fn1.call(this,xxx);
  fn2.call(this.yyy);
}

DOM2级事件

W3C 后来将 DOM1 升级为 DOM2,DOM2级规范开始尝试以一种符合逻辑的方式来标准化 DOM事件。DOM0级 可以认为 onclick 是 btn 的一个属性,DOM2级 则将属性升级为队列。

DOM2级 事件定义了两个方法,用于处理指定和删除事件处理程序的操作,addEventListener()removeEventListener(),所有的 DOM 节点中都包含这两个方法,它们都接收 3 个参数。

  1. 要处理的事件名

  2. 作为事件处理程序的函数

  3. 布尔值,true 代表在捕获阶段调用事件处理程序,false 表示在冒泡阶段调用事件处理程序,默认为 false。

btn.addEventListener('click',function(){
  //  do something
})
btn.addEventListener('click',function(){
  //  do something else
})

addEventListener()将事件加入到监听队列中,当浏览器发现用户点击按钮时,click 队列中依次执行匿名函数1、匿名函数2。

function fn1(){
  //  do something
}
function fn1(){
  //  do something else
}
btn.addEventListener('click',fn1)
btn.addEventListener('click',fn2)

如果这样写,click 队列中依次fn1.call(btn,event)fn2.call(btn,event)

通过addEventListener()添加的事件只能由removeEventListener()来移除,并且removeEventListener()只能移除具名函数,不能移除匿名函数。

IE 中 DOM2级事件

IE8 及之前,实现类似addEventListener()removeEventListener()的两个方法是attachEvent()detachEvent(),这两个方法接受相同的两个参数。

  1. 要处理的事件名

  2. 作为事件处理程序的函数

IE8 之前的只支持事件冒泡,所以通过attachEvent()添加的事件处理程序只能添加到冒泡阶段。

btn.attachEvent('click',fn1)
btn.attachEvent('click',fn2)

当用户点击时,click 队列依次fn1.call(undefined,undefined)fn2.call(undefined,undefined)

类似的detachEvent()也只能移除具名函数,不能移除匿名函数。

兼容处理

if(typeof btn.addEventListener === 'function'){
  btn.addEventListener('click',fn);
}else if(typeof btn.attachEvent === 'function'){
  btn.attachEvent('onclick',fn)
}else{
  btn.onclick=function(){
    // do something
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant