关于事件
什么是事件?
事件是可以被Javascript侦测到的行为,通俗的讲就是当用户与Web页面进行某些交互时,解释器就会创建响应的event对象以描述事件信息。
常见的事件有:
- 用户点击页面上的某项内容
- 鼠标经过特定的元素
- 用户按下键盘的某个按键
- 用户滚动窗口或改变窗口大小
- 页面元素加载完成或加载失败
事件句柄
通俗讲就是事件发生时调用的那个函数。
事件定义
定义事件的步骤:
- 获取事件对象
- 给事件对象绑定一个事件类型
- 编写事件句柄
html中写js代码,强耦合,不利于复用代码。不推荐
解决了强耦合性,但只能给一个事件对象绑定一个事件类型。 同样的事件类型,绑定两次,以 后一次 为准。
同样的事件类型,绑定多次,每个都会执行,可以设置时捕获还是冒泡。
第三个参数默认false(如果设置为true是事件捕获,false是事件冒泡)
DOM事件流
DOM0级与DOM2级区别:
- DOM2支持同一dom元素注册多个同种事件
- DOM2新增了捕获和冒泡的概念
添加事件
移除事件
事件解绑成功的主要原因就是:保持addEventListener和removeaddEventListener里面的参数是一致的。
IE事件流(IE事件处理程序)
添加事件
IE浏览器不支持事件捕获,默认就是事件冒泡,所有没有第三个参数。
移除事件
在ie中attachEvent是特殊的,这样触发的事件中,this总是指向window的
跨浏览器事件处理程序(解决兼容性)
事件周期
直系亲属树结构
一般的情况都是采用事件冒泡,很少使用事件捕获
事件委托 (原理就是事件冒泡)
使用事件委托,只添加一次就能实现多次的效果。
ul 是 父
li 是 子
因为li没有绑定事件,所以会往上冒泡,实现这样的效果。
上述的代码可以实现最终的效果。点击不同的li标签,执行不同的函数。
事件的冒泡处理机制
event对象常用属性和方法
event对象
事件处理函数的参数。
event对象常用属性和方法
type:事件类型
target:点击谁,谁就是target ,事件源
currentTarget:事件绑定在谁身上,谁就是currentTarget
preventDefault():阻止默认行为。
stopPropagation():阻止事件冒泡或捕获。
clientX/ clientY:从浏览器(左边)/(顶部底边)到鼠标点击的位置,之间的距离
pageX/pageY:从浏览器(左边)/(顶部底边)到鼠标点击的位置,之间的距离 + 滚动轴滚动的距离
screenX/screenY:屏幕最(左端)/(顶端)距离鼠标的位置
IE8及以下浏览器中的Event对象属性与方法
Event对象跨浏览器兼容写法
1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Event对象跨浏览器兼容写法</title> 7 </head> 8 9 <body> 10 <div id="parent"> 11 <div id="child">点击我</div> 12 </div> 13 <a href="http://www.baidu.com" id="a">跳转链接</a> 14 <script type="text/javascript"> 15 //Event addEventListener chrome firefox IE9 event.target preventDefault stopPropagation 16 //Event attachEvent IE8系列的 event.srcElement returnValue cancelBubble 17 var EventUtil = { 18 addHandler: function(element, type, handler) { 19 //绑定事件 20 //Chrome Firefox IE9等 addEventListener 21 //IE8及IE8以下的浏览器 attachEvent 22 if(element.addEventListener) { 23 element.addEventListener(type, handler, false); 24 } else if(element.attachEvent) { 25 element.attachEvent("on" + type, handler); 26 } else { 27 element["on" + type] = handler 28 } 29 }, 30 removeHandler: function(element, type, handler) { 31 //移除事件 32 //Chrome Firefox IE9等 33 //IE8及IE8以下的浏览器 34 if(element.removeEventListener) { 35 element.removeEventListener(type, handler, false); 36 } else if(element.detachEvent) { 37 element.detachEvent("on" + type, handler); 38 } else { 39 element["on" + type] = handler 40 } 41 }, 42 getTarget: function(event) { 43 return event.target || event.srcElement; 44 }, 45 preventDefault: function(event) { 46 if(event.preventDefault) { 47 event.preventDefault(); 48 } else { 49 event.returnValue = false; 50 } 51 }, 52 stopPropagation: function(event) { 53 if(event.stopPropagation) { 54 event.stopPropagation() 55 } else { 56 event.cancelBubble = true; 57 } 58 } 59 } 60 61 var parent = document.getElementById("parent"); 62 EventUtil.addHandler(parent, "click", function(event) { 63 alert("parent被触发了") 64 }) 65 66 var child = document.getElementById("child"); 67 EventUtil.addHandler(child, "click", function(event) { 68 //alert(111) 69 alert("child被触发了") 70 var target = EventUtil.getTarget(event); 71 console.log(target); 72 //阻止事件冒泡 73 EventUtil.stopPropagation(event) 74 }) 75 var a = document.getElementById("a"); 76 EventUtil.addHandler(a, "click", function(event) { 77 EventUtil.preventDefault(event); 78 }) 79 </script> 80 </body> 81 82 </html>
常用事件类型
UI事件 1.load
当页面完全加载后在window上触发,也可以应用在image标签上,图片加载完毕后弹框,可用于图片预加载,js动态加载,动态加载css EventUtil.addHandler(window,"load",function(e){ alert("loaded"); }) //img标签加载完毕 var image = document.getElementById("img"); EventUtil.addHandler(image, "load", function(e) { alert("图片加载完毕 "); }) image.src = "1.png"; 图片预加载 var image = new Image();//将图片存在了内存中 缓存在内存空间上 EventUtil.addHandler(image,"load",function(event){ alert("Image loaded!"); }); image.src = "smile.gif"; // js动态加载完毕 var script = document.createElement("script"); EventUtil.addHandler(script, "load", function(event){ alert("js Loaded"); }); script.src = "jquery.js"; document.body.appendChild(script); // css动态加载完毕 var link = document.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; EventUtil.addHandler(link, "load", function(event){ alert("css Loaded"); }); link.href = "example.css"; document.getElementsByTagName("head")[0].appendChild(link); 2.unload事件
用户从一个页面切换到另一个页面 3.resize
窗口大小发生变化时触发,重复执行,损耗性能 EventUtil.addHandler(window, "resize", function(event){ alert("Resized"); }); 4.scroll事件
主要针对新旧浏览器,滚动轮上下滚动触发 5.焦点事件 blur 元素失去焦点的时候触发 focus 元素获取焦点的时候触发,不支持冒泡 focusin 同focus一样 元素获取焦点的时候触发,支持事件浏览器是IE5.5+,Safari5.1+,chrome等 focuout 同blur一样,支持事件浏览器是IE5.5+,Safari5.1+,chrome等
最新的浏览器可能也会生效
6.鼠标事件
click
dblclick 双击事件
mousedown 鼠标按下时候触发的事件
mouseup 鼠标松开
mousedown+mouseup=click事件
mousemove鼠标在对象上移动,重复触发,注意代码性能优化。 mouseout鼠标离开元素时触发(离开目标对象或子元素都触发,范围比较广) mouseover鼠标进入元素时触发。(进入目标对象或子元素都触发,范围比较广) mouseenter鼠标进入目标元素。(只能进入 目标元素 触发,如其还有子元素不能触发。) mouseleave鼠标离开目标对象。(只能离开 目标元素 触发)
event.button
//高级浏览器:
event.button ==0鼠标左键 event.button==1鼠标中键 event.button==2鼠标右键 //IE8派系 // event.button == 0 没有按下按钮 //event.button == 1 按下主鼠标按钮 //event.button == 2 按下次鼠标按钮 //event.button == 3 按下同时按下主、次鼠标按钮 //event.button == 4 按下中间鼠标按钮
7 键盘事件
event.shiftKey表示当我鼠标点下去时同时按下键盘的shift键
1 var div = document.getElementById("myDiv"); EventUtil.addHandler(div, "clcik", function(event) { 2 var keys = new Array(); 3 if(event.shiftKey) { 4 keys.push("shift"); 5 } 6 if(event.ctrlKey) { 7 keys.push("ctrl"); 8 } 9 if(event.altKey) { 10 keys.push("alt"); 11 } 12 if(event.metaKey) { 13 keys.push("meta"); 14 } 15 console.log("keys:" + keys.join(",")) 16 ; });
1.keydown 返回键码,任意键触发 EventUtil.addHandler(myText,"keydown",function(event){ console.log(event.keyCode); }) 2.keyup 释放某键的时候触发,支持keyCode 3.keypress 按下字符键,更适用于使用 charCode(字符码,ASCII码),而不是keyCode。
对于keycode的支持有限制,有的浏览器支持,有的不支持
理解:
① keypress事件中keyCode是不稳定的。
举个例子:
打印结果显示s的键码值是83,
将keyCode放到keypress中;
打印结果显示s的键码是115:
所以说:keypress事件中keyCode是不稳定的。
② 这个兼容性的写法只是适用于keypress这个事件中哦,在keypress事件中如果浏览器支持charcode就返回charcode,如果浏览器不支持就返回keyCode。
4.textInput 输入什么字符就会打印什么 EventUtil.addHandler(myText, "textInput", function(event) { console.log(event.data); }) 5.DOMNodeRemoved document中任意元素被删除就会触发 EventUtil.addHandler(document, "DOMNodeRemoved", function(event) { console.log(111111); })
6. DOMSubtreeModified document结构中发生任何变化都会触发 EventUtil.addHandler(document, "DOMSubtreeModified", function(event) { console.log(111111); }) 同样也可以绑定除document外的其他元素。 7.DOMNodeRemovedFromDocument 从文档中移除之前被触发 8.DOMNodeInserted document中任意元素被添加就会触发 9.DOMNodeInsertedIntoDocument 从文档中添加之前被触发 H5新增事件 10.DOMContentLoaded 在DOM树结构创建好之后就会触发,不理会图像、javascript文件、css文件或其他资源是否已经下载,速度比load事件快 11.readstatechange 支持IE、firfox、opera,提供文档或者元素加载过程,但是与load事件一起使用时候很难预料,情绪化,限制IE.很难预料。不一定按顺序,或每个步骤都执行。 ①document.readState == uninitialized 尚未初始化 ②loading 对象正在加载数据 ③interactive 可以操作对象,单还没有完全加载
④对象已经加载完毕
12.hashchange 一定给window添加,,地址#后面的值变化,
EventUtil.addHandler(window, "hashchange", function(event) {
console.log(event.oldURL + ":"+event.newURL);
})
url地址#后的值发生变化时触发。
8 移动端触摸屏事件
touchstart手指触摸屏幕触发 三个属性: event.touches当前触摸屏幕的触摸点的数组,记录触摸点的信息有可能四个手指一起触摸 event.changedTouches 一个数组,数组中只包含引起事件的触摸点信, 如果四个手指可能移动了2个,这两个移动的触摸点信息。(移动的触摸信息) event.targetTouches一个数组,只包含放在元素上的触摸点信息,如果四个手指有两个在触发元素button外,两个在它上面,在上面的触摸点信息。(在事件对象上的触摸信息) touchmove手指移动划动触发,重复触发 touchend手指离开屏幕事件
小项目
实现:点击某个按钮,div的背景颜色变成相应的颜色。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>小项目</title> 5 <style type="text/css"> 6 *{ 7 margin: 0; 8 padding: 0; 9 list-style: none; 10 } 11 #canvas{ 12 height: 500px; 13 } 14 li{ 15 float: left; 16 width: 100px; 17 height: 30px; 18 border-radius: 10px; 19 background: #333; 20 text-align: center; 21 line-height: 30px; 22 color:#fff; 23 } 24 ul li:nth-child(1){ 25 background:red; 26 } 27 ul li:nth-child(2){ 28 background:black; 29 } 30 ul li:nth-child(3){ 31 background:blue; 32 } 33 ul li:nth-child(4){ 34 background:yellow; 35 } 36 ul li:nth-child(5){ 37 background:green; 38 } 39 </style> 40 </head> 41 <body> 42 <div id="canvas"></div> 43 <ul id="ul"> 44 <li>红色</li> 45 <li>黑色</li> 46 <li>蓝色</li> 47 <li>黄色</li> 48 <li>绿色</li> 49 </ul> 50 <script type="text/javascript"> 51 var ul = document.getElementById('ul'); 52 var canvas = document.getElementById('canvas'); 53 ul.addEventListener('click', function(e){//事件委托 54 var that = e.target;//事件源 55 console.log(e); 56 if(that.innerHTML == "红色"){ 57 canvas.style.background = "red"; 58 }else if(that.innerHTML == "黑色"){ 59 canvas.style.background = "black"; 60 }else if(that.innerHTML == "蓝色"){ 61 canvas.style.background = "blue"; 62 }else if(that.innerHTML == "黄色"){ 63 canvas.style.background = "yellow"; 64 }else{ 65 canvas.style.background = "green"; 66 } 67 }); 68 </script> 69 </body> 70 </html>