事件

1.解释以下概念:事件传播机制、阻止传播、取消默认事件、事件代理

  • 基础

    什么是事件
    JavaScript和HTML的交互是通过事件实现的。事件是某个行为或者触发,比如点击、鼠标移动,图片加载等。
    什么是事件流
    事件流描述的是从页面中接收事件的顺序。当用户点击了一个有嵌套关系的元素时,那是先点击的是用户本身想要点击的被嵌套的元素,还是嵌套元素的父元素?这里有三种事件传播的模型:事件冒泡,事件捕获,DOM事件流。
    1.事件冒泡:事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的元素

    事件冒泡

    2.事件捕获:不太具体的节点更早接收事件,而最具体的元素最后接收事件,和事件冒泡相反(ie低版本没有捕获)
    事件捕获

    3.DOM事件流:DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段
    DOM事件流

  • 事件传播机制

当一个事件发生以后,它会在不同的DOM节点之间传播。这种传播分为三个阶段:


事件传播机制
  • 第一阶段,“捕获阶段”。:事件从document开始向下传,一直传到触发的目标节点上,在这个过程中会依次检测是否有节点绑定了事件的监听函数,如果有就会执行。
  • 第二阶段,目标阶段:事件到达目标节点,并且触发监听函数。
  • 第三阶段,冒泡阶段:从目标节点依次上传,直到document,再依次判断是否有节点绑定了监听函数。
    这种三阶段的传播模型,会使得一个事件在多个节点上触发,比如会在捕获阶段和冒泡阶段在一个节点上执行两次。
  • 阻止传播

如果有特殊情况,需要事件在某个节点上停止传播,就可以使用stopPropagation()取消事件进一步捕获或冒
泡,防止再触发定义在别的节点上的监听函数,但是不包括在当前节点上新定义的事件监听函数

document.querySelector('#box') = function(e){
e.stopPropagation() //阻止传播
}
  • 取消默认事件

取消浏览器对当前事件的默认行为,像有些元素时有默认的事件的,比如标签,在点击的时候默认会打开所含的超链接。如果想要自定义点击链接的操作,就可以通过preventDefault()取消事件默认行为

document.querySelector('a') = function(e){
e.preventDefault() //阻止默认事件
}
  • 事件代理

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数统一处理。指定一个事件处理程序,就可以管理某一类型的所有事件

document.querySelector('ul').addEventListener('click', function(event){
    if(event.target.tagName.toLowerCase() === 'li'){   //或者if(e.target.classList.contains('box'))用class来选择
        //监听ul下面的所有li
    }
})

如果之后再在ul里面添加li,监听函数也可以监听新增的li

2.写一个 Demo,演示事件传播的过程,演示阻止传播的效果

捕获阶段还是冒泡阶段,可以通过addEventListener第三个参数cancelable属性来控制。默认是falsse为冒泡阶段,可以设置为true变成捕获阶段

html+css

  

  
container
box
target
js

如果想让事件在 box冒泡阶段 停止

3.解释DOM2事件传播机制

如果用单独的事件绑定,比如

document.querySelector('.button').onclick = function(){
  console.log('1')
}
document.querySelector('.button').onclick = function(){
  console.log('2')
}
//2

想让.button在被点击的时候触发两个事件,此时第二个监听函数会覆盖第一个,最后的输出 结果只有2
这个时候不要把onclick当成一个触发时间,要把它看成一个“属性”,那么后面的“属性”会覆盖掉前面的“属性”

  • box1
  • box2
document.querySelectorAll('.box').onclick = function(){ console.log(this.innerText) } //一个都输出不了

因为选择的是一个数组,没有onclick,除非用数组的forEach去遍历每一个数组,但是写起来又特别的麻烦

DOM2级事件定义了两个方法用于处理指定和删除事件处理程序的操作:
addEventListener
removeEventListener
所有的DOM节点都包含这两个方法,并且它们都接受三个参数:
1.事件类型
2.事件处理方法
3.布尔参数,如果是true表示在捕获阶段调用事件处理程序,如果是false,则是在事件冒泡阶段处理
这时,想要实现上面的效果就很容易了

document.querySelector('.button').addEventListener('click', function(){
  console.log('1')
},false)
document.querySelector('.button').addEventListener('click', function(){
  console.log('2')
},false)
//1
//2

4.补全代码

要求:

  • 当点击按钮开头添加时在
  • 这里是
  • 元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串.
  • 当点击每一个元素li时控制台展示该元素的文本内容。
  • 这里是
  • 饥人谷
  • 任务班

5.onlick与addEventListener的区别

  • onclick事件在同一时间只能指向唯一对象
  • addEventListener给一个事件注册多个listener
  • addEventListener对任何DOM都是有效的,而onclick仅限于HTML
  • addEventListener可以控制listener的触发阶段(捕获/冒泡)。对于多个相同的事件处理器,不会重复触发,不需要手动使用removeEventListener清除
  • IE9使用attachEvent和detachEvent

你可能感兴趣的:(事件)