这是我参与「第四届青训营 」笔记创作活动的第8天
前言
随着青训营课程的推进,已经开始接触 TypeScript 。 TypeScript 是 JavaScript 的超集,所以对我这种菜鸡而言,学不懂是正常的。之前有学过 Java ,从代码上来看,其实还是能理解不少,可是受限 JS 水平不够,还是雾里看花,还是继续啃 JavaScript 吧。
事件流
当然,这里不再复习事件绑定。
冒泡和捕获
事件传播的三个阶段是:事件捕获、事件冒泡和目标。
- 事件捕获阶段:事件从祖先元素往子元素查找( DOM 树结构),直到捕获到事件目标 target。在这个过程中,默认情况下,事件相应的监听函数是不会被触发的。
- 事件冒泡阶段:事件从事件目标 target 开始,从子元素往冒泡祖先元素冒泡,直到页面的最上一级标签。
- 事件目标:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
addEventListener 可以捕获事件:
.div1 {
width: 300px;
height: 300px;
background-color: black;
}
.div2 {
width: 200px;
height: 200px;
background-color: yellow;
}
.box {
width: 100px;
height: 100px;
background-color: red;
}
<div class="div1">
<div class="div2">
<div class="box"></div>
</div>
</div>
<script>
let div1 = document.querySelector(".div1");
let div2 = document.querySelector(".div2");
let box = document.querySelector(".box");
div1.addEventListener("click", function () {
console.log("div1 被抓到了")
}, true);
div2.addEventListener("click", function () {
console.log("div2 被抓到了")
}, true);
box.addEventListener("click", function () {
console.log("box 被抓到了")
}, true);
</script>
点击 box,猜猜在参数为true情况下,输出顺序:
可以看到,是按照捕获的顺序进行事件的处理。
而我们true改为默认值,即false:
是按照冒泡的顺序来处理事件。
取消冒泡
通过前面的例子可得子元素的事件被触发时,父元素的同样的事件也会被触发,那我们想让事件在子元素就不再往上传播了应该怎么做呢:
box.addEventListener("click", function (e) {
e.stopPropagation();
console.log("box 被抓到了")
});
修改完这行代码,效果为:
在最里层就停下来了!
事件委托
事件委托可以简单的理解为将子级的事件委托给父级来处理。
<div class="btnBox">
<button class="btn1">按钮1</button>
<button class="btn2">按钮2</button>
</div>
<script>
let btn1 = document.querySelector(".btn1");
let btn2 = document.querySelector(".btn2");
btn1.addEventListener("click", function () {
console.log(this.innerHTML)
})
btn2.addEventListener("click", function () {
console.log(this.innerHTML)
})
</script>
现在给两个按钮绑定了事件,在控制台输出内容:
显然,代码重复了,而且如果要新增一个绑定相同事件的按钮,又要重新写一次,太麻烦了!
let btnBox = document.querySelector(".btnBox");
btnBox.addEventListener("click", function (event) {
let target = event.target;
console.log(target.innerHTML);
})
通过将事件绑定到父节点上,减少了事件绑定的次数,减少内存消耗,提高性能。
计时器
setInterval():循环调用。将一段代码,每隔一段时间执行一次。(循环执行)
let count = 0;
setInterval(function () {
count++;
console.log(count);
}, 1000)
表示每隔 1000 ms ,执行一次函数。
通过clearInterval(),可以清除计时器效果:
let count = 0;
const timer = setInterval(function () {
count++;
console.log(count);
if (count === 3) {
clearInterval(timer);
}
}, 1000)
setTimeout():延时调用。将一段代码,等待一段时间之后再执行。(只执行一次)
可以通过clearTimeout()清除定时器效果。
写在最后
好的那么本期笔记先到这里,待我好好学学防抖和节流,再将其整理到下篇笔记中!