DOM中存在大量的事件,现在我们将在事件模型中对事件进行充分的认识。
并且如果我们想要得知一个事件被触发后的一些相关信息,比如:
事件发生的元素、键盘按键的状态、鼠标的位置等等信息,那么就需要用到就要从Event对象下去获取这些信息
12.01 - 事件模型
事件接口
on-*属性
通过标签下的on-属性我们可以给DOM绑定事件
示例代码
<!-- 标签属性 -->
<div id="box" onclick='alert(this.innerHTML);'>hello word</div>
// 标签对象属性
box.onclick = fucntion(){
alert(this.innerHTML);
}
相关特性
重复绑定的事件,只会生效最近一次绑定的函数
某些事件不能通过这样的方式绑定
EventTarget接口
addEventListener():给指定对象绑定一个指定事件的监听函数
示例代码
<p id="test">点我呀!</p> <script> test.addEventListener("click",function(){ alert("点到我啦!"); },false); </script>
参数
事件名:不带on前缀
事件函数
是否捕获
相关特性
可以重复的绑定相同的事件,这些事件的监听函数会依次执行
监听函数内的this同样指向触发事件的对象
冒泡参数为了保证兼容为必选参数,一般为false
removeEventListner():移除对象的指定的监听事件
示例代码
<p id="test">点我呀!</p> <script> // 监听函数 function fn(){ alert("点到我啦!"); } // 添加监听 test.addEventListener("click",fn,false); // 移除监听 test.removeEventListener("click",fn,false); </script>
参数
事件名
绑定的事件函数
绑定事件时是否捕获
相关特性
需要移除的事件名,事件函数,以及是否捕获必须一致
事件的传播阶段
事件触发之后会在有父子嵌套关系的元素之间如何进行传播,或者子级与父级同时绑定了相同的事件的时候,事件会以什么样的顺序触发这些都属于事件的传播阶段中发生的事情,这个过程可以分为三个阶段:
捕获阶段
:事件从window传递到目标元素前的阶段
目标阶段
:事件在目标元素上触发的阶段
冒泡阶段
:从目标元素返回window对象的阶段实际上 addEventListener() 的第三参数就是选择事件是否在捕获的阶段触发
不过一般情况下,我们都是冒泡阶段触发事件的情况较多
阻止事件冒泡
当我们不希望子级的事件在冒泡阶段传递给父级的时候,需要调用Event对象下的 stopPropagation() 方法来阻止事件继续向父级传递,比如:点击一个元素显示,点击文档其他任何地方的时候隐藏元素。
但是需要注意,只能阻止事件在冒泡阶段的传递
<div id="wrap">
<p id="box"></p>
</div>
<script>
box.addEventListener("click",function(e){
console.log("#box"); // "#box"
e.stopPropagation();// 阻止冒泡
},false);
wrap.addEventListener("click",function(e){
console.log("#wrap"); // 事件在#box冒泡阶段被阻止 不会打印 #wrap
},false);
</script>
事件的代理
利用事件的冒泡机制,在为一个元素的所有子级绑定同一事件的时候,可以不用单独的为所有子级元素绑定事件,而是绑定给父级进行代理,然后通过Event对象找到,触发事件的子级元素来处理子级业务逻辑
<div id="wrap">
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
</div>
<script>
wrap.addEventListener("click",function(e){
console.log(e.target.innerHTML);// 打印p标签的 innerHTML
},false);
</script>
Event对象
事件发生以后,会产生一个存储了
与当前事件发生时相关各种信息的
对象,这就是Event对象Event 对象在最新的浏览器下为事件函数的第一个参数
<div id="wrap">
test
</div>
<script>
wrap.addEventListener("click",function(e){
console.log(e);// MouseEvent 鼠标事件Event对象
},false);
</script>
事件目标节点相关的属性
绑定当前事件的节点:e.currentTarget
触发当前事件的节点:e.target
<div id="wrap">
<p id="box">test</p>
</div>
<script>
// 点击元素为p标签时
wrap.addEventListener("click",function(e){
console.log(e.target.id);// box 触发事件的事件源
console.log(e.currentTarget.id);// wrap 执行事件的节点
},false);
</script>
事件对象相关的属性
当前事件的类型:e.type
事件发生时与界面加载时的时间差:e.timeStamp
事件对象下的方法
阻止冒泡:e.stopPropagation()
阻止默认事件:e.preventDefault()
默认事件是指如,鼠标右键默认出现的菜单,a标签点击跳转,空格网页滚动,文本复制粘贴等浏览器默认存在的事件,如果阻止了默认事件这些事件将不会被触发
兼容相关
低版本IE下的Event对象与标准浏览器有可能存在的一定的差异,以下是一些兼容相关的资料
事件对象兼容
IE及某些版本的Chrome下的Event对象为 全局的 window.event
document.onclick = function(e){
e = e || window.event;
};
事件接口兼容
IE 下的事件绑定和解分别为 attachEvent() 和 datachEvent()
且this指向window 可以用 call() 方法执行改变this指向,事件名称需添加 "on" 字符串
function fn(){
alert(this);// window
document.datachEvent("onclick",fn)
}
document.attachEvent("onclick",fn);
阻止冒泡兼容
object.onclick = function(e){
e.stopPropagation?
e.stopPropagation():// 标准
e.cancelBubble = true;// IE
};
阻止默认事件兼容
除了调用 e.preventDefault()函数之外还有如下的阻止默认事件的方法:
e.preventDefault()
事件函数内:return false;
IE专用:e.returnValue = false;
document.onselectstart = function(e){
e = e || window.event;
// 阻止默认事件兼容
if(e.preventDefault){
e.preventDefault();
}else if(e.returnValue){
e.returnValue = false;
}else{
return false;
}
}
target
IE 下可能不存在 e.target 属性,低版本的IE下与之对应的为 e.srcElement
document.onclick = function(e){ e.target = e.target || e.srcElement; };
12.02 - 事件种类与Event
鼠标事件
事件列表
单击:click
双击:dblclick
移入:mouseover、mouseenter
移出:mouseout、mouseleave
按下:mousedown
抬起:mouseup
移动:mousemove
右键菜单事件:contextmenu
相关的Event属性
e.button:返回一个整数表示当前按下的鼠标键
0:按下了鼠标左键
1:按下了鼠标辅助键(鼠标滚轮)
2:按下了鼠标右键
ps:该属性在click时间下测试结果会出现差异只有在mousedown 或者 mouseup 事件的时候相对准确
e.clientX / e.clientY:返回鼠标事件发生时相对于
浏览器窗口
的位置e.pageX / e.pageY:返回鼠标事件发生时时相对于
整个文档
的位置
滚轮事件
鼠标的滚轮滚动的时候是一个单独的事件,可以根据 e.delta* 属性来判断鼠标滚动的方向,但是不同的浏览器得到的值不尽相同需要进行兼容处理
事件名
Chrome:
wheel
/mousewheel
Firefox:
wheel
/DOMMouseScroll (监听事件)
IE:
mousewheel
Event对象下的delta属性名
Chrome:
deltaY
/wheelDelta
Firefox:
deltaY (wheel)
/detail (DOMMouseScroll)
IE:
wheelDelta
方向表示值
Chrome / IE
下:120
上:-120
Firefox
下:-3
上:3
兼容方法
// 滚动兼容
function wheel(dom,callback){
var eName = "mousewheel";
// 判断是否为火狐
var ifFF = !(('on'+eName) in dom);
// 确定事件名
var event = ifFF?'DOMMouseScroll':eName;
dom.addEventListener(event,function(e){
// 阻止默认的滚动事件
e.stopPropagation();
e.preventDefault();
// 统一滚动方向的判断标准( e.delta<0 -- 上 , e.delta>0 -- 下)
e.delta = ifFF?e.detail:e.wheelDelta*-1;
callback && callback.call(this,e);
},false);
}
键盘事件
事件列表
keydown:按下键盘时
keypress:只要按下的键并非Ctrl、Alt、Shift和Meta,就接着触发keypress事件。
keyup:松开键盘时
相关的Event属性
e.altKey:是否按下alt键
e.ctrlKey:是否按下ctrl键
e.metaKey:是否按下meta键
e.shiftKey:是否按下shift键
e.key:返回按下的键名的字符串
e.keyCode:返回按下的键的键值数值
键盘事件的绑定对象
键盘事件的绑定对象一般为输入框等可以进行内容输入的元素,如果想要在文档的任何位置都能直接按键触发事件那么需要给window对象绑定事件
表单事件
事件列表
表单元素事件
input:元素的值发生改变的时候实时触发
change:元素的值改变完成后触发
focus:获取焦点的事件
blur:失去焦点的事件
表单对象事件
reset:表单重置时触发
submit:表单提交的时候触发
表单方法
表单元素方法
focus():获取焦点
blur():失去焦点
click():点击元素
select():选中文本
常用于被隐藏的文件选择表单元素(type=file)
表单对象方法
submit():提交表单
reset():重置表单
文档事件
除开用户进行手动触发的事件之外,文档在加载的过程中也会默认的触发一些事件
事件列表
load:资源或者界面成功加载完成的时候触发
DOMContentLoaded:文档个下载解析完成,但是还没有加载外部资源(图片,样式表,iframe等)还没有加载完成的时候触发,此事件的触发比 load事件提前许多
scroll:文档或者元素滚动条滚动的时候触发
resize:窗口的大小发生改变的时候触发,一般发生在 window、body、frameset对象上
CSS事件
一些样式触发的事件
事件列表
transitionend:过渡完成的时候触发事件
需要注意的是,改元素上每个在进行过渡的属性过渡完成的时候都会触发一次改事件,如果只想监听某一个属性是否过渡完成,可以通过判断 e.propertyName 属性来进行筛选
相关的Event属性
e.propertyName:触发事件的属性
wrap.addEventListener('transitionend',(e)=>{
console.log(e.propertyName)
});