一、理解事件
1、什么是事件
事件是Web浏览器通知应用程序(比如我们的js)发生了某个事情!
我们可以为这些特定的事情,事先安排好处理方案,这样就能够实现互动!
2、事件目标
你可以简单的理解为事件发生在的最具体的那个目标元素即为事件目标,有时也可能是document或者window!
3、事件类型
事件类型是一个用来说明发生了什么类型事件的字符串,你可以简单的理解为事件的名字!
常见的事件类型有哪些?
1)常用的与浏览器有关的事件类型:
①resize
当窗口或者框架的大小变化时在window对象上或框架上触发
②scroll
当用户滑动(滚动)带有滚动条的元素中的内容时在该元素上触发
滑动整个页面会在document以及window上触发
③error
当发生JavaScript错误时在window上面触发,当无法加载图像时在<img>元素上面触发,当无法加载嵌入内容时在<object>
元素上面触发,或者当有一或多个框架无法加载时在框架集上面触发
2)常用的与文档加载有关的事件类型:
①load
当页面完全加载后(包括所有图像、JavaScript文件、CSS文件等外部资源)在window对象上触发。
当所有的框架都加载完毕的时候会在框架集上面触发,
当图像加载完毕时会在img元素上面触发
使用object元素嵌入的内容加载完毕时会在object元素上触发
说白了:等内容(包括外部资源)加载完毕之后,在对应的元素对象上面触发
②beforeunload
会在window对象上面触发这个事件,让开发人员有可能在页面卸载前阻止这一操作。
这个事件会在浏览器卸载页面之前触发,可以通过它来取消卸载并继续使用原有页面。
将事件对象的returnValue 属性设置为要显示给用户的内容,并且将其返回才能够实现兼容各种浏览器;
3)常用的与表单有关的事件类型:
①blur
在元素失去焦点时在对应的元素上触发,该事件不会冒泡
②focus
在元素获得焦点时触发在对应的元素上,这个事件不会冒泡
③select
当用户选择文本框(<input>或<texterea>)中的一或多个字符时,在对应的元素上触发
④change
对于<input>和<textarea>元素,在它们失去焦点且value 值改变时在对应元素上触发
对于<select>元素,在其选项改变时在select元素上触发
⑤submit
浏览器会在将请求发送给服务器之前在对应的表单上触发submit事件
4)常用的与键盘有关的事件类型:
①keydown
当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件
事件对象中keyCode属性表示 键码
②keyup
当用户释放键盘上的键时触发
③keypress
当用户按下键盘上的字符键时触发,而且如果按住不放的话,会重复触发此事件
事件对象中charCode属性表示 ASCII码
5)常用的与鼠标有关的事件类型:
我们的与鼠标有关的事件类型,最能体现”事件传播“,由于我们后面需要专门的一节课来学习”事件传播“,
所以说,我们这节课在讲鼠标有关的事件类型的时候,我们先避开”事件传播“这个概念!
①click
在用户点击鼠标或者按下回车键时或者移动用户触摸时触发
②dblclick
在用户双击鼠标时触发
③mousedown
按下鼠标按键时,会发生 mousedown 事件
与 click 事件不同,mousedown 事件仅需要按键被按下,而不需要松开即可发生
④mouseup
在用户释放鼠标按钮时触发
⑤mouseenter
在鼠标光标从元素外部移动到元素范围之内时触发,这个事件不冒泡
⑥mouseleave
在位于元素上的鼠标光标移动到元素范围之外时触发,这个事件不冒泡
⑦mouseover
在鼠标指针移入一个元素边界之内,或者移入任何后代元素时触发
⑧mouseout
鼠标从当前元素移动到其他元素时触发(哪怕移动到的元素是当前元素的后代元素或者离开任何后代元素)
⑨mousemove
当鼠标指针在元素内部移动时重复地触发
4、事件处理程序(事件监听程序)
其实事件一直在发生,有人会问为什么我没感觉到?因为你没有为事件作出响应!怎么作出响应?
为"元素"绑定对应的事件处理程序(一个函数,当具体的元素上发生对应的事件时的就会触发这个函数的执行)
绑定的这个函数我们可以称为事件处理程序!
我们通过DOM对象的addEventListener方法来为具体的目标绑定对应的事件处理函数
Internet Explorer 8 及更早IE版本不支持 addEventListener() ,Opera 7.0 以及更早版本也不支持。
当然我们目前只是用这个原生的方法演示一下即可,后面我们jQuery会提供一个兼容各种浏览器的方法!
addEventListener()参数说明:
eventType:字符串,表示监听的事件类型
function:事件在预定目标发生时,执行的函数
useCapture:(可选)布尔值,是否注册到捕获阶段,默认false
5、事件传播(事件流)
事件传播指的是事件在页面中传播的顺序(事件流)
既然可能有很多个元素一齐发生了同样的事件,那么总该有个先后顺序吧?
事件传播描述的是从页面中接收事件的顺序。有意思的是,IE 和Netscape开发团队在当时居然提出了差不多是完全相反的事件流的概念。
当时IE开发团队提出的的事件传播顺序为事件冒泡,而Netscape公司提出的事件传播顺序为事件捕获。
IE开发团队提出的的事件传播顺序:事件冒泡
即事件开始是由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)
Netscape公司提出的事件传播顺序:事件捕获
事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。
“捕获”的用意在于在于一层一级的往里找,在找的过程中把事件依次传播给它们,直到找到具体的事件目标。
老版本的ie浏览器不支持(ie9以下的ie版本)
W3C规定的事件传播方式(我们可以称为DOM事件传播,或DOM事件流)
事件传播有三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段
事件捕获阶段:如果有绑定在事件捕获阶段的处理函数则按照捕获的顺序执行
处于目标阶段:如果有直接绑定在事件目标上的处理函数则按照绑定的先后顺序来执行(不管addEventListener的第三个参数是true还是false)
事件冒泡阶段:如果有绑定在事件冒泡阶段的处理函数则按照冒泡的顺序执行
1 <!DOCTYPE html> 2 <html id="html"> 3 <head> 4 <meta charset="utf-8" /> 5 <title>demo</title> 6 <script type="text/javascript" src="js/jquery-1.11.2.min.js"></script> 7 <style type="text/css"> 8 #div1 { 9 300px; 10 height:300px; 11 background:#eee; 12 border:1px solid #ccc; 13 } 14 </style> 15 <script type="text/javascript"> 16 $(function(){ 17 /* 18 //因为div1是事件目标,所绑定在他们身上的多个同样的事件处理程序,执行顺序是根据绑定先后而言! 19 var div1=document.getElementById('div1'); 20 div1.addEventListener('click',function(){ 21 console.log('1div_true'); 22 },true); 23 div1.addEventListener('click',function(){ 24 console.log('0div_false'); 25 }); 26 */ 27 28 var html=document.getElementById('html'); 29 var body=document.getElementById('body'); 30 var div1=document.getElementById('div1'); 31 window.addEventListener('click',function(){ 32 console.log('window_false'); 33 });//冒泡阶段,接收到click事件的时候执行 34 window.addEventListener('click',function(){ 35 console.log('window_true'); 36 },true); 37 document.addEventListener('click',function(){ 38 console.log('document_false'); 39 }); 40 document.addEventListener('click',function(){ 41 console.log('document_true'); 42 },true); 43 html.addEventListener('click',function(){ 44 console.log('html_false'); 45 }); 46 html.addEventListener('click',function(){ 47 console.log('html_true'); 48 },true); 49 body.addEventListener('click',function(){ 50 console.log('body_false'); 51 }); 52 body.addEventListener('click',function(){ 53 console.log('body_true'); 54 },true); 55 56 div1.addEventListener('click',function(){ 57 console.log('div1_true'); 58 },true); 59 div1.addEventListener('click',function(){ 60 console.log('div1_false'); 61 }); 62 }); 63 </script> 64 </head> 65 <body id="body"> 66 <div id="div1"></div> 67 </body> 68 </html>
PS:并不是所有的事件类型都支持事件冒泡!低版本的ie浏览器也没有捕获这个阶段!
一堆烂摊子,坐等我们后面jQuery来解决这个问题!
6、事件对象
当我们事件处理函数执行的时候,我们的事件处理函数会接受到参数->事件对象,我们使用一个变量接受即可
当然低版本的ie浏览器是接受不到的,并且事件对象内的一些属性名称和W3C规定的标准的属性名称也可能不一致!
事件对象内部,包含了与该事件类型以及目标有关的数据,不同的事件类型,包含的属性以及方法可能也不太一样!
bubbles Boolean 表明事件是否冒泡
preventDefault() Function 取消事件的默认行为。如果cancelable是true,则可以使用这个方法
stopImmediatePropagation() Function 忽略当前元素尚未执行的的事件处理函数;终止事件在元素树种的传播
stopPropagation() Function 执行完当前元素的所有事件处理函数后;终止事件在元素树中的继续传播
target Element 事件的目标
currentTarget Element 其事件处理程序当前正在处理事件的那个元素
当前执行的事件处理函数所绑定在的那个元素对象!
注意:在事件处理程序内部,this始终等于currentTarget的值,而target则只包含事件的实际目标
type String 被触发的事件的类型
7、事件委托
正常思路:
直接将事件处理函数绑定到事件目标上!
事件委托:
将事件处理函数委托给他们的祖先对象!
事件冒泡!
退一步,海阔天空!
注意点:
事件类型必须要支持事件冒泡!
大家最好将委托对象选择为 是举例事件目标近一点的!