/*
*一、事件触发的三个阶段
*1.window往事件触发处传播,遇到注册的捕获事件就会触发。
*即事件由外向内,就称为捕获。
*2.传播到事件触发处是触发注册事件。
*3.从事件触发处往window传播,遇到注册的冒泡事件就会触发。
*即事件由内向外,就称为冒泡。
*事件触发一般会按照以上步骤触发
*例如下面的示例就是先注册捕获,然后再注册冒泡。
*/
<body>
<div id="like">1
<div id="ss">2
<div id="mm">3</div>
</div>
</div>
<script>
let like = document.getElementById("like");
like.addEventListener("click", function () {
console.log("1");
});
let ss = document.getElementById('ss');
ss.addEventListener("click", function () {
console.log("2")
},true)
let mm = document.getElementById('mm');
mm.addEventListener("click", function () {
console.log("3")
})
</script>
</body>
/* 如果点击mm节点会输出2,3,1因为ss节点设置了
第三个参数为true,默认值为false,即按冒泡执行
设置为true之后就会先捕获,所以就会输出2,3执行捕获
然后再执行like节点输出1。
/*
*但是也有特殊情况,如果给目标节点同时注册冒泡和捕获事件时
*会按照注册的顺序执行。
*/
<body>
<div id="like">我是like</div>
<script>
let like = document.getElementById("like");
like.addEventListener("click", function () {
console.log("冒泡");
});
let ss = document.getElementById('like');
ss.addEventListener("click", function () {
console.log("捕获");
})
</script>
</body> //执行的结果为冒泡 捕获 按顺序执行
总结以上知识点:
一般情况下事件触发捕获事件先触发,冒泡在后
但是当目标节点同时注册冒泡、捕获事件时
按照注册事件顺序执行。
注册事件
通常使用addEventListener注册事件。
<body>
<div id="like">我是like</div>
<div id="ss">
</div>
<script>
let like = document.getElementById("like");
like.addEventListener("click", function (event) {
event.stopImmediatePropagation()
// event.stopPropagation()
console.log("冒泡");
});
let ss = document.getElementById('ss');
ss.addEventListener("click", function () {
console.log("捕获");
})
</script>
</body>
以上代码输出结果为冒泡,event.stopImmediatePropagation()
方法阻止了事件的进一步传播。
事件代理(事件委托)
适用场景:
子节点是动态生成的
子节点上的注册事件就需要绑定在父节点上。
<body>
<ul id="like">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<script>
let ul=document.getElementById("like");
ul.addEventListener('click',function(event){
console.log(event.target)
console.log(this)
})
</script>
</body>
谈到事件代理,此处的this和target也涉及到一定的知识点。
关于事件的的三要素
1.事件源(this和target)
通俗的讲,this是addEventListener()方法前的那个节点
event.target是鼠标点击的那个节点。
2.事件的类型(单击事件,双击事件)
3.事件处理函数(注册事件需要执行的操作)
关于事件代理的优点
1.节省内存
2.不需要给子节点设置注销事件