全面解析javascript事件流模型以及各事件流模型在浏览器中的兼容性情况

首先,讲一下为什么会有事件流模型。举个简单的例子来说,当你看着纸上一组同心圆的时候,你拿着笔点着同心圆里最小的那个圆的时候,是不是也可以说你也在点着这组同心圆的所有圆?显然是可以说的。

所以,当你点击页面上的一个button,你是不是也在点击着包含这个button的父级元素?同样,是的。这便是为什么会有事件流以及事件流模型。

事件流

事件流有两种:一种是微软公司提出的冒泡事件流,一种是网景公司提出捕获事件流。它们定义的事件传播方向恰恰相反。

  • 事件冒泡(Event Capturing): 是一种从下往上的传播方式。事件最开始由最具体的元素(也就是DOM最底层的子节点), 然后逐渐向上传播到最不具体的那个节点(也就是DOM中最高层的父节点)。
  • 事件捕获(Event Bubbling): 是一种从上到下的传播方式。事件最开始由不太具体的节点最早接受事件, 而最具体的节点最后接受事件。

例如:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="myDiv">Click me!</div>
</body>
</html>

在冒泡型事件流中click事件传播顺序为div -> body -> html -> document

这里写图片描述

在捕获型事件流中click事件传播顺序为document -> html -> body -> div

这里写图片描述

之前,微软公司的IE系列浏览器主张冒泡型事件处理,网景公司的Netscape系列浏览器主张捕获型,谁也说服不了谁,之后W3C组织制定了DOM标准事件流,但可惜的是网景公司并未撑到DOM标准制定就被收购了,但它的捕获事件流的思想却被借鉴了下来。

DOM事件流:

DOM标准采用捕获+冒泡。两种事件流都会触发DOM的所有对象,从document对象开始,也在document对象结束。

这里写图片描述

DOM标准规定事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。

  • 事件捕获阶段:实际目标(div)在捕获阶段不会接收事件。也就是在捕获阶段,事件从document到html再到body就停止了。上图中为1~3.

  • 处于目标阶段:事件在div上发生并处理。但是事件处理会被看成是冒泡阶段的一部分。

  • 冒泡阶段:事件又传播回document

事件流模型

现在常用事件流模型的可以说就是2种:DOM0 模型,DOM2模型。(有些说是3种,HTML事件处理程序、DOM0 模型、DOM2模型,虽然说HTML事件处理程序不存在浏览器的兼容性问题,但个人不推荐使用,可自行了解)

DOM 0 模型:

如要给btn按钮添加点击事件处理程序

<input type="button" id="btn">

在js代码区添加事件处理程序和绑定关系

var btn = document.getElementById("btn");

btn.onclick = function showMessage(){

    alert("hello world");

}

如果要移除该点击事件处理程序

btn.onclick = null;

DOM 0模型并不是W3C组织制定的标准,但是由于在W3C组织制定标准之前,这种方式广被各种浏览器所采用,到现在各种浏览器也都支持,所以就被保留了下来。

说明:DOM 0模型不存在浏览器兼容性的问题,也就是说,它被各种浏览器支持,可跨浏览器使用。

注意:通过DOM 0方法添加的事件,无法控制是冒泡事件流还是捕获事件流,但是现今流行的浏览器中(safari、IE、opera、chrome、Firefox)都把其在冒泡事件流阶段处理。

DOM 2 模型:

如要给btn按钮添加点击事件处理程序

<input type="button" id="btn">

js区添加事件处理程序和绑定关系

     var btn= document.getElementById("btn");
     btn.addEventListener("click", function () {
       alert("innerCircle的click事件在捕获阶段被触发");
    },true);
     btn.addEventListener("click", function () {
       alert("innerCircle的click事件在冒泡阶段被触发");
    },false);

事件绑定监听函数的方式 : addEventListener(eventType, handler, useCapture).

当useCapture取值false为冒泡阶段调用事件处理程序;当useCapture取值true为捕获阶段调用事件处理程序。

移除事件的方式:removeEventListener(eventType, handler, useCapture)

说明:DOM 2 模型并未被IE9以下版本支持即 IE(6,7,8)不支持DOM 2 注册和移除事件的方式,且只支持冒泡事件流,不支持DOM事件流。

在IE(6,7,8)版本中,注册事件和移除事件的写法是:

var btn3 = document.getElementById("btn3");

btn3.attachEvent("onclick", showMessage);//注册事件

btn3.detachEvent("onclick", showMessage);//移除事件

function showMessage(){

    alert("hello world");

}

但是IE 9及以上版本(IE 10 ,IE11,IE edge)支持DOM 事件流且支持DOM2注册和移除事件的方式。

所以,我们可以按照对DOM2的支持把浏览器分为两类:IE(6,7,8)和 其它浏览器。

因此jquery等这些js库就封装了跨浏览器的事件处理方式。

总结

如果同时出现DOM0和DOM2事件处理程序,那么不同浏览器处理它们的优先级会怎样呢?

chrome/opera/safari等webkit内核的浏览器:DOM2级 DOM0级
firefox浏览器和IE浏览器(指IE9及以上版本)会将DOM0级事件优先调用:DOM0级 DOM2级

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值