一:事件机制的描述
1. js事件机制描述的是事件在DOM里面传递的顺序,以及我们可以对这些事件做出如何的响应。
2. js事件的触发可以分为三个阶段:
- 捕获阶段
- 目标阶段
- 冒泡阶段
二: 事件冒泡的五个注意点:
假设,有这样的 html 结构:
<div id="test" class="test">
<div id="testInner" class="test-inner"></div>
</div>
1. 在外层div上注册事件,点击内层div时,捕获事件总比冒泡事件先执行
const btn = document.getElementById("test");
//捕获事件
btn.addEventListener("click", function(e){
alert("capture is ok");
}, true);
//冒泡事件
btn.addEventListener("click", function(e){
alert("bubble is ok");
}, false);
先弹出 capture is ok,后弹出 bubble is ok。
2. 当在触发的dom上绑定事件时,哪个先注册就先执行哪个
const btnInner = document.getElementById("testInner");
//冒泡事件
btnInner.addEventListener("click", function(e){
alert("bubble is ok");
}, false);
//捕获事件
btnInner.addEventListener("click", function(e){
alert("capture is ok");
}, true);
先弹出 bubble is ok
,再弹出 capture is ok
。
3. 当外层 div 和内层 div 同时注册了捕获事件时,点击内层 div 时,外层 div 的事件一定会先触发
const btn = document.getElementById("test");
const btnInner = document.getElementById("testInner");
btnInner.addEventListener("click", function(e){
alert("inner capture is ok");
}, true);
btn.addEventListener("click", function(e){
alert("outer capture is ok");
}, true);
先弹出 outer capture is ok
,再弹出 inner capture is ok
。
4. 同理,当外层 div 和内层 div 都同时注册了冒泡事件,点击内层 div 时,一定是内层 div 事件先触发。
const btn = document.getElementById("test");
const btnInner = document.getElementById("testInner");
btn.addEventListener("click", function(e){
alert("outer bubble is ok");
}, false);
btnInner.addEventListener("click", function(e){
alert("inner bubble is ok");
}, false);
先弹出 inner bubble is ok
,再弹出 outer bubble is ok
。
5. 阻止事件的派发
btnInner.addEventListener("click", function(e){
//阻止冒泡
e.stopPropagation();
alert("inner bubble is ok");
}, false);
三:事件代理
事件代理用到js事件的两个特性:事件冒泡和目标元素,使用事件代理,我们可以把事件处理器添加到一个元素上,等待一个事件从它的子级元素里冒泡上来,并且可以得知这个事件是从哪个元素开始的。
window.onload=function(){
const ulNode=document.getElementById("list");
ulNode.addEventListener('click', function(e) {
/*判断目标事件是否为li*/
if(e.target && e.target.nodeName.toUpperCase()=="LI"){
console.log(e.target.innerHTML);
}
}, false);
};
四:事件对象 event
- event.target:触发事件的元素。
- event.currentTarget:事件绑定的元素。
<ul id="ulT">
<li class="item1">fsda</li>
<li class="item2">ewre</li>
<li class="item3">qewe</li>
<li class="item4">xvc</li>
<li class="item5">134</li>
</ul>
<script type="text/javascript">
document.getElementById("ulT").onclick = function (event) {
console.log(event.target);
console.log(event.currentTarget);
}
</script>
如果点击li,console上的情况如下:
target的结果是:<li class="item5">
currentTarget的结果是:<ul id="ulT">
- event.preventDefault():取消事件的默认行为。
- event.stopPropagation():阻止事件的派发(包括了捕获和冒泡)。