事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。事件是系统天生自带的,JavaScript 与 HTML 之间的交互是通过事件实现的。

可以使用侦听器(或事件处理程序)来预订事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察者模式,支持页面的行为与页面的外观之间的松散耦合。

1. 事件类型

JS 常用事件:

  • 鼠标事件

    • click:点击(pc 端是点击,移动端是单击,移动端使用 click 会有 300ms 延迟问题),按下,抬起后触发

    • dblclick:双击,大约 300ms 内连续点击两次

    • mouseover:鼠标滑过

    • mouseout:鼠标滑出

    • museenter:鼠标进入

    • mouseleave:鼠标离开

    • mousemove:鼠标滑动,在元素可视区域内移动就触发

    • mousedown:鼠标按下(左右键),按下就触发

    • mouseup:鼠标松开(左右键),click 是按下抬起后触发,而且是先把 down 和 up 触发,才会触发 click

    • mousewheel:鼠标滚轮事件

  • 键盘事件

    • keydown:键盘按下,获取的是键盘码

    • keyup:键盘松开

    • keypress:键盘按下,获取的是 ASCII 码,一般不使用。长按会一致触发 keydown 和 keypress

    • input:由于 PC 端有物理键盘,可以监听到键盘的按下和松开,但是移动端是虚拟的键盘,所以 keydown 和 keyup 在大部分手机上都没有,我们使用 input 事件统一代替(内容改变事件)

  • input 框事件

    • focus:获得焦点

    • blur:失去焦点

    • change:内容改变

input 的值是在 keydown 之后,keyup 之前改变的,而且它的值都是字符串类型

input 只能输入数字:

  1. inp.onkeyup = function() {
  2. this.value = this.value.replace(/\D+/g, '');
  3. }
  • 系统事件:

    • load:资源加载完毕(包含图片)

    • unload:

    • beforeunload:

    • scroll:滚动条滚动

    • window.onresize:可视窗口大小发生改变

    • $(document).ready:JQ 的事件 DOM 树加载完毕

  • 移动端事件

    • [touch]单手指操作

      • touchstart:手指按下

      • touchmove:手指移动

      • touchend:手指离开

      • touchcancel:因为意外情况导致手指操作取消

    • [gesture]多手指操作

      • gesturestart:手指按下

      • gesturechange:手指改变

      • gestureend:手指离开

  • H5 中的 audio/video 音视频事件

    • canplay:可以播放(播放过程中可能出现由于资源没有加载完成,导致的卡顿)

    • canplaythrough:资源加载完成,可以正常无障碍播放

2. mouseenter 和 mouseover 的区别

mouseover

  1. inner.onmouseover = function() {
  2. console.log('inner over');
  3. }
  4. inner.onmouseout = function() {
  5. console.log('inner out');
  6. }
  7. outer.onmouseover = function() {
  8. console.log('outer over');
  9. }
  10. outer.onmouseout = function() {
  11. console.log('outer out');
  12. }
  1. 当进入 outer 时,触发 outer over,

  2. 当进入 inner 时,先触发 outer out,再触发inner over,再触发 outer over

  3. 当离开 inner,进入 outer 时,先触发 inner out,再触发 outer out,再触发 outer over

即使结构上是包含的关系,进入 inner 也会离开 outer,使得触发事件特别乱且多。而我们想要的是,进入 inner 时,不会离开 outer,也不会再传播触发 outer over

mouseenter

  1. inner.onmouseenter = function() {
  2. console.log('inner over');
  3. }
  4. inner.onmouseleave = function() {
  5. console.log('inner out');
  6. }
  7. outer.onmouseenter = function() {
  8. console.log('outer over');
  9. }
  10. outer.onmouseleave = function() {
  11. console.log('outer out');
  12. }

上面相同流程下来,只触发了四次事件,outer enter、inner enter、inner leave、outer leave。减少了事件触发,也防止不必要的执行。

区别总结:

  1. over 属于滑过事件,从父元素进入子元素,属于离开父元素,会触发父元素的 out,触发子元素的 over,然后又冒泡到父元素的 over

  2. enter 属于进入,从父元素进入子元素,并不算离开父元素,不会触发父元素的 leave,只触发子元素的 enter

  3. enter 和 leave 阻止了事件的冒泡传播,而 over 和 out 还存在冒泡

所以对于父元素嵌套子元素这种情况,使用 over 会发生好很多不愿意操作的事情,此时我们会使用 enter 会更加简单,操作方便,所以真实项目中 enter 的使用比 over 多。

需要注意的是,由于 enter 阻止了冒泡,所以使用事件委托的时候,不能使用 enter