Skip to content
本页目录

Event 事件

事件冒泡与事件捕捉

DOM 标准事件流的触发的先后顺序为:先捕获再冒泡。即先从根节点流向事件源,再从事件源流向根节点

事件监听方法

语法

JS
/**
 * @param { String } event 事件名称
 * @param { Function } listener 事件回调函数
 * @param { Boolean } [useCapture] 默认值为 false 冒泡,设置事件流向
 * 
*/
window.addEventListener(event, listener, useCapture)
/**
 * @param { String } event 事件名称
 * @param { Function } listener 事件回调函数
 * @param { Boolean } [useCapture] 默认值为 false 冒泡,设置事件流向
 * 
*/
window.addEventListener(event, listener, useCapture)
JS
// 监听
window.addEventListener('click', fn, true)

// 移除监听,需要对应监听的函数名称,如果是匿名函数,则无法移除
window.removeEventListener('click', fn, true)

function fn(event) { }
// 监听
window.addEventListener('click', fn, true)

// 移除监听,需要对应监听的函数名称,如果是匿名函数,则无法移除
window.removeEventListener('click', fn, true)

function fn(event) { }

阻止事件方法

  • e.preventDefault() 阻止默认浏览器动作,比如阻止 a 链接跳转
  • e.stopPropagation() 阻止事件的冒泡和捕获,使事件只作用在当前元素
  • return false 相当于执行以上两种方法,并返回

事件

1. 鼠标事件

  • MouseEvent() 鼠标事件构造器

  • click

  • dblclick

  • mouseenter 鼠标指针进入元素时触发,不会冒泡,事件不会被子元素捕捉,所以移动到子元素时不会触发

  • mouseover 鼠标指针在元素上移动时触发,事件会作用到子元素

  • mouseleave 鼠标指针离开元素,不会冒泡

  • mousedown 鼠标按下

  • mousemove 鼠标移动,

  • mouseup 鼠标抬起

  • contextmenu 鼠标右击事件,制作右击菜单时使用

  • mousewheel 鼠标滚轮事件,不同浏览器方向有差异(已废弃)

  • wheel 鼠标滚轮事件

触发顺序:mouseover -> mouseenter -> mousemove -> mouseout -> mouseleave

2. 表单事件

  • focusin 元素即将获取焦点
  • focus 元素获取到焦点,支持的元素有 input、radio、checkbox、select、textarea、button、window 等,tab 也可触发
  • focusout 元素即将失去焦点
  • blur 元素失去焦点
  • input <input type="text"> 时,输入内容变化触发,通过 js 动态修改值不会触发
  • change 内容发生改变触发,标签有 input、select、textarea (注意在 <input type="text"> 时需要 blur 才会触发)
  • reset
  • submit
  • search <input type="search"> enter 回车键触发
  • select <input> 或者 <textarea> 内容被选中时触发

3. 键盘事件

  • keydown 键盘按键按下时触发,不抬起会持续触发
  • keyup 按键抬起时触发
  • keypress 功能键按下不会触发

4. 浏览器事件

  • DOMContentLoaded DOM 解析完成触发此事件,它是 document 事件
  • load 页面所有资源加载完毕,它是 window 事件
  • error 资源加载出错时
  • beforeunload 页面刷新或关闭前(表单提示用户未保存)
  • unload 网页卸载
  • hashchange url hash 改变时触发
  • scroll 页面滚动
  • resize 调整窗口大小
  • visibilitychange 页面切换到后台或从后台切入

5. 触摸事件

  • touchstart
  • touchmove
  • touchend

6. 动画事件

  • animationstart 动画开始播放时触发
  • animationend 动画播放结束时触发
  • animationiteration 动画重复播放时触发
  • transitionend 过渡动画结束时触发

7. 其它

  • online 网络连接成功时触发
  • offline 网络离线时触发
  • popstate 浏览记录前进后退时触发,vue-routerhistory 实现方式
  • storage webStorage 内容发生改变时触发,详情查看存储模块
  • message 其它窗口 postMessage 事件触发

自定义事件

createEvent 使用的许多方法,如 initCustomEvent,都被废弃了

1. 使用 Event 构造函数创建

  • 优点:注册与触发简单
  • 缺点:无法传递数据

Event 构造函数:

JS
/**
 * @param { String } typeName 事件名称
 * @param { Object } [option] 事件配置
 * @param { Boolean } option.bubbles=false 该事件是否冒泡
 * @param { Boolean } option.cancelable=false 事件能否被取消
 * @param { Boolean } option.composed=false 事件是否会在影子 DOM 根节点之外触发侦听器
 * */ 
event = new Event(typeName, option);
/**
 * @param { String } typeName 事件名称
 * @param { Object } [option] 事件配置
 * @param { Boolean } option.bubbles=false 该事件是否冒泡
 * @param { Boolean } option.cancelable=false 事件能否被取消
 * @param { Boolean } option.composed=false 事件是否会在影子 DOM 根节点之外触发侦听器
 * */ 
event = new Event(typeName, option);

dispatchEvent() 派发事件

  • 原生事件会触发时会先进入事件队列,dispatchEvent() 不会,它是同步的
  • 事件派发方法可以绑定在任意的 dom 或方法里上调用

示例:

JS
// 注册事件
const event = new Event('build');

// 事件监听
window.addEventListener('build', function (e) { 
    console.log(e)
}, false);

// 派发事件
window.dispatchEvent(event);
// 注册事件
const event = new Event('build');

// 事件监听
window.addEventListener('build', function (e) { 
    console.log(e)
}, false);

// 派发事件
window.dispatchEvent(event);

2. 使用 CustomEvent 构造函数

Event 参数差不多,只是 option 中增加了 detail 属性,用来传递数据

  • 优点:可传递数据
JS
// 注册事件并传入数据
const event = new CustomEvent("custom:cat", { 
    detail: { 
        name: "mimi" 
    } 
})

// 事件监听
document.addEventListener("custom:cat", e => {
  console.log(e.detail) // { name: "mimi" }
})

// 派发事件
document.dispatchEvent(event)
// 注册事件并传入数据
const event = new CustomEvent("custom:cat", { 
    detail: { 
        name: "mimi" 
    } 
})

// 事件监听
document.addEventListener("custom:cat", e => {
  console.log(e.detail) // { name: "mimi" }
})

// 派发事件
document.dispatchEvent(event)

事件委托

过于基础,举个例子,一个列表每个元素需要绑定一个事件,可以绑定在其父元素上,根据 event 实际作用的子元素信息,执行相应的方法。