事件

作者: Long_Dark | 来源:发表于2020-03-25 19:36 被阅读0次

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

  • 基础

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

    事件冒泡
    2.事件捕获:不太具体的节点更早接收事件,而最具体的元素最后接收事件,和事件冒泡相反(ie低版本没有捕获)
    事件捕获
    3.DOM事件流:DOM2级事件规定事件流包括三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,首先发生的是事件捕获,为截取事件提供机会,然后是实际目标接收事件,最后是冒泡阶段
    DOM事件流
  • 事件传播机制

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


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

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

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

取消浏览器对当前事件的默认行为,像有些元素时有默认的事件的,比如<a>标签,在点击的时候默认会打开所含的超链接。如果想要自定义点击<a>链接的操作,就可以通过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
<style> 
    .container,
    .box,
    .target{
      border: 1px solid;
      padding: 10px;
    }  
  </style>
  <button id="btn">click</button>

  <div class="container">
    container
    <div class="box">
      box
      <div class="target">target</div>
    </div>
  </div>
js
<script>
  var $ = function(e){
    return document.querySelector(e)
  }
  $('.container').addEventListener('click',function(){
    console.log('container 捕获阶段')
  },true)
  $('.box').addEventListener('click',function(){
    console.log('box 捕获阶段')
  },true)
  $('.target').addEventListener('click',function(){
    console.log('target 捕获阶段')
  },true)
   $('.target').addEventListener('click',function(){
    console.log('target 冒泡阶段')
  },false)
  $('.box').addEventListener('click',function(){
    console.log('box 冒泡阶段')
  },false)
  $('.container').addEventListener('click',function(){
    console.log('container 冒泡阶段')
  },false)
//正常点击target  输出
//container 捕获阶段
//box 捕获阶段
//target 捕获阶段
//target 冒泡阶段
//box 冒泡阶段
//container 冒泡阶段
</script>
如果想让事件在 box冒泡阶段 停止
<script>
  var $ = function(e){
    return document.querySelector(e)
  }
  $('.container').addEventListener('click',function(){
    console.log('container 捕获阶段')
  },true)
  $('.box').addEventListener('click',function(){
    console.log('box 捕获阶段')
  },true)
  $('.target').addEventListener('click',function(){
    console.log('target 捕获阶段')
  },true)
   $('.target').addEventListener('click',function(){
    console.log('target 冒泡阶段')
  },false)
  $('.box').addEventListener('click',function(e){
    e.stopPropagations()  //这里不能用this 
    console.log('box 冒泡阶段')
  },false)
  $('.container').addEventListener('click',function(){
    console.log('container 冒泡阶段')
  },false)
//container 捕获阶段
//box 捕获阶段
//target 捕获阶段
//target 冒泡阶段
//box 冒泡阶段
</script>

3.解释DOM2事件传播机制

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

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

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

<ul>
  <li class="box">box1</li>
  <li class="box">box2</li>
</ul>
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>元素前添加一个新元素,内容为用户输入的非空字符串;当点击结尾添加时在最后一个 li 元素后添加用户输入的非空字符串.
  • 当点击每一个元素li时控制台展示该元素的文本内容。
<ul class="ct">
  <li>这里是</li>
  <li>饥人谷</li>
  <li>任务班</li>
</ul>
<input class="ipt-add-content" placeholder="添加内容"/>
<button id="btn-add-start">开头添加</button>
<button id="btn-add-end">结尾添加</button>
<script>
//你的代码
</script>
<script>
  var $ = function(e){
    return document.querySelector(e)
  }
  
  var ct = $('.ct')
  var addstr = $('#btn-add-start')
  var addend = $('#btn-add-end')
  var input = $('.ipt-add-content')
  
  addstr.onclick = function(){
    if(input.value !== ''){
      var box = document.createElement('li')
      box.innerText = input.value
      ct.insertBefore(box, ct.firstChild)
    }
  }
  
  addend.onclick = function(){
    if(input.value !== ''){
      var box = document.createElement('li')
      box.innerText = input.value
      ct.appendChild(box)
    }
  }
  
  $('.ct').addEventListener('click', function(s){   //监听点击
    if(s.target.tagName.toLowerCase() === 'li'){
      console.log(s.target.innerText)
    }
  })
</script>

5.onlick与addEventListener的区别

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

相关文章

  • JavaScript事件01——事件流

    大纲:概念(事件、事件流)事件流模型(事件冒泡、事件捕获、DOM事件流) 一、概念: 1、事件:事件就是用户或浏览...

  • 事件对象,事件监听,事件冒泡,事件代理

    一、事件对象 二、冒泡事件:(事件从子元素往父级元素向上触发事件)处理兼容问题:主流浏览器:e.stopPropa...

  • 事件总结

    DOM事件主要内容 事件流 事件注册 事件对象 事件分类 事件代理 什么是DOM事件? 事件是某个行为或者触发,比...

  • Javascript事件系统

    本文内容 事件基础 事件监听方式 事件默认行为 事件冒泡与事件捕获 事件绑定与事件委托 事件基础 注意:本文不会深...

  • Javascript事件-事件冒泡,事件捕获,事件监听和事件委托

    事件处理机制 (一)DOM事件流 DOM模型是一个树形结构,在DOM模型中,HTML元素是有层次的。当一个HTML...

  • 【事件】事件流

    1、JavaScript和HTML之间的交互通过事件实现的。2、事件流描述的是从页面中接收事件的顺序。3、IE 和...

  • 【事件】事件对象

    触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的额信息。(包括导致事件的元...

  • 【事件】事件类型

    DOM3 级事件规定了以下几类事件: UI(User Interface,用户界面)事件,当用户与页面上的元素交互...

  • 2018-09-10JQuery高级应用

    JQuery事件 window事件 鼠标事件 键盘事件 表单事件 事件注册语法$(对象).type(fn)type...

  • JS事件

    ?事件的相关术语 事件类型: 鼠标事件、键盘事件事件名称: click、dbclick等事件目标: 表示与发生事件...

网友评论

      本文标题:事件

      本文链接:https://www.haomeiwen.com/subject/odfxuhtx.html