JavaScript 事件高级
1 注册事件(绑定事件)
(1) 概述
<1> 给元素添加事件,称为注册事件或者绑定事件。
<2> 注册事件有两种方式:传统方式和方法监听注册方式。
传统方式见 DOM 3 添加事件
<3> 两种注册事件方式的区别:
<3.1> 传统方式中,同一元素、同一事件只能有一个事件处理程序,若有两个,后一个会覆盖前一个。
<3.2> 方法监听方式中,同一元素、同一事件可以注册多个监听器(即事件处理程序),执行时依次执行。
(2) addEventListener事件监听方式
<1> 目标对象.addEventListener(事件类型字符串,事件处理函数,useCapture); //useCapture:可选参数,不写默认是false。
//IE9以上版本支持
<2> 目标对象.addEventListener()方法将指定的监听器注册到目标对象上,当该对象触发指定的事件时,就会执行事件处理函数。
<3> 该方法所接收的参数
<3.1> 事件类型字符串:比如click、mouseover,注意这里不要带on。
<3.2> 事件处理函数:事件发生时,会调用该监听函数。
<3.3> useCapture:可选参数,是一个布尔值,默认是false。
<4> 使用
div.addEventListener('click',function(){
alert("div被点击");
})
(3) attachEvent事件监听方式
<1> 目标对象.attachEvent(事件类型字符串,事件处理函数);
//IE9以前版本支持
<2> 目标对象.attachEvent()方法将指定的监听器注册到目标对象上,当该对象触发指定的事件时,指定的回调函数就会被执行。
<3> 该方法所接收的参数:
<3.1> 事件类型字符串:比如onclick、onmouseover,这里要带on
<3.2> 事件处理函数:当自标触发事件时回调函数被调用。
<4> 使用
div.attachEvent('onclick',function(){
alert("div被点击");
})
(4) 注册事件兼容性解决办法
处理兼容性原则:首先照顾大多数浏览器,再处理特殊浏览器。
function addEventListener(element,eventName,fn){
//判断当前浏览器是否支持addEventListener方法
if(element.addEventListener){
element.addEventListener(eventName,fn);
//判断当前浏览器是否支持attachEvent方法
}else if(element.attachEvent){
element.attachEvent('on'+eventName,fn);
}else{
//相当于element.onclick=fn;
element['on'+eventName]=fn;
//事件类型某种程度上也可以当作对象的一个属性来使用。
}
}
2 删除事件(解绑事件)
(1) 删除事件的方式
<1> 传统注册方式:目标对象.onclick = null;
<2> 方法监听注册方式
<2.1> 目标对象.removeEventListener(事件类型字符串,事件处理函数,useCapture);
//兼容firefox、chrome、IE、safari、opera,不兼容IE7、IE8。
<2.2> 目标对象.detachEvent(事件类型字符串,事件处理函数);
//兼容IE7、IE8,不兼容firefox、chrome、IE9、IE10、IE11、safari、opera。
(2) 删除事件兼容性解决办法
function removeEventListener(element,eventName,fn){
//判断当前浏览器是否支持addEventListener方法
if(element.removeEventListener){
element.removeEventListener(eventName,fn);
//判断当前浏览器是否支持attachEvent方法
}else if(element.detachEvent){
element.detachEvent('on'+eventName,fn);
}else{
//相当于element.onclick=null;
element['on'+eventName]=null;
}
}
3 DOM事件流
(1) 事件流描述的是从页面中接收事件的顺序。
//点击子元素时,首先所有父元素的单击事件被执行,然后该子元素的单击事件被执行,最后其父元素的单击事件再次被执行。
//但是Js代码中只能执行捕获或者冒泡其中的一个阶段,onclick和attachEvent只能得到冒泡阶段。
(2) 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
(3) DOM事件流分三个阶段:捕获阶段、当前目标阶段、冒泡阶段
事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
当前目标阶段:事件被具体元素接收。
事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到DOM最顶层节点的过程。
(4) 注意
<1> Js代码中只能执行捕获或者冒泡其中的一个阶段。
<2> onclick和attachEvent只能得到冒泡阶段。
<3> addEventListener第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false,表示在事件冒泡阶段调用事件处理程序。
<4> 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
<5> 有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave。
<6> 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件。
4 事件对象
(1) 概述
<1> event对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。
//简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象。目标对象.onclick=function(event){}目标对象.addEventListener('click',function(event){})
//这个event就是事件对象,我们还喜欢的写成e或者evt。
<2> event有很多属性和方法-,比如:
<2.1>谁绑定了这个事件。
<2.2>鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。
<2.3>键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。
(2) 事件对象的使用语法
<1> event是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
<2> 当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。
<3> 若要获取,只需要定义形参e即可。目标对象.onclick=function(event){}
(3) 事件对象的兼容性
<1> 事件对象本身的获取存在兼容问题:
<1.1> 标准浏览器中是浏览器给方法传递的参数,只需要定义形参e就可以获取到。
<1.2> 在IE 6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找。
<2> 解决办法:e = e || window.event;
//若e可以获取到,则逻辑表达式后后半部分不必执行,若e不可以获取到,则e=windows.event。
(4) 事件对象的常见属性和方法
<1> e.target:返回触发事件的对象。(标准)
<1.1> e.target返回的是触发事件的对象(元素),this返回的是绑定事件的对象(元素)。
<1.2> e.target与this的区别:e.target是点击了哪个元素,就返回哪个元素;this是哪个元素绑定了这个点击事件,那么就返回哪个元素。
<1.3> currentTarget:与this相似,返回绑定事件的元素。
<2> e.srcElement:返回触发事件的对象。(非标准) //IE6-8使用
兼容性解决办法
div.onclick=function(e){
e=e||windows.event;
var target=e.target||e.srcElement;
}
<3> e.type:返回事件的类型比如clickmouseover不带on。
<4> e.cancelBubble:该属性阻止冒泡。(非标准) //IE6-8使用
<5> e.returnValue:该属性阻止默认事件,即默认行为,比如阻止链接跳转。(非标准) //IE6-8使用
阻止默认行为,让链接不跳转,让按钮不提交。
<6> e.preventDefault():该方法阻止默认事件,即默认行为,比如阻止链接跳转。(标准)
也可以利用 return false 来阻止默认行为,没有兼容性问题,单return后面的代码不执行,而且仅限于传统的注册方式。
<7> e.stopPropagation():阻止冒泡。(标准)
(5) 阻止事件冒泡
<1> 阻止事件冒泡的两种方式
<1.1> 标准写法:利用事件对象里面的 stopPropagation()方法。
① e.stopPropagation();
② 案例阻止链接跳转
var a = document.querySelector('a');
//当用户点击a元素,即链接。
a.addEventListener('click',function(e){
//此时,阻止默认行为,即跳转。
e.stopPropagation();
})
<1.2> 非标准写法:IE6-8 利用事件对象cancelBubble属性。
<2> 阻止事件冒泡的兼容性解决办法
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true;
}
(6) 事件委托(代理、委派)
<1> 事件委托
事件委托也称为事件代理,在jQuery里面称为事件委派。
<2> 事件委托的原理
<2.1> 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
<2.2> 案例:给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。
var ul=document.querySelector('ul');
ul.addEventListener('click',function(e)){
//e.target可以得到真正点击的对象。
e.target.style.backgroundColor='pink';
}
<3> 事件委托的作用
我们只操作了一次DOM,提高了程序的性能。
(7) 常用的鼠标事件
//若事件类型为鼠标事件,那么事件对象类型即为鼠标事件对象MouseEvent。
<1> 常用鼠标事件
<1.1> 禁止鼠标右击菜单contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单。
//当用户右击打开菜单时。
document.addEventListener('contextmenu',function(e){
//此时,阻止默认行为,即显示右键菜单。
e.preventDefault();
})
<1.2> 禁止鼠标选中(selectstart开始选中)
//当用户开始选中文字时。
document.addEventListener('selectstart',function(e){
//此时,阻止默认行为,即选中。
e.preventDefault();
})
<2> 鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。我们主要是用鼠标事件对象MouseEvent和键盘事件对象KeyboardEvent。e.clientX:返回鼠标相对于浏览器窗口可视区的x坐标。e.clientY:返回鼠标相对于浏览器窗口可视区的y坐标。e.pageX:对于浏览器窗口可视区的x坐标。//IE9+支持e.pageY:对于浏览器窗口可视区的y坐标。//IE9+支持e.screenX:返回鼠标相对于电脑屏幕的x坐标。e.screenY:返回鼠标相对于电脑屏幕的y坐标。
(8) 常用的键盘事件
//若事件类型为键盘事件,那么事件对象类型即为键盘事件对象KeyboardEvent。
<1> 常用键盘事件
<1.1> onkeyup:某个键盘按键被松开时触发。
<1.2> onkeydown:某个键盘按键被按下时触发。
<1.3> onkeypress:某个键盘按键被按下时触发。但是它不识别功能键比如ctrl、shift、箭头等。
<1.4> 注意
① 如果使用addEventListener不需要加on。
② onkeypress和前面2个的区别是,它不识别功能键,比如左右箭头shift等。
③ 三个事件的执行顺序是:keydown、keypress、keyup。
<2> 键盘事件对象
<2.1> e.keyCode:返回该键的ASCII码值。
<2.2> 注意:
① onkeydown和onkeyup不区分字母大写,onkeypress区分字母大小写。
② 在我们实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)。
③ Keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值。

浙公网安备 33010602011771号