js:javascript中的事件体系:常见事件、事件监听、事件移除、事件冒泡、事件捕获、事件委托、阻止事件

参考资料

常见的事件

鼠标事件

事件 触发时机
click 鼠标的主键在一个元素上被按下和放开时
dblclick 在单个元素上单击两次鼠标的主按钮时
contextmenu 在用户尝试打开上下文菜单时
mousedown 鼠标按钮在元素内按下时
mouseup 鼠标按钮在元素内释放时
mouseenter 鼠标首次移动到元素的激活区域内时
mouseleave 鼠标指针移出某个元素时被触发
mousemove 鼠标的光标在元素内移动时

键盘事件

事件 触发时机
keypress 当按下产生字符或符号值的键时已弃用
keydown 键盘按键按下时(所有按键均会触发)
keyup 按键被松开时触发

Focus events

事件 触发时机
focus 元素获取焦点时
blur 元素失去焦点的时

添加事件监听

方式一:addEventListener()(推荐)

语法

addEventListener(type, listener);
addEventListener(type, listener, options);
addEventListener(type, listener, useCapture);

参数

参数名 类型 必须 说明
type String 监听事件类型(大小写敏感)
listener Funcion 当所监听的事件类型触发时,会接收到一个事件通知Event对象
options Objcet 可选 一个指定有关 listener 属性的可选参数对象
useCapture Boolean 可选 false事件冒泡;true事件捕获

options可选值

参数名 类型 必须 说明
capture Boolean 可选 事件捕获
once Boolean 可选 最多只调用一次 listener
passive Boolean 可选 表示 listener 永远不会调用 preventDefault()
signal AbortSignal 可选 该 AbortSignal 的 abort() 方法被调用时,监听器会被移除。

示例:绑定input获得焦点事件

<input
  type="text"
  id="input-name"
/>

<script>
  let inputName = document.querySelector('#input-name')

  inputName.addEventListener('focus', (event) => {
      
      
    console.log(event)
  })
</script>

addEventListener 方式可以在单个事件上添加多个监听器

<button>按钮</button>

<script>
  const btn = document.querySelector('button')

  // 添加多个事件处理器
  btn.addEventListener('click', () => {
      
      
    console.log('处理器1')
  })

  btn.addEventListener('click', () => {
      
      
    console.log('处理器2')
  })
</script>

方式二:事件处理器属性

示例:为div元素绑定click点击事件

<style>
  #box {
      
      
    width: 200px;
    height: 200px;
    background-color: gray;
  }
</style>

<div id="box"></div>

<script>
  let box = document.querySelector('#box')

  box.onclick = (event) => {
      
      
    console.log(event)
  }
</script>

事件处理器属性,不能为一个事件添加一个以上的处理程序,因为任何后续尝试都会覆写较早设置的属性

方式三:内联事件处理器(不推荐)

<input
  type="text"
  onfocus="handleFocus()"
/>

<script>
  function handleFocus(event) {
      
      
    let e = event || window.event

    console.log(e)
  }
</script>

你永远不应该使用 HTML 事件处理器属性——那些已经过时了,使用它们是不好的做法。

移除监听器

方式一:removeEventListener

<button>按钮</button>

<script>
  function handleButtonClick(event) {
      
      
    console.log(event)
  }

  const btn = document.querySelector('button')
  // 添加事件处理器
  btn.addEventListener('click', handleButtonClick)

  // 移除监听器
  btn.removeEventListener('click', handleButtonClick)
</script>

方式二:AbortController

<button>按钮</button>

<script>
  function handleButtonClick(event) {
      
      
    console.log(event)
  }

  const controller = new AbortController()

  const btn = document.querySelector('button')

  // 添加事件处理器
  btn.addEventListener('click', handleButtonClick, {
      
      
    signal: controller.signal, // 向该处理器传递 AbortSignal
  })

  // 移除任何/所有与该控制器相关的事件处理器
  controller.abort()
</script>

事件的控制

阻止默认行为 preventDefault

表单中只有一个输入框,默认键盘敲下回车就会提交表单,可以阻止这种默认行为

<!-- 表单 -->
<form id="form">
  <input
    type="text"
    id="name"
  />
</form>

<script>
  const form = document.querySelector('#form')
  
  form.addEventListener('submit', (e) => {
      
      
    e.preventDefault()
    console.log('submit');
  })
</script>

事件冒泡

当点击button时,外层容器也会接收到click事件

<div id="box">
  <button>点击</button>
</div>

<script>
  const btn = document.querySelector('button')
  const box = document.querySelector('#box')

  btn.addEventListener('click', (e) => {
      
      
    console.log('btn click')
  })

  box.addEventListener('click', (e) => {
      
      
    console.log('box click')
  })
</script>

输出顺序

btn click
box click

阻止事件冒泡 stopPropagation

使用stopPropagation可以阻止事件继续传播

<div id="box">
  <button>点击</button>
</div>

<script>
  const btn = document.querySelector('button')
  const box = document.querySelector('#box')

  btn.addEventListener('click', (e) => {
      
      
    e.stopPropagation() // 阻止冒泡
    console.log('btn click')
  })

  box.addEventListener('click', (e) => {
      
      
    console.log('box click')
  })
</script>

事件捕获

<div id="box">
  <button>点击</button>
</div>

<script>
  const btn = document.querySelector('button')
  const box = document.querySelector('#box')

  btn.addEventListener(
    'click',
    (e) => {
      
      
      console.log('btn click')
    },
    {
      
       capture: true }
  )

  box.addEventListener(
    'click',
    (e) => {
      
      
      console.log('box click')
    },
    {
      
       capture: true }
  )
</script>

输出(和冒泡顺序相反)

box click
btn click

事件委托

利用事件冒泡可以实现事件委托,简化代码

简单的事件监听

<div id="box">
  <button id="buttonA">点击A</button>
  <button id="buttonB">点击B</button>
</div>

<script>
  const buttonA = document.querySelector('#buttonA')
  const buttonB = document.querySelector('#buttonB')

  buttonA.addEventListener('click', (e) => {
      
      
    console.log('buttonA click')
  })

  buttonB.addEventListener('click', (e) => {
      
      
    console.log('buttonB click')
  })
</script>

使用事件委托,仅用监听外层元素的事件

<div id="box">
  <button id="buttonA">点击A</button>
  <button id="buttonB">点击B</button>
</div>

<script>
  const box = document.querySelector('#box')

  box.addEventListener('click', (e) => {
      
      
    // 事件触发元素 buttonA / buttonB
    console.log(e.target)

    // 获取元素id属性
    let targetId = e.target.getAttribute('id')
    console.log(targetId)

    // 处理元素 box
    console.log(e.currentTarget)
  })
</script>

参考文章

  1. 如何将事件作为参数传递给 JavaScript 中的内联事件处理程序?

猜你喜欢

转载自blog.csdn.net/mouday/article/details/131426784