接触项目以来一直用的是框架,原生很多东西很基础自己却没掌握好,总结一下关于dom事件。
dom事件指的就是dom.Event,表示在dom 中发生的任何事件,大致可以包括:用户交互操作产生(例如鼠标或键盘事件),或者由 API 生成(例如指示动画已经完成运行的事件,视频已被暂停等等)。
dom的事件流分为三个阶段:

  1. 捕获阶段:当我们在 DOM 树的某个节点发生了一些操作(例如单击、鼠标移动上去),就会有一个事件发射过去。这个事件从 Window 发出,不断经过下级节点直到触发的目标节点。在到达目标节点之前的过程,就是捕获阶段(Capture Phase)。事件由页面元素接收,逐级向下,到具体的元素。

  2. 目标阶段:当事件不断的传递直到目标节点的时候,最终在目标节点上触发这个事件,就是目标阶段。具体的元素本身。

  3. 冒泡阶段:事件冒泡即事件开始时,由最具体的元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点。跟捕获相反,具体元素本身,逐级向上,到页面元素(我们平时用的事件绑定就是利用的事件冒泡的原理)。

    事件捕获:当使用事件捕获时,父级元素先触发,子元素后触发。
    事件冒泡:当使用事件冒泡时,子元素先触发,父元素后触发

了解了事件的传递过程接下去看如何注册事件监听器,有三种注册事件监听器的方法
1.EventTraget.addEventListener平时使用中用的教多的一种方式,包含三个参数:监听事件的类型(比如click等),具体事件(一般是一个函数),冒泡或者捕获事件(默认为false冒泡)

1
2
3
4
5
6
7
8
var app = document.getElementById('app'); 
var app1 = document.getElementById('app1');
app.addEventListener('click', function() {
alert('我是父元素')
})
app1.addEventListener('click', function() {
alert('我是子元素')
})

冒泡1
测试一下假如改变最后一个参数为true

1
2
3
4
5
6
7
8
 var app = document.getElementById('app');
var app1 = document.getElementById('app1');
app.addEventListener('click', function() {
alert('我是父元素')
}, true);
app1.addEventListener('click', function() {
alert('我是子元素')
})

看一下效果:
第三个参数
第三个参数 就是决定了我在冒泡的时候还是捕获的时候触发当前的事件 所以一开始默认是false 就是冒泡 当我们点击最里面事件 在最后由里向外传递的时候依次触发 然鹅当我只有把父组件的第三个参数改为true(捕获模式) 一开始点击子组件的时候才会在由外向里传递的过程中就触发了 父组件的弹窗 所以是把true放在父组件上 没毛病了😂
2.利用html属性

1
<button onclick='alert(123456)'>我是按钮</button>

一般不建议使用
3.dom事件属性

1
app1.onclick = function{alert('第三种模式')}

既然前面讲到了冒泡和捕获,在实际的项目中,因为事件捕获的存在有时候会影响我们需要的效果,举个,设计一个弹窗div,需求是在当点击弹窗之外的遮罩层(即window部分)的时候弹窗消失,但是因为事件冒泡的原因,当点击弹窗本身也会导致弹窗消失,此时我们就需要阻止冒泡啦~
w3c阻止冒泡方法是e.stopPropagation(),IE则是使用e.cancelBubble = true,可以用之前的来亲测一波:

1
2
3
4
5
6
7
8
9
10
var app = document.getElementById('app');
var app1 = document.getElementById('app1');
app.addEventListener('click', function() {
alert('我是父元素')
})
app1.addEventListener('click', function(ev) {
// console.log(ev)
ev.stopPropagation();
alert('我是子元素')
})

阻止默认事件
还有一个是事件委托,emmm…我的理解就是通过事件冒泡原理,把子元素的事件全都通过父级元素实现,比如一个ul列表,如果要在每一个li上绑定事件触发未免太麻烦了,于是乎我们可以把事件绑定在ul上,事件委托还用到一个dom属性,就是event.target,它表示触发事件的对象 (某个DOM元素) 的引用,举个:

1
2
3
4
var ul2 = document.getElementById('ul2');
ul2.addEventListener('click', function(ev) {
console.log(ev.target)
})

效果:
这样子我们就能捕获到每一个准确的子元素并且触发相应的事件了