什么是事宜?(敲黑板)
事宜,就是文档或浏览器窗口发作的一些特定的交互霎时。(by 《JavaScript高等程序设计》)
比方鼠标点击,双击,滚动条滑动…
什么是事宜流?
先来看一个简朴的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="main">
<div class="btn-wrap">
<button id="btn">点击</button>
</div>
<div>
</body>
</html>
这时候我们点击btn
的同时,也能够视为同时点击了btn
的容器元素,以至单击了全部页面。
事宜流指的是从页面吸收事宜的递次。
关于事宜流,IE和Netscape提出了差不多相反的观点,IE提出的就是广为人知的事宜冒泡流,而Netscape提出的则是事宜捕捉流。
1. 事宜冒泡
事宜冒泡,即事宜开始时由最详细的元素吸收,如上面例子中的btn
,然后逐步向上级流传到较为不详细的节点。DOM2级事宜
划定addEventListener
要领的第三个参数设为false
,示意事宜在冒泡阶段触发。
注:运用频仍的事宜托付现实上也是应用了事宜冒泡。
照样雷同的DOM构造为例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="main">
<div class="btn-wrap">
<button id="btn">点击</button>
</div>
<div>
<script type="text/javascript">
var btn=document.querySelector("#btn"),
btnWrap=document.querySelector(".btn-wrap"),
main=document.querySelector(".main"),
body=document.querySelector("body"),
html=document.querySelector("html");
btn.addEventListener("click",function(){
console.log("你点击了ID为btn的button元素!");
},false);
btnWrap.addEventListener("click",function(){
console.log("你点击了class为btn-wrap的DIV元素!");
},false);
main.addEventListener("click",function(){
console.log("你点击了class为main的DIV元素!");
},false);
body.addEventListener("click",function(){
console.log("你点击了body元素!");
},false);
html.addEventListener("click",function(){
console.log("你点击了html元素!");
},false);
document.addEventListener("click",function(){
console.log("你点击了document对象!");
},false);
</script>
</body>
</html>
假如我们点击btn
,那末这个click事宜的流传递次以下:
也就是,click事宜起首在btn
元素上触发,而这个元素就是我们单击的元素,然后click事宜沿DOM树向上流传,在每一级的节点都邑发作,直至流传到document对象。
一切当代浏览器都支撑事宜冒泡。
2. 事宜捕捉
事宜捕捉,即事宜从不太肯定的节点吸收,然后向下流传到最详细的节点,事宜捕捉的意图在于在事宜抵达预期目的之前捕捉它。DOM2级事宜
划定addEventListener
要领的第三个参数设为true
,示意事宜在捕捉阶段触发。
照样雷同的DOM构造为例:
将参数改成true
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="main">
<div class="btn-wrap">
<button id="btn">点击</button>
</div>
<div>
<script type="text/javascript">
var btn=document.querySelector("#btn"),
btnWrap=document.querySelector(".btn-wrap"),
main=document.querySelector(".main"),
body=document.querySelector("body"),
html=document.querySelector("html");
btn.addEventListener("click",function(){
console.log("你点击了ID为btn的button元素!");
},true);
btnWrap.addEventListener("click",function(){
console.log("你点击了class为btn-wrap的DIV元素!");
},true);
main.addEventListener("click",function(){
console.log("你点击了class为main的DIV元素!");
},true);
body.addEventListener("click",function(){
console.log("你点击了body元素!");
},true);
html.addEventListener("click",function(){
console.log("你点击了html元素!");
},true);
document.addEventListener("click",function(){
console.log("你点击了document对象!");
},true);
</script>
</body>
</html>
假如我们点击btn
,那末这个click事宜的流传递次以下:
在事宜捕捉过程当中,document对象起首吸收到click事宜,然后事宜沿着DOM树顺次向下流传。
现在支撑事宜捕捉流的浏览器有:IE9,Safari,Chrome,Opera,Firefox。
因为老版本浏览器不支撑事宜捕捉,发起人人更多的是用事宜冒泡,在有特殊需要时再运用事宜捕捉。
3. DOM事宜流
依据DOM2级事宜
划定,事宜流应当包含三个阶段,事宜捕捉阶段,处于目的阶段和事宜冒泡阶段。
照样雷同的DOM构造为例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div class="main">
<div class="btn-wrap">
<button id="btn">点击</button>
</div>
<div>
<script type="text/javascript">
var btn=document.querySelector("#btn"),
btnWrap=document.querySelector(".btn-wrap"),
main=document.querySelector(".main"),
body=document.querySelector("body"),
html=document.querySelector("html");
//冒泡
btn.addEventListener("click",function(){
console.log("你点击了ID为btn的button元素!");
},false);
btnWrap.addEventListener("click",function(){
console.log("你点击了class为btn-wrap的DIV元素!");
},false);
main.addEventListener("click",function(){
console.log("你点击了class为main的DIV元素!");
},false);
body.addEventListener("click",function(){
console.log("你点击了body元素!");
},false);
html.addEventListener("click",function(){
console.log("你点击了html元素!");
},false);
document.addEventListener("click",function(){
console.log("你点击了document对象!");
},false);
//捕捉
btn.addEventListener("click",function(){
console.log("你点击了ID为btn的button元素!");
},true);
btnWrap.addEventListener("click",function(){
console.log("你点击了class为btn-wrap的DIV元素!");
},true);
main.addEventListener("click",function(){
console.log("你点击了class为main的DIV元素!");
},true);
body.addEventListener("click",function(){
console.log("你点击了body元素!");
},true);
html.addEventListener("click",function(){
console.log("你点击了html元素!");
},true);
document.addEventListener("click",function(){
console.log("你点击了document对象!");
},true);
</script>
</body>
</html>
假如我们点击btn
,那末这个click事宜的流传递次以下:
在DOM事宜流中,现实的目的btn
不会吸收到事宜。这意味着在捕捉阶段,事宜从document到btn-wrap
就住手了,下一阶段是“处于目的”阶段,因而事宜在btn
上发作,然后冒泡阶段发作,事宜又流传回文档。
注:多半支撑DOM事宜流的浏览器都完成了一种特定行动,纵然
DOM2级事宜
范例明确要求捕捉阶段不会触及目的阶段,IE9,Safari,Chrome,Firefox,Opera9.5及更高版本都邑在事宜捕捉阶段触发事宜对象上的事宜,这也是上图btn
被触发两次的缘由。
IE9,Safari,Chrome,Firefox,Opera都支撑DOM事宜流,IE8及更早版本不支撑DOM事宜流。
本文学问点大多来自《JavaScript高等程序设计》一书,博主在这里也是做一次总结,稳固一下相干学问,同时也愿望没打仗过事宜流的童鞋们,有一个也许的观点。