前言
本教程是基于JavaScript高级教程第三版,自己用来学习并整理的知识点,仅供参考。
JS和HTML之间的交互是通过事件实现的。
13.1 事件流
事件流描述的是从页面中接收事件的顺序
- 事件冒泡
事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>事件流</title>
</head>
<body>
<div id="myDiv">Hello</div>
</body>
</html>
若点击div,click时间会按照如下传播 div->body->html->document
- 事件捕获——很少使用
不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件,与事件冒泡顺序相反
- DOM事件流
包括三个阶段——1. 事件捕获阶段 2. 处于目标阶段 3. 事件冒泡阶段
13.2 事件处理程序
事件就是用户或浏览器自身执行的某种动作,例如click、load等是事件的名字,响应某个事件的函数就叫事件处理程序(事件侦听器),以on开头
- HTML事件处理程序
<button onclick="alert('click')">点击</button>
这样指定事件处理程序会创建一个封装着元素属性值的函数,函数中有局部变量event,即事件对象
在函数内部,this就等于事件的目标元素
<button value="aaa" onclick="alert(this.value)">点击</button>
<button value="aaa" onclick="console.log(event)">点击</button>
会弹出aaa
弊端:会存在时差问题;拓展事件处理程序的作用域链在不同浏览器会导致不同结果;HTML和JS紧密耦合,更换事件处理程序就要改动两个地方
- DOM0级事件处理程序
将一个函数赋值给一个事件处理程序属性
var btn = document.getElementById("btn");
btn.onclick = function(){
console.log("click");
}
btn.onclick = null //删除事件处理程序
- DOM2级事件处理程序
//处理指定和删除事件处理程序的操作,接收三个参数:要处理的事件名、作为事件处理程序的函数和一个布尔值; true则在捕获阶段调用,false则冒泡阶段调用
addEventListener()
removeEventListener()
<button id="myDiv">点击</button>
var btn = document.getElementById("myDiv");
btn.addEventListener("click",function(){
console.log("哈哈");
},false)
btn.addEventListener("click",function(){
console.log("你好你好");
})
//使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序
//通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除,移除时传入的参数与添加处理程序时使用的参数相同,即addEventListener()添加的匿名函数将无法删除
btn.removeEventListener("click",function(){
console.log("你好你好");
}) //没有办法删除
var sayHi = function(){
console.log("你好你好");
}
btn.addEventListener("click",sayHi,false);
btn.removeEventListener("click",sayHi,false); //移除成功
- IE事件处理程序
attachEvent()和detachEvent()接受相同的两个参数,事件处理程序名称与事件处理程序函数
在全局作用域中运行 this等于window
- 跨浏览器的事件处理程序
addHandler()
removeHandler()
13.3 事件对象
event,包含着所有与事件有关的信息,包括导致事件的元素、事件的类型以及其他与特定事件相关的信息;鼠标操作导致的事件对象中会包含鼠标位置的信息
- DOM中的事件对象
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
console.log(event.type); //click
}
//event对象包含与创建它的特定事件有关的属性和方法
在事件处理程序内部 this始终等于event.currentTarget的值 而target只包含事件的实际目标
如果直接将事件处理程序指定给了目标元素,则this、currentTarget和target包含相同的值
//一个函数处理多个事件 可以用type
var handler = function(event){
switch(event.type){
case "click":
alert("Clicked");
break;
case "mouseover":
event.target.style.backgroundColor = "red"
break;
}
}
//阻止特定事件的默认行为preventDefault()
例:阻止链接导航
var baidu = document.getElementById("baidu");
baidu.addEventListener("click",function(event){
event.preventDefault()
})
stopPropagation()——立即停止事件在DOM层次中的传播,取消进一步的事件捕获或冒泡
eventPhase()——确定事件当前正位于事件流的哪个阶段
-
IE中的事件对象 略
https://www.likecs.com/show-308323561.html
-
跨浏览器中的事件对象 略
https://www.cnblogs.com/178-533/p/7535367.html
13.4 事件类型
- UI事件
不一定与用户操作有关的事件 只列几个
load:页面完全加载后在window上触发...
unload: 页面完全卸载后为window上面触发
error:当发生JS错误时在window上触发、
resize:当窗口或框架的大小变化时在window/框架上触发
scroll:当用户滚动带滚动条的元素中的内容时
window.addEventListener("scroll",function(){
console.log(document.documentElement.scrollTop);
})
- 焦点事件
在元素获取/失去焦点时触发
blur:在元素失去焦点时触发
focus:在元素获得焦点时触发,这个事件不会冒泡
...
- 鼠标与滚轮事件
click
dblclick 双击
mousedown 按下任意鼠标按钮触发
mousrenter 鼠标光标从外部首次移动到元素范围之内时触发 不冒泡
mouseleave 鼠标光标从外部首次移动到元素范围之外时触发 不冒泡
mousemove 鼠标指针在元素内部移动时重复地触发
mouseout 鼠标指针位于一个元素上方,然后用户将其移入另一个元素时触发
mouseover:鼠标指针位于一个元素外部,用户将其首次移入另一个元素边界之内触发
mouseup:用户释放鼠标按钮时触发
客户区坐标位置
clientX 鼠标指针在视口中地水平坐标
clientY 垂直坐标
var div = document.getElementById("myDiv");
div.addEventListener("click",function(event){
console.log(event.clientX);
console.log(event.clientY);
})
页面坐标位置
pageX
pageY
console.log('page',event.pageX);
console.log('page',event.pageY);
//当页面没有滚动时 page和client的值相等
//滚动时 page = client + scrollTop/Left
屏幕坐标位置 ——鼠标事件发生时鼠标指针相对于整个屏幕的坐标信息
screenX
screenY
修改键 Shift Ctrl Alt Meta
相关元素
鼠标按钮
event中button属性 0 主鼠标按钮 1 中间鼠标按钮 2 此鼠标按钮
触摸设备:没有鼠标
无障碍性问题
- 键盘与文本事件
keydown:按下键盘上的任意键触发,按住不放重复触发
keypress:按下键盘上的字符键触发...
keyup:释放键盘上的键时触发
键码
字母A——65
回车——13
字符编码charcode——只在发生keypress事件时才包含值 DOM3中不再包含
而是包含两个新属性key和char
textInput事件——当用户在可编辑区域中输入字符时触发
<input type="text" id="username">
var user = document.getElementById("username");
user.addEventListener("textInput",function(event){
console.log(event.data); //输一个字符,打印一次
})
- 复合事件——处理IME的输入序列
- 变动事件——在DOM中的某一部分发生变化时给出提示
- HTML5事件
contextmenu事件——鼠标右键调出上下文菜单
beforeload事件——浏览器卸载页面之前触发
DOMContentLoaded事件
readystatechange事件
pageshow和pagehide事件
haschange事件——URL参数列表发生变化时通知开发人员
- 设备事件
orientationchange事件——开发人员确定用户何时将设备由横向查看模式切换为纵向查看模式
...
- 触摸与手势事件
触摸事件
touchstart——手指触摸屏幕时触发
touchmove——手指在屏幕上滑动时连续地触发
touchend——手指从屏幕上移开时触发
touchcancle——系统停止跟踪触摸时触发
...
手势事件
13.5 内存和性能
在JS中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能
- 事件委托——解决事件处理程序过多
利用事件冒泡,只指定一个事件处理程序。就可以管理某一类型地所有时间
<ul id="myUl">
<li id="one">1</li>
<li id="two">2</li>
<li id="three">3</li>
</ul>
<script>
var myUl = document.getElementById("myUl");
myUl.addEventListener("click",function(event){
console.log(event.target.id);
switch(event.target.id){
case "one":
console.log("我是1");
break;
case "two":
console.log("我是2");
break;
case "three":
console.log("我是3");
break;
}
})
</script>
- 移除事件处理程序
13.6 模拟事件
- DOM中事件模拟
createEvent()方法创建event对象
模拟鼠标事件——createEvent("MouseEvents")——返回initMouseEvent方法
var btn = document.getElementById("myBtn");
//创建事件对象
var event = document.createEvent("MouseEvents");
//初始化事件对象
event.initMouseEvent("click",true,true,document.defaultView,0,0,0,0,0,false,false,false,false,0,null);
//触发事件
btn.dispatchEvent(event);
模拟键盘事件
模拟其他事件
- IE中的事件模拟 略