1. 事件對象
1. 事件對象
Event 對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。
- 什么時候會產生Event 對象呢?
- 例如: 當用戶單擊某個元素的時候,我們給這個元素注冊的事件就會觸發,該事件的本質就是一個函數,而該函數的形參接收一個event對象.
- 事件通常與函數結合使用,函數不會在事件發生前被執行!
2. 事件流
2.1 事件流發展史
- 事件發展史,這位大神已經寫好了,想去偷瞄兩眼的請點擊這里
2.2 冒泡
- 什么是事件冒泡,
- 官方的定義就是從最特定的事件目標到最不特定的事件目標
意思就是說,假如用戶單擊了一個元素,該元素擁有一個click事件,那么同樣的事件也將會被它的祖先觸發,這個事件從該元素開始一直冒泡到DOM樹的最上層,這一過程稱為事件冒泡
2.3 捕獲
- 什么是事件捕獲
事件捕獲和事件是相反的,也就是說,當用戶觸發了一個事件的時候,這個事件是從DOM樹的最上層開始觸發一直到捕獲到事件源.
2.4 事件流
- 它的由來
由於微軟和網景亂搞,后來必須要為事件傳播機制,制定一個標准,因為事件捕獲是網景公司開發出來的,而事件冒泡是由微軟公司開發出來的,它們都想要自己的技術成為標准,所以導致這兩個公司老是干架,制定標准的人為了不讓它們干架,所以研發了事件流.
2.5 事件流的寫法以及實現方式
- 標准實現方式使用關鍵詞
addEventListener
,假如你想要給某一個元素添加事件,現在就可以這樣寫element.addEventListener(eventType, fn, false)
dom對象.addEventListener(事件類型, 回調函數, 事件機制)
這里的事件類型表示你要使用哪種事件類型比如click
, 回調函數里面寫着觸發此事件你要做什么事情, 事件機制分為冒泡和捕獲,如果為false
表示事件冒泡,為true
表示事件捕獲
- 既然有標准的實現方式,那么肯定也存在着不和諧的寫法,沒辦法誰讓人家牛逼呢,俗話說的好啊
兩虎之爭必有一傷
,可傷了我們程序員了.這種不和諧的寫法是
dom對象.attachEvent(eventType, fn)
第一個參數表示事件類型,第二個是回調.這種寫法兼容IE, IE沒有實現事件捕獲,因為在當時他比較厲害,以為沒必要…………只是,,,,省略一千字, 現在微軟的瀏覽器已經做得很好了… 只是調侃一下無其他意圖..
- 以上的兩種寫法一種是兼容W3C標准的一種是老版IE的寫法,怎么寫兼容性寫法呢?下面是注冊事件和刪除事件的
Code
1.// 注冊時間
2.if(dom.addEventListener) {
3. dom.addEventListener(eventType, fn);
4.} else {
5. if(dom.attachEvent) {
6. dom.attachEvent('on' + eventType, fn);
7. }
8.}
9.
10.// 下面是刪除事件
11.if(dom.removeEventListener) {
12. dom.removeEventListener(eventType, fn, false);
13.} else {
14. if(dom.detachEvent) {
15. dom.detachEvent("on" + eventType, fn)
16. }
17.}
- 冒泡和捕獲的一個小demo
1.<!DOCTYPE html>
2.<html>
3.<head>
4. <meta charset="utf-8">
5. <title>bubble event</title>
6. <style type="text/css">
7. body{margin:0;}
8. #one{
9. width:500px;
10. height:500px;
11. background:rgb(255,0,0);
12. border: 1px solid transparent;
13. }
14. #two{
15. width:400px;
16. height:400px;
17. margin: 0 auto;
18. margin-top: 50px;
19. background:rgb(255,50,50);
20. border: 1px solid transparent;
21. }
22. #three{
23. width:300px;
24. height:300px;
25. margin: 0 auto;
26. margin-top: 50px;
27. background:rgb(255,100,100);
28. border: 1px solid transparent;
29. }
30. #four{
31. width:200px;
32. height:200px;
33. margin: 0 auto;
34. margin-top: 50px;
35. background:rgb(255,150,150);
36. }
37. </style>
38.</head>
39.<body>
40. <div id='one'>
41. <div id='two'>
42. <div id='three'>
43. <div id='four'>
44. </div>
45. </div>
46. </div>
47. </div>
48.
49. <script>
50. var one = document.getElementById('one');
51. var two = document.getElementById('two');
52. var three = document.getElementById('three');
53. var four = document.getElementById('four');
54.
55. var useCapture = false; //false為冒泡獲取【目標元素先觸發】 true為捕獲獲取【父級元素先觸發】
56. one.addEventListener('click', function(event) {
57. event || (event = window.event);
58. console.log(event);
59. console.log('one');
60. }, useCapture);
61. two.addEventListener('click', function() {
62. console.log('two');
63. }, useCapture);
64. three.addEventListener('click', function() {
65. console.log('three');
66. }, useCapture);
67. four.addEventListener('click', function() {
68. console.log('four');
69. }, useCapture);
70.
71. /*
72. false
73. 冒泡
74. 點擊four div
75. 輸出結果:four three two one
76.
77. true
78. 捕獲
79. 點擊four div
80. 輸出結果: one two three four
81. */
82. </script>
83.</body>
84.</html>
注意: 不管是微軟的寫法還是標准的寫法,都支持給一個事件綁定多個函數.並且支持動態的添加和刪除事件
3. 關於event對象
- 在觸發的事件的函數里面我們會接收到一個event對象,通過該對象我們需要的一些參數,比如說我們需要知道此事件作用到誰身上了,就可以通過event的屬性
target
來獲取到(IE暫且不談),或者想阻止瀏覽器的默認行為可以通過方法preventDefault()
來進行阻止.以下是event對象的一些屬性和方法
屬性 | 描述 |
---|---|
altKey | 返回當事件被觸發時,”ALT” 是否被按下。 |
button | 返回當事件被觸發時,哪個鼠標按鈕被點擊。 |
clientX | 返回當事件被觸發時,鼠標指針的水平坐標。 |
clientY | 返回當事件被觸發時,鼠標指針的垂直坐標。 |
ctrlKey | 返回當事件被觸發時,”CTRL” 鍵是否被按下。 |
metaKey | 返回當事件被觸發時,”meta” 鍵是否被按下。 |
relatedTarget | 返回與事件的目標節點相關的節點。 |
screenX | 返回當某個事件被觸發時,鼠標指針的水平坐標。 |
screenY | 返回當某個事件被觸發時,鼠標指針的垂直坐標。 |
shiftKey | 返回當事件被觸發時,”SHIFT” 鍵是否被按下。 |
IE
屬性(除了上面的鼠標/事件屬性,IE 瀏覽器還支持下面的屬性)
屬性 | 描述 |
---|---|
cancelBubble |
如果事件句柄想阻止事件傳播到包容對象,必須把該屬性設為 true。 |
fromElement | 對於 mouseover 和 mouseout 事件,fromElement 引用移出鼠標的元素。 |
keyCode | 對於 keypress 事件,該屬性聲明了被敲擊的鍵生成的 Unicode 字符碼。對於 keydown 和 keyup |
offsetX,offsetY | 發生事件的地點在事件源元素的坐標系統中的 x 坐標和 y 坐標。 |
returnValue |
如果設置了該屬性,它的值比事件句柄的返回值優先級高。把這個屬性設置為 |
srcElement |
對於生成事件的 Window 對象、Document 對象或 Element 對象的引用。 |
toElement | 對於 mouseover 和 mouseout 事件,該屬性引用移入鼠標的元素。 |
x,y | 事件發生的位置的 x 坐標和 y 坐標,它們相對於用CSS動態定位的最內層包容元素。 |
- 標准 Event 屬性 下面列出了 2 級 DOM 事件標准定義的屬性。
屬性和方法 | 描述 |
---|---|
bubbles | 返回布爾值,指示事件是否是起泡事件類型。 |
cancelable |
返回布爾值,指示事件是否可擁可取消的默認動作。 |
currentTarget |
返回其事件監聽器觸發該事件的元素。 |
eventPhase | 返回事件傳播的當前階段。 |
target |
返回觸發此事件的元素(事件的目標節點)。 |
timeStamp | 返回事件生成的日期和時間。 |
type |
返回當前 Event 對象表示的事件的名稱。 |
initEvent() | 初始化新創建的 Event 對象的屬性。 |
preventDefault() |
通知瀏覽器不要執行與事件關聯的默認動作。 |
stopPropagation() |
不再派發事件。 |
4. Event對象的一些兼容性寫法
- 獲得event對象兼容性寫法
event || (event = window.event);
- 獲得target兼容型寫法
event.target||event.srcElement
- 阻止瀏覽器默認行為兼容性寫法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
- 阻止冒泡寫法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
- 注冊和刪除事件方法的形式
1.// 綁定事件.
2.function on(id, eventType, fn) {
3. var dom = this.isString(id) ? this.$id(id) : id;
4. if(dom.addEventListener) {
5. dom.addEventListener(eventType, fn);
6. } else {
7. if(dom.attachEvent) {
8. dom.attachEvent('on' + eventType, fn);
9. }
10. }
11.},
12.// 解除綁定
13.function un(id, eventType, fn) {
14. var dom = this.$id(id);
15. if(dom.removeEventListener) {
16. dom.removeEventListener(eventType, fn, false);
17. } else {
18. if(dom.detachEvent) {
19. dom.detachEvent("on" + eventType, fn)
20. }
21. }
22.
23.}