事件Events
- 事件是javascript的核心,你看到的任何javascript脚本都是由事件触发。网页的交互性,在JS中事件是必不可少的。
- 事件可以是用户的行为,也一些事件不是用户触发,比如:页面的加载
事件发展历史
- 简单事件处理浏览器刚发明出来,跳转链接就是最简单的鼠标触发事件。
- 事件流处理随着其他事件种类的产生,问题随之而来。对于嵌套元素,父子元素同时绑定相同的事件,当事件触发时,这两个嵌套元素事件流的执行顺序该如何确定?
- 伴随着浏览器大战,微软和网景公司给出了不一样的答案。
- 微软公司采用事件冒泡模型,即先执行子元素,再执行父元素。
- 网景公司采用事件捕获模型,即先执行父元素,再执行子元素。
- 随后W3C制定标准事件模型
- 事件源
- 事件对象
-
事件流
为什么会有事件流?
我的想法对于元素的嵌套,且每个元素都绑定了相同的事件。当你点击一个元素,你没法判断到底是怎么样的执行顺序,这会发生冲突问题。到底是父元素优先级高,还是子元素的优先级高。我想应该遍避免在全局document上绑定事件,同时要阻止事件冒泡。
易错点有一些简单事件并没有事件流。比如:fouse、blur、change、submit、reset、select事件冒泡
最开始是目标元素触发click事件,然后在DOM上逐层向上传递,直到window对象。
//事件冒泡会一直到window对象
<body>
<div class="box1">
<span>盒子1</span>
<div class="box2">
<span>盒子2</span>
</div>
</div>
</body>
<script>
let box1 = document.getElementsByClassName('box1')[0];
let box2 = document.getElementsByClassName('box2')[0];
box1.onclick = () => {console.log('我是盒子1')};
box2.onclick = () => {console.log('我是盒子2')};
document.onclick = () => {console.log('我是盒子document')};
window.onclick = () => {console.log('我是盒子window')};
</script>
事件捕获
最开始是在window对象触发click事件,然后在DOM上逐层向下传递,直到目标节点对象。
- 这种模型提供了拦截事件的可能,但是目标事件也没办法触发。也只有这种特殊情况才会使用它。
总结下来,没法阻止事件捕获,一旦阻止事件捕获,目标事件又不会触发。
DOM事件流
兼容上面两个事件模型。通过事件对象中的addEventListener方法,设定参数会执行不同的事件流模型。
我的想法事件流决定了事件监听节点,事件响应的先后顺序,也就是节点队列。
举例在DOM事件流模型中,不同的节点规定不同的事件流,节点队列的排序就是事件捕获的节点 -> 目标节点 -> 事件冒泡的节点。当浏览器接收到事件消息,事件处理引擎依照节点队列依次响应事件。
<body>
<div class="box1">
<span>盒子1</span>
<div class="box2">
<span>盒子2</span>
</div>
</div>
</body>
<script>
let box1 = document.getElementsByClassName('box1')[0];
let box2 = document.getElementsByClassName('box2')[0];
window.addEventListener('click', () => console.log('我是盒子window'), true);
document.addEventListener('click', () => console.log('我是盒子document'), true);
box1.addEventListener('click', () => console.log('我是盒子1'), false);
box2.addEventListener('click', () => console.log('我是盒子2'), false);
</script>