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等。
③ 三个事件的执行顺序是:keydownkeypresskeyup
<2> 键盘事件对象
<2.1> e.keyCode:返回该键的ASCII码值。
<2.2> 注意:
onkeydownonkeyup不区分字母大写,onkeypress区分字母大小写。
② 在我们实际开发中,我们更多的使用keydownkeyup,它能识别所有的键(包括功能键)。
Keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值。

posted @ 2023-05-30 16:01  10kcheung  阅读(73)  评论(0)    收藏  举报