事件对象
事件
事件函数:事件要调用的函数;
事件处理函数:事件触发时要执行的函数;
事件对象:事件发生时,与这个事件有关的信息保存的一个对象;
当一个事件发生时,将有关信息保存在事件函数的内置全局对象 event 当中,可以直接使用,包括事件类型,操作对象,鼠标位置;
常用的内置对象:
type:获取事件类型;target(srcElement(ie8-)):获取触发事件的对象;clientX/Y:鼠标到文档可视区的坐标点;offsetX/Y:当前位置距离上一个定位元素的距离screenX/Y:当前位置距离屏幕的坐标点pageX/Y,鼠标到文档的距离,包括滚动的地方;ie8 以下没有;e.button0 是鼠标左键,1 是滚动按下 2 是鼠标右键
IE/谷歌:使用事件函数内的内置对象;
标准浏览器:使用事件函数的第一个参数形参;
做兼容:
//如果不做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;
做兼容:
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 取消;
做兼容:
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;
事件源兼容:
var target = ev.target || ev.srcElementvar target = ev.target || ev.srcElement取消事件默认行为
return false;对事件绑定设置的不起作用,也可以直接使用以下的两种;事件绑定的阻止默认行为:
event.preventDefault();IE 事件绑定:
event.returnValue = false;
总结
| 事件绑定 | 取消事件绑定 | 阻止事件冒泡 | 事件委托 | 取消默认行为 | |
|---|---|---|---|---|---|
| 通常 | obj.事件=函数 | onclick = null | return false | ||
| 标准浏览器 | addEventListener | removeEventListener | stopPropagation | event.target | event.preventDefault() |
| 非标准浏览器 | attachEvent | detachEvent | cancelBubble | event.srcElement | event.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 一样
监听自定义事件
window.addEventListener('follow', (event) => {
console.log(event.detail) // {name:'前端'}
})window.addEventListener('follow', (event) => {
console.log(event.detail) // {name:'前端'}
})派发自定义事件
window.dispatchEvent(
new CustomEvent('follow', {
detail: {
name: '前端',
},
}),
)window.dispatchEvent(
new CustomEvent('follow', {
detail: {
name: '前端',
},
}),
)例子:
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(元素,[可选的事件名字])
monitorEvents(document, 'click')monitorEvents(document, 'click')try catch
用来捕获出错的代码,try..catch 只能捕获同步代码,不能捕获异步代码的错误;
如果出错了,则不能执行下面的步骤,因此可以使用 try 来捕获错误
try {
//可能成功的事件
} catch (e) {
//捕获错误
} finally {
// 无论成功于否都会执行
}try {
//可能成功的事件
} catch (e) {
//捕获错误
} finally {
// 无论成功于否都会执行
}
Cao Note