Skip to content

事件对象 ​

事件 ​

事件函数:事件要调用的函数;

事件处理函数:事件触发时要执行的函数;

事件对象:事件发生时,与这个事件有关的信息保存的一个对象;

当一个事件发生时,将有关信息保存在事件函数的内置全局对象 event 当中,可以直接使用,包括事件类型,操作对象,鼠标位置;

常用的内置对象:

  • type:获取事件类型;

  • target(srcElement(ie8-)):获取触发事件的对象;

  • clientX/Y:鼠标到文档可视区的坐标点;

  • offsetX/Y:当前位置距离上一个定位元素的距离

  • screenX/Y:当前位置距离屏幕的坐标点

  • pageX/Y,鼠标到文档的距离,包括滚动的地方;ie8 以下没有;

  • e.button 0 是鼠标左键,1 是滚动按下 2 是鼠标右键

IE/谷歌:使用事件函数内的内置对象;

标准浏览器:使用事件函数的第一个参数形参;

做兼容:

js
//如果不做ie8兼容,就可以不用写
div.onclick = function (ev) {
  var ev = ev || window.event
}
//如果不做ie8兼容,就可以不用写
div.onclick = function (ev) {
  var ev = ev || window.event
}

事件绑定 ​

  • 定义:在一个元素上绑定多个事件,不会覆盖,都会执行;

  • obj.addEventListener("click",fn,false); 标准,true(捕获),false(冒泡);this 指向自己;

事件不需要加 on,事件处理函数,布尔值); 缺点:不兼容 IE;

  • 元素.attachEvent(事件(要加 on),事件处理函数);只有冒泡;倒序执行;IE8 及以下;非标准;this 指向 window;

做兼容:

js
function setEvent(obj, even, fn) {
  //元素,事件,事件处理函数;
  if (obj.attachEvent) {
    obj.attachEvent('on' + even, fn)
  } else {
    obj.addEventListener(even, fn, true)
  }
}
function setEvent(obj, even, fn) {
  //元素,事件,事件处理函数;
  if (obj.attachEvent) {
    obj.attachEvent('on' + even, fn)
  } else {
    obj.addEventListener(even, fn, true)
  }
}

标准浏览器的事件绑定和 ie 浏览器的事件绑定的区别:

(1)ie 没有捕获,标准有捕获

(2)ie 的事件名称前面有 on,标准没有

(3)标准的 ie 会根据事件的顺序正序执行,非 ie 标准逆序,标准正序

(4)ie 的 this 是 window,标准的是触发这个事件的对象

(4)标准浏览器的事件绑定和 ie 浏览器的事件绑定是不共存的,因此我们需要进行一个兼容的操作,一般情况下,如果是两个方法的兼容,那么就拿出其中一个方法,在各个浏览器中查看获取的值,标准浏览器和 ie 浏览器会得到不一样的结果。

取消事件绑定 ​

取消事件绑定最好明确函数的名字,不然会有很多不确定的因素;

  • 普通的:元素.onclick = null;

  • addEventListener 事件函数:removeEventListener("事件",事件处理函数);

  • attachEvent 事件函数:detachEvent("事件",事件处理函数);

事件流 ​

捕获: 当父元素和子元素都绑定了事件,先触发父元素,再触发子元素,从外到内;

冒泡: 先触发子元素再触发父元素,从内到外;

事件发生时会在元素节点与根节点之间按照特定的顺序传播,路径所经过的所有节点都会收到该事件,这个传播过程即 DOM 事件流。

DOM 事件流会有 3 个阶段:

事件捕获阶段:事件的传播是从最不特定的事件目标到最特定的事件目标。即从 DOM 树的根到叶子。

确定目标阶段:通过捕获确定具体触发事件的元素

事件冒泡阶段:事件的传播是从最特定的事件目标到最不特定的事件目标。即从 DOM 树的叶子到根。

阻止冒泡事件(掌握) ​

问题:子元素设置事件,再给其父元素设置事件,当触发子元素事件的时候,其父元素的事件也触发了,子元素监听到触发事件,所有包含事件的父元素都会触发;

阻止:

event.stopPropagation();IE8 以下不兼容; Propagation 传播传递

event.cancelBubble=true;IE8 以下兼容; Bubble 冒泡,cancel 取消;

做兼容:

js
event.stopPropagation ? event.stopPropagation() : (window.event.cancelBubble = true)
event.stopPropagation ? event.stopPropagation() : (window.event.cancelBubble = true)

注意:不是所有的事件都能冒泡,blur、focus、load、unload不能冒泡;

事件委托 ​

  • 将子元素要做的事情委托给父元素;event.target

  • 使用场景:子元素很多,事件相同的使用,后添加的相同元素会有相同的脚本

  • 原理:事件委托是利用事件冒泡原理来实现的,因为点击子元素会冒泡到父元素,那么给父元素做点击事件,里面的元素做点击事件时,都会冒泡到父元素身上,这就是事件委托,委托它们的父级代为执行事件

  • 事件委托实现:将事件添加到父元素上,当事件发生时,父元素会找到对应触发事件的子元素去处理,后期添加的子元素,依然有这个事件

事件源不兼容 IE8-,IE8 支持:event.srcElement;

事件源兼容:

js
var target = ev.target || ev.srcElement
var target = ev.target || ev.srcElement

取消事件默认行为 ​

  • return false;对事件绑定设置的不起作用,也可以直接使用以下的两种;

  • 事件绑定的阻止默认行为:event.preventDefault();

  • IE 事件绑定:event.returnValue = false;

总结 ​

事件绑定取消事件绑定阻止事件冒泡事件委托取消默认行为
通常obj.事件=函数onclick = nullreturn false
标准浏览器addEventListenerremoveEventListenerstopPropagationevent.targetevent.preventDefault()
非标准浏览器attachEventdetachEventcancelBubbleevent.srcElementevent.returnValue = false;

键盘事件 ​

  • onkeydown;按下;不区分大小写

  • onkeyup;抬起;

  • onkeypress;比 onkeydown 后触发,区分大小写,只能包含数字和字母,大小写是反过来的;不能获取到功能键,如箭头;

键盘值: event.key 获得按下的键;

event.keyCode 获得按下的键码值,字母为大写的 Unicode 码;

event.shiftKey;是否按下 shift 键,返回布尔值;

event.ctrlKey;是否按下 ctrl 键;

event.altKey;是否按下 alt 键;

  • 扩展

compositionstart 中文输入法输入开始时触发。

compositionend 中文输入法输入结束时触发。

鼠标滚轮事件: ​

元素.onmousewheel 滚动的时候触发;

event.wheelDelta:120 向上滚动;-120 向下滚动;

火狐浏览器需要通过绑定事件获取:

div.addEventListener("DOMMouseScroll",事件处理函数);

event.detail:-3 向上滚动,3 向下滚动;

customEvent 事件 ​

自定义事件,就跟 vue 里面的 on 跟 emit 一样

监听自定义事件

js
window.addEventListener('follow', (event) => {
  console.log(event.detail) // {name:'前端'}
})
window.addEventListener('follow', (event) => {
  console.log(event.detail) // {name:'前端'}
})

派发自定义事件

js
window.dispatchEvent(
  new CustomEvent('follow', {
    detail: {
      name: '前端',
    },
  }),
)
window.dispatchEvent(
  new CustomEvent('follow', {
    detail: {
      name: '前端',
    },
  }),
)

例子:

js
var div = document.createElement('div')
div.click = function () {
  console.log('被点击了111111')
}
var click = new Event('click')
div.dispatchEvent(click)
var div = document.createElement('div')
div.click = function () {
  console.log('被点击了111111')
}
var click = new Event('click')
div.dispatchEvent(click)

监控事件 ​

  • 使用 monitorEvents 侦听特定类型的事件。
  • 使用 unmonitorEvents 停止侦听。
  • 使用 getEventListeners 获取 DOM 元素的所有事件
  • 使用“Event Listeners Inspector”面板获取有关事件侦听器的信息。

获取元素绑定的事件对象:getEventListeners(元素); 需要在控制台打印:

监控元素上的事件命令: monitorEvents 和 unmonitorEvents

monitorEvents(元素,[可选的事件名字])

js
monitorEvents(document, 'click')
monitorEvents(document, 'click')

try catch ​

用来捕获出错的代码,try..catch 只能捕获同步代码,不能捕获异步代码的错误;

如果出错了,则不能执行下面的步骤,因此可以使用 try 来捕获错误

js
try {
  //可能成功的事件
} catch (e) {
  //捕获错误
} finally {
  // 无论成功于否都会执行
}
try {
  //可能成功的事件
} catch (e) {
  //捕获错误
} finally {
  // 无论成功于否都会执行
}