4、事件类型
“DOM3级事件”规定了一下几类事件:
1)UI事件(用户界面事件),当用户与页面元素交互时触发
2)焦点事件,当元素获得或失去焦点时触发
3)鼠标事件,当用户通过鼠标在页面上执行操作时触发
4)滚动事件,当使用鼠标滚轮(或类似设备)时触发
5)文本事件,当在文档中输入文本时触发
6)键盘事件,当用户通过键盘在页面执行操作时触发
7)合成事件,当IME(Input Method Editor,输入法编辑器)输入字符时触发
8)变动事件(mutation),当底层DOM结构发生变化时触发
9)变动名称事件,当元素或属性名变动时触发。已废弃
4.1 UI事件
1)DOMActivate:表示元素已经被用户操作(通过鼠标或键盘)激活
2)load:当页面加载后在window上触发,当所有框架都加载完成时在框架集上触发,当图像加载完成时在<img>元素上触发,当嵌入的内容加载完成时在<object>元素上触发
3)unload:当页面完全卸载(页面关闭或刷新)后在window上触发,当所有框架都卸载后在框架集上触发,当嵌入内容卸载完后在<object>元素上触发
4)abort:在用户停止下载过程时,如果嵌入的内容没有加载完,则在<object>元素上触发
5)error:当发生JavaScript错误时在window上触发,当无法加载图像时在<img>元素上触发,当无法加载嵌入内容时在<object>元素上触发,当有一个或多个框架无法加载时在框架集上触发
6)select:当用户选择文本框(<input>或<textarea>)中的一个或多个字符时触发
7)resize:当窗口或框架的大小或变化是在window或框架上触发
8)scroll:当用户滚动带滚动条的元素是,在该元素上触发
var myimg = document.getElementById("myimg"); var mydiv = document.getElementById("mydiv"); EventUtil.addHandler(window,"load",function(event){ var event = EventUtil.getEvent(event); console.log("event window Loaded, "+event.type); var image = new Image(); EventUtil.addHandler(image,"load",function(event){ //预加载图片,Image 对象 console.log("Image loaded"); mydiv.appendChild(image); // 图片加载完成后,插入DOM中 }); image.src = "img/IMAGE.png"; // 设置路径后就开始加载图片了 var script = document.createElement("script"); EventUtil.addHandler(script,"load",function () { //IE9+、Firefox、Opera、Chrome、Safari3+,支持script元素的load事件 console.log("script is loaded"); }); script.src = "js/test.js"; //对于script,只有在指定了src属性,并添加到文档后,才会开始加载script document.body.appendChild(script); var link = document.createElement("link"); // IE all、 FireFox、Chrome、Edge、Opera、Safari?,支持link元素的load事件 link.type = "text/css"; link.rel = "stylesheet"; EventUtil.addHandler(link,"load",function (event) { console.log("link css loaded"); }); link.href = "css/list.css"; document.getElementsByTagName("head")[0].appendChild(link); }); function imgLoad(event){ console.log("img loaded!"); var event = EventUtil.getEvent(event); console.log(EventUtil.getTarget(event).src); } function imgLoadError(event){ console.log("failed to load img!"); var event = EventUtil.getEvent(event); console.log(EventUtil.getTarget(event).src); } //<img src="img/date.png" alt="user" id="myimg" onload="target = event.target ? event.target : event.srcElement; console.log('img loaded! ' + target.src)" onerror="console.log('failed to load img')"/> EventUtil.addHandler(myimg, "load",imgLoad);// 在IE 上无法检测到图像的加载事件(估计是程序执行到这里,图片已经加载完了) myimg.onload = imgLoad; // 在IE 上无法检测到图像的加载事件(估计是程序执行到这里,图片已经加载完了) myimg.onerror = imgLoadError; EventUtil.addHandler(window,"unload",function(event){ // unload事件多是用来清除引用,避免内存泄漏的 console.log("unloaded!");// 页面已关闭,提示框看不到;刷新页面可以 }); EventUtil.addHandler(window,"beforeunload",function(event){ // 采用addEventListener()或attachEvent()方式添加beforeunload事件的处理程序,无效 return "xxx"; }); /* window.onbeforeunload = function(event){ //DOM0级添加beforeunload事件的处理程序,有效 return '您可能有数据没有保存'; // 页面刷新、关闭前触发确定离开提示。浏览器支持:Chrome、Firefox、Edge、IE }; */ EventUtil.addHandler(window,"resize",function(event){ // 页面调整高度或宽度触发,当拖放窗口大小时,会连续触发这个事件 console.log('resized!'); }); EventUtil.addHandler(window,"scroll",function(event){ // 页面滚动时,会连续重复触发scroll事件 if(document.compatMode == "CSS1Compat"){ console.log(document.documentElement.scrollTop); } else { console.log(document.body.scrollTop); } });
window 的 load、unload事件的event事件对象,在兼容DOM事件的浏览器里target是document,而不兼容DOM事件的浏览器(IE)中的srcElement没有值。另外, window 的 load、unload的事件处理程序都可以在<body>中指定 onload、onuload特性的方式添加
4.2 焦点事件
1)focus:元素获得焦点时触发,这个事件不会冒泡,所有浏览器都支持
2)blur:元素失去焦点时触发,这个事件不会冒泡,所有浏览器都支持
3)focusin:元素获得焦点时触发,与 focus 事件等价,但会冒泡。浏览器支持:IE5.5+,Safari5.1+、Opera11.5+、Chrome、Firefox
4)focusout:元素失去焦点时触发,与 blur 事件等价,但会冒泡。浏览器支持:IE5.5+,Safari5.1+、Opera11.5+、Chrome、Firefox
5)DOMFocusIn:元素获得焦点时触发,与 focus 事件等价,但会冒泡。DOM3级事件中被废弃,浏览器支持:Opera
6)DOMFocusOut:元素失去焦点时触发,与 blur 事件等价,但会冒泡。DOM3级事件中被废弃,浏览器支持:Opera
结合document.hasFocus() -->判断文档是否获取焦点,以及document.activeElement -->文档中获得焦点的元素,来确定用户的操作行为。
4.3 鼠标与滚轮事件
1)click:单击主鼠标按钮(鼠标左键)或按下回车键时触发
2)dblclick:双击主鼠标键(鼠标左键)时触发
3)mousedown:按下了任意鼠标按钮时触发
4)mouseup:释放鼠标按钮时触发
5)mouseenter:鼠标光标从元素外部首次移动到元素范围内时触发,这个事件不冒泡,而且光标移动到后代元素上不会触发。
6)mouseleave:在位于元素上方的鼠标光标移动到元素范围之外时触发,这个事件不冒泡,而且光标移动到后代元素上不会触发。
7)mousemove:当鼠标指针在元素内部移动是重复触发
8)mouseout:在鼠标指针位于一个元素上方,然后将其移动到另一个元素时触发。另一个元素可能位于前一个元素外部,也可能是这个元素的子元素。
9)mouseover:在鼠标指针位于一个元素外部,然后将其首次移动到另一个元素范围内时触发
10)mouseWheel: 滚轮事件,滚动页面时触发
页面所有的元素都支持鼠标事件,除了mouseenter 和 mouseleave,其他所有事件都会冒泡,也可以被取消。
在同一个元素上相机触发 mousedown 和mousedown 事件,才会触发 click 事件;只有触发两次 click 事件,才会触发 dblclick 事件。这个过程中有一个事件被取消,后面的事件就不会发生。
在 IE9+、Chrome、Firefox、Safari、Opera中,鼠标键按下、弹起发生的事件顺序:mousedown ----> mouseup ----> click ----> mousedown ----> mouseup ---->click ----> dblclick
在 IE8- 中,在双击中,会跳过第二个 mousedown 和 click,鼠标键按下、弹起发生的事件顺序:mousedown ----> mouseup ----> click ----> mouseup ----> dblclick
1) 鼠标事件发生时 ,事件对象保存了一些事件发生的位置信息
客户区坐标:事件发生时鼠标指针在视口中的坐标,event.clientX,event.clientY
页面坐标:事件发生时鼠标指针在页面中的坐标,event.pageX,event.pageY。IE8- 中事件对象不支持页面坐标,但可以通过客户区坐标和scrollLeft 和 scrollTop 计算出来。
屏幕坐标:事件在整个屏幕中的坐标,event.screenX,event.screenY
var clientCoordinates = null; var pageCoordinates = null; var screenCoordinates = null; EventUtil.addHandler(btn,"click",function (event) { event = EventUtil.getEvent(event); clientCoordinates = {x:event.clientX,y:event.clientY}; pageCoordinates = {x:event.pageX,y:event.pageY}; if(pageCoordinates.x === undefined){ pageCoordinates.x = event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft); } if(pageCoordinates.y === undefined){ pageCoordinates.y = event.clientY + (document.body.scrollTop || document.documentElement.scrollTop); } screenCoordinates = {x:event.screenX,y:event.screenY}; console.log(clientCoordinates); console.log(pageCoordinates); console.log(screenCoordinates); });
2)修改键,shift、ctrl、alt、meta(Windows中的windows键,apple中的cmd键),这些键和鼠标事件可以配合完成一些事情。
鼠标事件中有四个布尔值属性,shiftKey、ctrlKey、altKey、metaKey,这些键按下,其值为true,反之为false。IE、Firefox不支持metaKey。
EventUtil.addHandler(btn,"click",function (event) { event = EventUtil.getEvent(event); var keys = new Array(); if(event.shiftKey){ keys.push("shift"); } if(event.ctrlKey){ keys.push("ctrl"); } if(event.altKey){ keys.push("alt"); } if(event.metaKey){ keys.push("metaKey"); } console.log("keys:" + keys.join(",")); });
3)相关元素,event.relatedTarget,mouseover 和 mouseout 事件都会涉及把鼠标从一个元素的边界之内移动到另一个元素的边界之内。
对于 mouseover 事件:事件的主目标是获得光标的元素,相关元素是失去光标的元素;
对于 mouseout 事件:事件的主目标是失去光标的元素,相关元素是获得光标的元素。
IE8- 不支持relatedTarget,但有相关信息:mouseover 事件,事件对象的 fromElement 属性; mouseou 事件,事件对象的 toElement 属性。IE9+都支持。
4)鼠标按钮,对于mousedown 和 mouseup 事件有 event.button,表示鼠标按下了哪个键:鼠标主键(左键),鼠标次键(右键),鼠标中间滚轮
DOM规定,0---->鼠标主键,1---->鼠标中间滚轮,2---->鼠标次键
IE8- 事件对象也有 button 属性,但更详细,用三位二进制数表示,从低位到高位分别是:主键、次键、滚轮,按下键就是1,所以换成十进制就是:
0----> 没有按下键,1----> 按下主键,2----> 按下次键,3---->同时按下了主、次键,4---->按下滚轮,5---->同时按下了主键和滚轮,6---->同时按下了次键和滚轮,7---->同时按下了三个键。
mouseup事件中 button 属性表示的是释放哪个键。
对于click 事件,button 属性的值都是0。
4)鼠标滚轮事件, mousewheel,DOMMouseScroll(Firefox)
滚轮事件可以在任何元素上触发,最终会冒泡到 document(IE8-)或 window (IE9+、Opera、Chrome、Safari,Firefox)对象上。
mousewheel 事件包含鼠标事件的所有标准信息,另外还有一个 wheelDelta(detail,DOMMouseScroll事件)属性。
鼠标向前滚动时 wheelDelta 是120,向后滚动 wheelDelta 是 -120
在Firefox中,鼠标向前滚动时 detail 是 -3,向后滚动 detail 是 3
function handleMOuseWheel(event) { event = EventUtil.getEvent(event); console.log(event.wheelDelta || -event.detail * 40); } EventUtil.addHandler(document,"mousewheel",handleMOuseWheel); EventUtil.addHandler(document,"DOMMouseScroll",handleMOuseWheel);
5)触摸设备
iOS 和 Android 设备没有鼠标,一般只能触发 click 事件
a:不支持双击 dblclick 事件,双击浏览器窗口可能会放大画面
b:轻击可单击元素触发 mousemove 事件,如果此操作会导致内容变化,将不再有其他事件发生;如果屏幕灭有一次变化,那么会依次发生mousedown、mouseup、click 事件。轻击不可单击的元素不会触发任何事件
可单击元素是指 那些单击可产生默认操作的元素(如链接)或者指定了onclick 事件处理程序的元素。
c:mousemove 事件也会触发mouseover 和 mouseout 事件
d:两个手指放在屏幕上且页面随手指移动而滚动时会触发 mousewheel 和 scroll 事件
4.4 键盘与与文本事件
4.4.1 键盘事件
1)keydown 事件:在键盘上按下任意键时触发,如果按住不放的话,会重复触发
2)keypress 事件:在键盘上按下字符键时触发,如果按住不放的话,会重复触发
3)keyup 事件:释放按键时触发
只要获取到焦点,所有元素都可以发生 keydown、keypress、keyup 这三个事件,但通常是在文本输入时用到。如果按下了字符键,先是触发 keydown 事件,然后是 keypress 事件,最后是 keyup 事件。
键盘事件 也支持修改键,事件对象中有四个布尔值属性,shiftKey、ctrlKey、altKey、metaKey,这些键按下,其值为true,反之为false。IE、Firefox不支持metaKey。
4.4.2 键码 keyCode(键盘上按键的编码) 和 字符编码 charCode(ASCII编码),都是只读属性。
在 keydown 和 keyup 事件发生时,event对象会包含一个 keyCode 属性。对于字母字符和大键盘上的数字键, keyCode 的值与 ASCII 码中对应大写字母或数字的编码相同。同时event对象也有 charCode 属性,但值都为 0(IE8- 为 undefined)
在 keypress 事件发生时,event对象也会包含 keyCode 和 charCode 属性,且 keyCode 和 charCode 相同 ,都是对应字符的 ASCII 编码值(IE8- 和 早期Opera 中 charCode 为 undefined)。
4.4.3 textInput 事件,DOM3 新添加的事件,在可编辑区域中输入字符时触发,类似 keypress 事件。事件对象有一个 data 属性,值是按下的键的字符。Chrome、Safari、Opera(高版本)、Edge支持,Firefox、IE不支持。
4.5 复合事件
是DOM3 新添加的一类事件,用于处理 IME(Input Method Editor,输入法编辑器)的输入序列。IME 可以让用户在输入物理键盘找不到的字符,比如中文输入。
1)compositionstart :在IME的文本复合系统打开时触发,表示要开始输入了
2)compositionupdate:在向输入字段中插入新字符时触发
3)compositionend:在IME 的文本年复合系统关闭时触发,表示返回正常键盘输入状态
这三个事件的事件对象中包含 data 属性,值是在各个阶段时的文本。
浏览器支持:Chrome、Edge
4.6 变动事件
DOM2级变动事件能在DOM中的某一部分发生变化时给出提示,变动事件是给XML 或 HTML DOM设计的
1)DOMSubtreeModified:在DOM结构中发生任何变化时触发,这个事件在其他变动事件触发后都会触发
2)DOMNodeInserted:在一个节点作为子节点被插入到另一个节点中触发
3)DOMNodeRemoved:在节点从其父节点中移除是触发
4)DOMNodeRemovedIntoDocument:在一个节点被直接插入文档或通过子树间接插入文档后触发,这个事件在DOMNodeInserted之后触发
5)DOMAttrModified:在特性被修改之后触发
6)DOMCharacterDataModified:在文本节点的值发生变化时触发
。。。。。。
4.7 HTML5 事件