事件
事件是 JavaScript 与 HTML 的交互的实现。
事件冒泡流又称作 IE 事件流,被定义为从最具体的元素传播到不那么具体的元素,触发顺序也就是由深到表;事件捕获流,被定义为从最不具体的元素到最具体的元素,触发顺序也就是由表到深。
DOM0级事件:获取元素后,使用元素的事件属性绑定方法
const div = document.getElementById("div");
div.onclick = function() {
console.log(this.id);
}
在该段代码中,this 指的是元素本身(此处引申出一个 this 相关的指向问题)。如果需要移除对应事件程序,则将其对应的事件复制为 null
DOM2级事件:使用 addEventListener 和 removeEventListener (事件[不带on];触发函数;true[事件捕获] / false[默认,事件冒泡])
const div = document.getElementById("div");
div.addEventListener("click", function(){
console.log(this.id)
}, false);
注意 removeEventListener 无法删除匿名函数
IE版:attachEvent 和 detachEvent (事件[如 onclick];触发函数)
const div = document.getElementById("div");
div.attachEvent("onclick", function(){
console.log(this === window); // true
})
IE版的事件绑定作用域在全局中生效运行,所以this 等于window ;IE版事件绑定多次函数时,会从最后一个绑定的函数开始触发(逆序)
删除同 removeEventListener
跨浏览器事件处理程序
const EvnetUtil = {
// 绑定
addHandler: function(eve, type, callback){
if (eve.addEventListener) {
eve.addEventListener(type, callback);
} else if (eve.attachEvent) {
eve.attachEvent(on${type}
, callback);
} else {
eve[on${type}
] = callback;
}
},
// 删除
removeHandler: function(eve, type, callback){
if (eve.removeEventListener) {
eve.removeEventListener(type, callback);
} else if (eve.detachEvent) {
eve.detachEvent(on${type}
, callback);
} else {
eve[on${type}
] = null;
}
},
}
新写法
const btn = document.getElementById("myBtn");
const handler = function (event) {
switch(event.type){
case "click":
console.log("clicked");
break;
case "mouseover":
event.target.style.backgroundColor = "red";
break;
case "mouseout":
event.target.style.backgroundColor = "";
break;
}
}
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;
--
preventDefault() 阻止特定事件的默认动作,如链接跳转
stopPropagetion() 立即阻止事件流在DOM结构中的传播(比如按钮和body同时设置点击,但是按钮触发后不会继续冒泡到body)
IE事件对象
如果事件处理程序是使用 DOM0 方式指定的,则event 对象只是window 对象的一个属性
const btn = document.getElementById("myBtn");
btn.onclick = function () {
let event = window.event;
console.log(event.type); // click
}
如果事件处理程序是使用 DOM2 方式指定的(attachEvent ),则event 会作为唯一参数传给处理函数;
const btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(event){
console.log(event.type); // click
})
IE事件阻止默认行为;
const link = document.getElementById("myLink");
link.onclick = function(){
window.event.returnValue = false; // 取 false
}
IE事件阻止事件流传播;
const btn = document.getElementById("myBtn");
btn.onclick = function(){
window.event.cancelBubble = true; // 取 true
}
事件类型
用户界面事件(UIEvent):涉及与BOM交互的通用浏览器事件;
焦点事件(FocusEvent):在元素获得和失去焦点时触发;
鼠标事件(MouseEvent):使用鼠标在页面上执行某些操作时触发;
滚轮事件(WheelEvent):使用鼠标滚轮或类似设备时触发;
输入事件(InputEvent):向文档中输入文本时触发;
键盘事件(KeyboardEvent):使用键盘在页面上执行某些操作时触发;
合成事件(CompositionEvent):在使用某种 IME 输入字符时触发;
用户页面事件
‒ load:在 window 上当页面加载完成后触发 / 方式1:DOM0 或 DOM2 在 window 上绑定 / 方式2:向<body> 元素添加 onload 属性;
‒ unload:会在文档卸载完后触发,常用在从一个页面导航到另一个页面时触发,清理旧页面引用 / 方式1:DOM0 或 DOM2 在 window 上绑定 / 方式2:向<body> 元素上添加 onunload 属性;
‒ resize:当浏览器窗口被缩放到新的高宽度时触发,浏览器的最大化和最小化也会触发事件;
‒ scroll:当用户滚动包含滚动条的元素时触发;
‒ select:在文本框上当用户选择了一个或多个字符时触发;
‒ error:在 window 上当 JavaScript 报错时触发;
‒ abort
焦点事件
‒ blur:当元素失去焦点时触发,不冒泡;
‒ focus:当元素获取焦点时触发,不冒泡;
‒ focusin:同focus,冒泡版;
‒ focusout:同blur,冒泡版;
鼠标和滚轮事件
‒ click:在用户单击鼠标左键或按键盘回车键时触发;
‒ dbclick:在用户双击鼠标左键时触发;
‒ mousedown:在用户按下任意鼠标键时触发,不联动键盘;
‒ mouseenter:在用户把鼠标光标从元素外部移动到内部时触发,不冒泡,不会在后代元素上触发;
‒ mouseleave:在用户把鼠标光标从元素内部移动到外部时触发,不冒泡,不会在后代上触发;
‒ mousemove:鼠标在元素上移动时触发;
‒ mouseout:在鼠标从元素移动到另一个元素时触发,另一个元素可以是父级也可以是子级;
‒ mouseover:在用户把鼠标光标从元素外部移入内部时触发;
‒ mouseup:当用户释放鼠标键时触发;
‒ 客户端坐标:通过event 对象的clientX 和clientY 属性获取,基于浏览器视口;
‒ 页面坐标:通过event 对象的pageX 和pageY 属性获取,基于页面内容;
‒ 屏幕坐标:通过event 对象的screenX 和screeY 属性获取,基于屏幕;
‒ 修饰键:shiftKey、ctrlKey、altKey、metaKey
键盘与输入事件
‒ keydown:用户按下某个键时触发,持续按住持续触发;
‒ keyup:用户释放按键时触发;
‒ 使用keyCode 获取键码;
‒ textInput:只能在可编辑区域上,字符被输入时触发,使用 event.data 可以调出要插入的字符的内容
HTML事件
‒ contextmenu
‒ beforunload:页面即将从浏览器中卸载时触发;
‒ DOMContentLoaded:DOM树构建完成后立即触发;
‒ readystatechange:意在提供文档或元素加载状态的信息(原以为是Ajax里专属的,实际不是);
‒ pageshow、pagehide:pageshow在load之后触发,pagehide在unload之前触发;
设备事件
‒ orientationcahgne:判断手机属于垂直还是水平模式,window.orientation 属性可以获取
‒ deviceorientation:判断手机在XYZ轴上的旋转;
‒ devicemotion:判断设备在移动
触摸及手势事件
‒ touchstart:手指放在触摸屏上时触发
‒ touchmove:手指在触摸屏上滚动时触发,可以使用preventDefault() 阻止
‒ touchend:手指离开时触发;
‒ touchcancel:系统停止跟踪触摸时触发;
‒ gesturestart:一个手指已经在屏幕上,另一个手指放到屏幕上时触发;
‒ gesturechange:任何一个手指在屏幕上的位置发生变化时触发;
‒ gestureend:其中一个手指离开屏幕时触发;
性能与内存
- 事件委托:事件委托利用事件冒泡的机制,可以只使用一个事件处理程序来管理一种类型的事件
- 删除事件处理程序:使用 innerHTML 替换内容时,绑定在组件上的方法程序并没有跟着被清除