1. 事件流
比如我们给一个div注册了点击事件:
DOM事件流分为三个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
如下图:
捕获阶段:
在元素触发事件的时候会经历如下:
这种从最顶层元素逐一向内(目标元素)传播渗透判断触发即为捕获阶段。
冒泡阶段:
在元素触发事件的时候会经历如下:
这种从目标元素逐一向外(最顶层)传播判断触发即为冒泡阶段。
形象一点的解释:
注意:
- JS代码中只能执行捕获或者冒泡其中一个阶段
- onclick只能得到冒泡阶段;
- 如果使用addEventListentr()注册事件,则第三个参数就可以指定其为捕获阶段或者冒泡阶段;如果第三个参数是 true,那么则处于捕获阶段,如果是false或者省略,则处于冒泡阶段;
- 实际开发中我们很少使用事件捕获,更关注事件冒泡;
- 有些事件是没有冒泡的,如onblur,onfocus,onmouseenter,onmouseleave。
捕获阶段示例:
<body>
<div class="father">
<button>点击</button>
</div>
<script>
const father = document.querySelector(".father");
const btn = document.querySelector("button")
father.addEventListener('click', function() {
alert("father");
}, true)
btn.addEventListener('click', function() {
alert("son");
}, true)
</script>
</body>
点击按钮后:
点击确定后:
冒泡阶段示例:
<body>
<div class="father">
<button>点击</button>
</div>
<script>
const father = document.querySelector(".father");
const btn = document.querySelector("button")
father.addEventListener('click', function() {
alert("father");
}, false)
btn.addEventListener('click', function() {
alert("son");
}, false)
</script>
</body>
点击按钮后:
点击确定后:
2. 事件对象
2.1 什么是事件对象
2.2 事件对象的常见属性和方法
- e.target:返回触发事件的对象
<body>
<button>点击</button>
<script>
const btn = document.querySelector("button");
btn.addEventListener('click', function (e) {
console.log(e.target);
})
</script>
</body>
点击结果如下:
- e.type: 返回事件的类型
<body>
<button>点击</button>
<script>
const btn = document.querySelector("button");
btn.addEventListener('click', function (e) {
console.log(e.type);
})
</script>
</body>
点击结果如下:
- e.preventDefault():阻止默认行为,比如不让链接跳转
<body>
<a href="https://www.baidu.com">百度</a>
<script>
const a = document.querySelector("a");
a.addEventListener('click', function (e) {
e.preventDefault(); // 点击不会跳转到百度页面
})
</script>
</body>
- e.stopPropagation():阻止冒泡
<body>
<div class="father">
<button>点击</button>
</div>
<script>
const father = document.querySelector(".father");
const btn = document.querySelector("button");
father.addEventListener('click', function (e) {
alert("father");
}, false)
btn.addEventListener('click', function (e) {
alert("son");
e.stopPropagation()
}, false)
</script>
</body>
点击按钮后只会调用btn绑定的事件,不会向上冒泡。
3. 事件委托
示例如下:
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
const ul = document.querySelector("ul");
const lis = document.querySelectorAll("li");
// 给ul添加点击事件
ul.addEventListener('click', function(e) {
// e.target: 返回触发事件的对象,指向点击的那个对象
console.log(e.target);
})
</script>
</body>
点击第一个li结果如下:
点击第二个li结果如下:
点击第三个li结果如下: