事件


2020-09-27 上次更新时间:4/29/2022, 9:34:08 AM 0

# 事件级别

事件级别又分 DOM0 级、DOM2 级、DOM3 级。

DOM0级事件:1. 直接在标签内直接添加执行语句,2. 定义执行函数

<input type="text" id="test">
<input type="button" value="button" onclick="alert(document.getElementById('test').value)">

<script>
    document.getElementById('button').onclick=function(){
        alert(document.getElementById('test').value);
    }
</script> 
1
2
3
4
5
6
7
8

DOM2 级事件:addEventListener

element.addEventListener('click',function(){},false)
1

DOM3 级事件:给 addEventListener 新增了更多事件类型,如鼠标事件、键盘事件等。

element.addEventListener('keyup',function(){},false)
1

# 事件流

# 事件冒泡

自下而上

事件冒泡:从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。

# 阻止事件冒泡

e.stopPropagation()

# 阻止节点绑定的其他事件

e.stopImmediatePropagation()

# 应用场景

  1. 实现事件代理

  2. 如果父或子元素同时绑定了事件,在执行子元素事件是不想触发父元素,那么子元素的事件需要停止冒泡,event.stopPropagation()

  3. 如果 li 内还包含有其他元素,那么点击时得到的event.target就不是 li 标签,就需要用到冒泡一级一级往上找,直到找到这个 li 标签才触发

# 事件捕获

自上而下

事件捕获:从顶层对象 document 发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。

# 实现事件捕获

addEventListener(event, fn, true/false) : 第三参数默认是false(冒泡),true(捕获)。

<div id="first">
    <button id="button">事件冒泡</button>
</div>

<script>
    // 结果:先执行first的事件,再执行button
    document.getElementById("button").addEventListener("click",function(){
        alert("button");
    },true);

    document.getElementById("first").addEventListener("click",function(){
        alert("first");
    },true);

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 阻止事件捕获

  • 阻止捕获,只要阻止事件执行,就可以阻止捕获,所以使用 stopPropagation() 也可以阻止捕获

# 事件监听

事件处理程序/事件监听的名字以on开头,因此 click 事件的事件处理程序就是 onclick,load 事件的事件处理程序就是 onload。

# html 事件

<input type="button" value="click" onclick="showMsg()">
1

# 添加/删除事件

  • 添加:addEventListener(event, fnName, true/false) 第三个参数为 true,表示在捕获阶段调用,false 则是在冒泡阶段调用
  • 删除:removeEventListener(event, fnName, true/false)

所有的 dom 节点都包含这两个方法。

addEventListener() removeEventListener() 属于Dom2 级事件处理程序

var btn = document.getElementById('myBtn');
btn.addEventListener("click", function() {
    console.log('点击了')
}, false);
1
2
3
4

注意点:

  • addEventListener 是可以添加多个的
  • addEventListener 后只能用 removeEventListener 移除,并且使用完后要记得移除,否则会占用内存
  • 最好加在冒泡阶段,也就是第三个参数不设置为 true,兼容型比较好

# 事件对象

在触发 Dom 的某个事件时,会产生一个事件对象 event,这个对象中包含所有与事件有关的信息。

每个 event 对象都有以下属性和方法,并且它们都是只读的。

属性/方法 类型 说明
bubbles Boolean 表明事件是否冒泡
cancelable Boolean 表明是否可以取消事件的默认行为
currentTarget Element 其事件处理程序当前正在处理事件的那个元素
target Element 事件的目标
defaultPrevented Boolean 为 true 表示已经调用了 preventDefault()(DOM3级事件中新增)
detail Integer 与事件相关的细节信息
eventPhase Integer 调用事件处理程序的阶段:1 表示捕获阶段,2 表示“处于目标”,3 表示冒泡阶段
type String 被触发的事件的类型
view AbstractView 与事件关联的抽象视图。等同于发生事件的window对象
preventDefault() Function 取消事件的默认行为。如果cancelable是true,则可以使用这个方法
stopImmediatePropagation() Function 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级事件中新增)
stopPropagation() Element 取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法

在事件处理程序内部,对象 this 始终等于 currentTarget 的值,而 target 则只包含事件的实际目标。如果直接将事件处理程序指定给了目标元素,则 this、currentTarget 和 target 包含相同的值。

# 事件委托/事件代理

例如一个列表中的每一个元素都需要一个点击效果,不需要每一个都绑定 click 事件,可以将事件委托给父级元素来触发,也就是事件委托。

事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

事件委托通过 addEventListener 实现。

<ul id="list">
    <li data-value="1">1111</li>
    <li data-value="2">2222</li>
    <li data-value="3">3333</li>
    <li data-value="4">4444</li>
</ul>
<script>
    var list = document.getElementById('list')
    list.addEventListener('click', function(event) {
        console.log('event', event.target) // 对应li
    })
</script>
1
2
3
4
5
6
7
8
9
10
11
12

# 事件类型

详细事件类型 - 《MDN - 事件参考》

上次更新时间: 4/29/2022, 9:34:08 AM