二、JavaScript语言--事件处理--DOM事件探秘
第一章 事件流
事件:是文档或浏览器窗口中发生的、特定的交互瞬间。JavaScript和HTML之间的交互都是通过事件来实现的。
事件流:描述的是从页面中接受事件的顺序
IE:事件冒泡流
Netscape:事件捕获流
事件冒泡:即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档)。
事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。
第二章 事件处理程序
1、HTML事件处理程序
HTML事件的缺点:HTML和JS代码紧密的耦合在一起。如果需要改事件处理程序,JS代码和HTML都需要进行修改。
例子:
2、DOM0级事件处理程序
较传统的方式:把一个函数赋值给一个事件的处理程序属性。是用的比较多的方法,原因是简单,有跨浏览器的优势。没有HTML事件的缺点。优点:可以给一个元素添加多个事件处理程序,按顺序执行。
例子:
3、DOM2级事件处理程序
DOM2级事件定义了两个方法:
用于处理指定和删除事件处理程序的操作
addEventListener()和removeEventListner()
接收三个参数:
语法为:
element.addEventListener(type,listener,useCapture)
要处理的事件名、作为事件处理程序的函数和布尔值(true-->表示在捕获阶段调用事件处理程序,false-->表示在冒泡阶段调用事件处理程序(可以兼容各种浏览器))。
•其中element是要绑定函数的对象。
•type是事件名称,要注意的是"onclick"要改为"click","onblur"要改为"blur",也就是说事件名不要带"on"。
•listener当然就是绑定的函数了,记住不要跟括号
•最后一个参数是个布尔值,表示该事件的响应顺序
优点:可以给一个元素添加多个事件处理程序,按顺序执行。
注意:用addEventListener()添加的事件,只能用removeEventListner()移除。且在IE中不好使。
例子:
4、IE事件处理程序
attachEvent()添加事件
detaEvent()删除事件
接收相同的两个参数:事件处理程序的名称(事件需要把on加上)和事件处理程序的函数
不使用第三个参数的原因:IE8以及更早的浏览器版本只支持事件冒泡。
支持IE事件处理程序的浏览器:IE和OPERA
例子:
注意:从IE11开始,已经开始使用DOM2级事件处理程序,而不再使用IE事件处理程序。
5、跨浏览器的事件处理程序(使用能力检测方法)
跨浏览器事件处理程序最好是封装在一个对象内,如下实例代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>跨浏览器的事件处理程序</title> </head> <body> <input type="button" value="按钮" id="btn"> <script type="text/javascript"> function showMsg() { alert("Hello World ! "); } var eventUtil = { //创建eventUtil对象 // 添加句柄 addHandler: function(element, type, handler) { //将添加事件封装在addHandler方法里面,添加三个参数,element:添加事件的对象,type:添加的事件类型,handler:触发怎样的操作 if (element.addEventListener) { //进行判断,如果支持DOM2级,则使用DOM2级添加事件 element.addEventListener(type, handler, false); } else if (element.attachEvent) { //如果支持DOM0级,则使用DOM0级添加事件 element.attachEvent('on' + type, handler); //不要直接写type,传入type事件类型的时候,需要传入没有on的事件类型,在这一步会给加上on } else { //如果支持HTML事件处理程序,则使用HTML事件处理程序添加事件 element['on' + type] = handler; //在JS当中,所有添加事件的方法,这两种写法是等价的 element.onclick=function(){}等价于element['onclick']=function(){} } }, // 删除句柄 removeHandler: function(element, type, handler) { //将删除事件封装在emoveHandler方法里面 if (element.removeEventListener) { element.removeEventListener(type, handler, false); } else if (element.detachEvent) { element.detachEvent('on' + type, handler); } else { element['on' + type] = null; } } } var btn = document.getElementById("btn"); eventUtil.addHandler(btn, 'click', showMsg); eventUtil.removeHandler(btn, 'click', showMsg); </script> </body> </html>
第三章 事件对象
什么是事件对象?即在触发DOM上的事件时,都会产生的一个对象(event)。
1、DOM中的事件对象
(1)type属性:用于获取事件类型
--浏览器显示-->
(2)target属性:用于获取事件目标
--浏览器显示-->
(3)stopPropagation()方法 用于阻止事件冒泡
(4)preventDefault()方法 阻止事件的默认行为
比如a标签的默认跳转行为,如果我们要阻止它进行跳转,可以这样使用:
2、IE中的事件对象
(1)type属性:用于获取事件类型
(2)srcElement属性 用于获取事件的目标
在非IE的浏览器,可以直接用event,就是事件传入传出的过程,但是在IE,特别是IE8之前的浏览器,在引入对象的时候,是用window.event引入的。所以建议这样写:
(3) cancelBubble属性 用于阻止事件冒泡
设置为true表示阻止冒泡,设置为false表示不阻止冒泡
(4) returnValue属性 用于阻止事件的默认行为
设置为false表示阻止是按的默认行为
3、练习:完成点击登录按钮显示登陆层
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> * { margin: 0; padding: 0; } .head { font-size: 12px; padding: 6px 0 0 10px; } #login_box { width: 300px; height: 150px; background: #eee; border: 1px solid #ccc; position: absolute; left: 50%; top: 50%; margin-left: -150px; margin-top: -75px; display: none; } #login_box p { height: 20px; border-bottom: 1px solid #ccc; font-size: 12px; padding: 6px 0 0 5px; font-weight: bold; } #close { width: 14px; height: 14px; background: url(close.png) no-repeat; position: absolute; right: 4px; top: 6px; } </style> <script type="text/javascript"> window.onload = function() { var login_btn = document.getElementById('login'), login_box = document.getElementById('login_box'), close = document.getElementById('close'); // 封装添加事件监听程序 function addEvent(ele, type, hander) { if (ele.addEventListener) { ele.addEventListener(type, hander, false); } else if (ele.attachEvent) { ele.attachEvent('on' + type, hander); } else { ele['on' + type] = hander; } } // 显示登录层函数 function showLogin() { login_box.style.display = "block"; } // 隐藏登录层函数 function hideLogin() { login_box.style.display = "none"; } addEvent(login_btn, 'click', showLogin); addEvent(close, 'click', hideLogin); } </script> </head> <body> <div class="head">亲,您好! <input type="button" value="登 录" id="login"> </div> <div id="login_box"> <p>用户登录</p><span id="close"></span> </div> </body> </html>
第四章 事件类型
1、鼠标事件
onclick:鼠标点击事件,多用在某个对象控制的范围内的鼠标点击
ondblclick:鼠标双击事件
onmousedown:鼠标上的按钮被按下
onmouseup:鼠标按下后,松开时激发的事件
onmouseover:当鼠标移动到某对象范围的上方时触发的事件
onmousemove(冒泡):鼠标移动时触发的事件,可持续触发
onmouseout(冒泡):当鼠标离开某对象范围时触发的事件
2、键盘事件
onkeypress:当用户按下键盘上的字符键的时候触发,而且按住不放的话,会重复触发此事件
onkeydown:当用户按下键盘上的任意键的时候触发,而且按住不放的话,会重复触发此事件
onkeyup:当用户释放键盘上的键时触发
keycode:按下的键的代码(等于Unicode值)
shiftkey,ctrlkey,altkey,metakey(DOM):是否按下了Shift,Ctrl,Alt,Meta键 // event.shiftKey=true|false|1|0 true按下 false 释放
button:0-未按下键;1-按左键;2-按右键;3-同时按下左右;4-按下中键;5-按下左和中;6-按下右和中;7-同时按下左中右
3、表单事件
onblur:当前元素失去焦点时触发的事件 [鼠标与键盘的触发均可]
onchange:当前元素失去焦点并且元素的内容发生改变而触发的事件 [鼠标与键盘的触发均可]
onfocus:当某个元素获得焦点时触发的事件
onreset:当表单中RESET的属性被激发时触发的事件
onsubmit:一个表单被递交时触发的事件
4、页面事件
onload:页面内容完成传送到浏览器时触发的事件,包括外部文件引入完成
onunload:当前页面将被改变时触发的事件
onbeforeunload:当前页面的内容将要被改变时触发的事件
onabort:图片在下载时被用户中断
onerror:捕抓当前页面因为某种原因而出现的错误,如脚本错误与外部数据引用的错误
onresize:当浏览器的窗口大小被改变时触发的事件
onscroll:浏览器的滚动条位置发生变化时触发的事件
5、clientX和clientY
鼠标事件都是在浏览器窗口中的特定位置上发生的。这个位置信息保存在事件的clientX和clientY属性中。所有浏览器都支持这两个属性,他们的值表示事件发生时鼠标指针在可视窗口中的水平和垂直坐标。不包括页面滚动的距离。
* JS 获取浏览器窗口大小相关属性,详见博文随笔。