Js 事件詳解

Dm碼羊發表於2020-05-14

一:js中常見得事件

 

(1) : 滑鼠事件
        click :點選事件
        dblclick :雙擊事件
        contextmenu : 右鍵單擊事件
        mousedown :滑鼠左鍵按下事件
        mouseup :滑鼠左鍵抬起事件
        mousemove :滑鼠移動
        mouseover :滑鼠滑入事件
        mouseout :滑鼠滑出事件
        mouseenter :滑鼠移入事件
        mouseleave :滑鼠移出事件
(2):鍵盤事件
        keyup : 鍵盤抬起事件
        keydown : 鍵盤按下事件
        keypress : 鍵盤按下事件
(3):表單事件
        change : 表單內容改變事件
        input : 表單內容輸入事件
        blur : 表單失去焦點
        focus: 表單獲取焦點
 
二:事件偵聽過程詳解
  
  1:事件偵聽 - 就是給事件源(dom元素)繫結一個事件
    
    給DOM元素新增一個事件偵聽(監聽),這個DOM元素只能收到對應事件型別的訊息
    語法DOM元素.addEventListener(事件型別,事件回撥函式,是否捕獲時執行)   - addEventListener這個就是用來偵聽事件得關鍵字
   偵聽事件addEventListenerd的三個引數引數: 
                引數1:事件型別 - 必須是字串,可以設定為任意字串,但是部分字串是系統事件型別
                引數2: 事件回撥函式 - 指向一個函式,當收到事件時執行該函式,如果沒有收到不執行函式,寫偵聽事件時不執行函式
                   注意1:事件回撥函式 - 有且僅有一個引數 為 e  - event物件
                   注意2:e 是一個事件物件,偵聽事件收到訊息時獲得的事件物件
     引數3:是否捕獲時執行 - 預設值是false,在冒泡時執行,捕獲時不執行 / 如果設定為true,在捕獲時執行
1 // 建立一個偵聽事件 , 事件型別為 點選 click ,回撥函式為clickHandler ,預設 冒泡
2             document.addEventListener('click',clickHandler)
3 
4 // 事件回撥函式的引數  MouseEvent - 滑鼠事件
5             function clickHandler(e) {
6                 console.log("我被點選了")  
7             }

  在上面得程式碼中偵聽事件得物件為 document 就是網頁,當我們點選網頁得任何一個位置就會觸發點選事件,那麼就會執行事件的回撥函式 clickHandler,列印結果

  1.2:刪除事件  

    刪除事件 : 語法 - 偵聽物件.removeEventListener(事件型別,事件回撥函式)  IE8 以上支援
               刪除事件的相容寫法:attachEvent 僅IE8及以下支援    事件型別   "on"+type   沒有捕獲、冒泡階段選項
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 6     <title>Document</title>
 7 </head>
 8 <body>  
 9     <button id="btn">按鈕</button>
10 </body>
11 <script>
12         // 獲取dom元素
13         var btn = document.querySelector('#btn')
14         // 偵聽事件
15         btn.addEventListener('click',clickHandler1)
16         // 事件回撥函式
17         var num = 0
18         function clickHandler1(e){
19             num++
20             console.log('當num > 3 得時候刪除事件')
21             if (num>3){
22                 // 刪除事件
23                 e.currentTarget.removeEventListener('click',clickHandler1)
24             }
25         }    
26 </script>
27 </html>

  當我們不斷點選按鈕,就會不斷的觸發事件,每點選一次 num 的值就會增加,當num大於3時,就刪除本次建立的事件和事件回撥函式,為什麼要刪除事件呢?因為當元素的事件不再使用時,必須刪除,否則會造成記憶體堆積,偵聽事件都會被儲存在堆中,當元素被刪除了,也必須刪除該元素的所有事件。

 

  2:事件偵聽 與 拋發  

   事件偵聽語法 : 事件偵聽物件.addEventListener(事件型別,事件回撥函式,是否捕獲時執行)

   建立事件物件語法:var evt = new Event(事件型別)  -指建立一個事件物件

        拋發事件語法: 事件偵聽物件.dispatchEvent(接受事件物件變數)
   在我們建立事件的過程中,必須先偵聽在拋發   - 如果先拋發在偵聽,我們將無法獲取到事件是否被觸發
            在我們使用偵聽事件的過程中需要注意:
                1:事件拋發一般分兩種 : 系統拋發事件 /  自定義拋發事件(需要我們自己建立事件物件)
                2:偵聽 和 拋發的物件 是同一個
                3:偵聽 和 拋發的事件型別 完全相同
                4:事件回撥函式不能使用return 返回值,但是可以return 跳出
       
 1 // 偵聽事件
 2         document.addEventListener('奧裡給',customHandler)
 3 // 建立一個事件物件 
 4         var evt = new Event('奧裡給')
 5 // 拋發事件
 6         document.dispatchEvent(evt)
 7 // 事件回撥函式
 8         function customHandler(e) {
 9             console.log(e.type)  //e.type 檢視事件的型別
10 }

 

 

三:事件三階段
  
       一階段:捕獲 由外到內
                 二階段:目標 到達目標
                 三階段:冒泡 由內到外
  事件三階段案例:先寫好html程式碼顯示三個背景顏色不一樣的塊。如下
js程式碼
 1 // 獲取 標籤
 2     var div0 = document.querySelector('.div0')    // 綠色背景塊
 3     var div1 = document.querySelector('.div1')    // 淺粉色塊
 4     var div2 = document.querySelector('.div2')    // 紅色塊
 5 
 6      // 給每個塊都新增點選事件  
 7     div0.addEventListener('click',clickHandler0)
 8     div1.addEventListener('click',clickHandler1)
 9     div2.addEventListener('click',clickHandler2)
10     function clickHandler0(e){
11         console.log('點選div0')
12     }
13 
14     function clickHandler1(e){
15         console.log('點選div1')
16         
17     }
18 
19     function clickHandler2(e){
20         console.log('點選div2')
21     }

當我們在點選紅色塊時,我們會發現,div1和div0都被列印了,這就是事件的冒泡,我們點選的真正目標為紅色塊div2,但是卻觸發了其他兩個塊,那麼事件如何進行三階段的呢?   首先當我們點選紅色塊div2時,事件進入一階段,捕獲階段,他會先進入div0,查詢目標,當沒有發現,會進入下一層查詢目標,當進入粉絲塊時,也沒有發現我們想要的目標,當進入紅色塊div2 時,就會找到我們點選的目標,div2,這個時候事件的一階段就變成了二階段,目標階段,就會開始向外傳送資訊觸發事件,執行事件回撥函式,並由二階段變成三階段,冒泡階段,這時是由內向外的一個過程,不斷的往外並觸發經過的塊的事件,直到最外層,這就是事件三階段的全過程。那麼我們可不可以讓他不冒泡呢,有 

阻止冒泡語法 e.stopPropagation()  只需要寫在想停止冒泡的事件回撥函式中

阻止事件冒泡 - 當我們只想讓紅色塊觸發事件,其他兩個塊不觸發就是不冒泡,就在紅色塊的事件回撥函式中,寫上阻止事件冒泡,這樣當事件到二階段找到目標時,就不會往外冒泡了,那麼div0和div1就不會被觸發,看如下程式碼,
 1     div0.addEventListener('click',clickHandler0)
 2     div1.addEventListener('click',clickHandler1)
 3     div2.addEventListener('click',clickHandler2)
 4     function clickHandler0(e){
 5         console.log('點選div0')
 6         
 7     }
 8 
 9     function clickHandler1(e){
10         console.log('點選div1')
11         
12     }
13 
14     function clickHandler2(e){
15         e.stopPropagation()  // 阻止事件冒泡
16         console.log('點選div2') 
17 
18     }

這就是事件的三階段過程,當你想在哪裡阻止就在哪裡書寫阻止事件的方法,是很給力的
 
四:常用滑鼠事件詳解
  
  1:滑鼠點選 和 雙擊事件
    1.1 單擊事件
1         // 單擊事件 click  - 偵聽物件 document
2          document.addEventListener("click",clickHandler)
3          // 滑鼠單擊事件回撥函式
4          function clickHandler(e){
5             console.log("我被點選了")
6          }    

當我們點選頁面任意一個地方時,就會觸發點選事件,列印結果

    1.2 雙擊事件

1         // 雙擊事件 dblclick  - 偵聽物件 document
2          document.addEventListener("dblclick",dbclickHandler)
3          // 滑鼠雙擊事件回撥函式
4          function dbclickHandler(e){
5             console.log("我被雙擊了")
6          }    

當我們雙擊頁面任意一個地方時,就會觸發點選事件,列印結果

 

  2:滑鼠移入移出事件 和 滑鼠滑入滑出事件 

 

    滑鼠移入移出(mouseenter 移入 mouseleave 移出)和 滑鼠滑入滑出事件事件是(mouseover 滑入 mouseout 滑出)有區別的,為了讓能更好的區分,將所有的事件寫在一個Dom元素上,同一個元素可以新增多個事件。

    滑鼠移入 和 滑鼠滑入事件的區別:滑鼠滑入事件是有冒泡階段的 ,可以收到子元素的滑入和滑出,而滑鼠移入事件沒有冒泡階段的,只能收到當前容器的移入和移出

    HTML程式碼如下:

 1 <style>
 2         /* 滑鼠事件樣式 */
 3         #div1{
 4             width: 200px;
 5             height: 200px;
 6             background-color: orange;
 7         }
 8         #div2{
 9             width: 100px;
10             height: 100px;
11             background-color: red;
12         }
13 </style>
14 <body>
15         <!--  滑鼠事件 -->
16         <div id="div1">
17             <div id="div2"></div>
18         </div>
19 </body>

  JS程式碼

 1      // 給 div1 新增 滑鼠劃入滑出,移入移出事件
 2     var div1 = document.querySelector('#div1')
 3     div1.addEventListener('mouseover',mouseHandler)   // 滑入
 4     div1.addEventListener('mouseout',mouseHandler)    // 滑出
 5     div1.addEventListener('mouseenter',mouseHandler)  // 移入
 6     div1.addEventListener('mouseleave',mouseHandler)  // 移出
 7 
 8     // 事件回撥函式
 9     function mouseHandler(e){
10         console.log(e.type)   // e.type 為事件的型別
11     }

當我們將滑鼠移入到 div1 父盒子上時,會發現滑鼠移入和滑入事件都觸發,因為div1父容器元素新增了移入滑入事件,效果如下:

 

 當將滑鼠移入到紅色塊 div2 中時,此時div2未新增任何事件,但是卻會觸發滑鼠滑入事件(mouseover),因為mouseovr事件有會冒泡,而moseenter並不會,只會收到當前新增了事件容器的事件,也就是div1,效果如下:

說明 mouseover 時有會冒泡的,而 moseenter是沒有冒泡階段的。

 

  3:滑鼠左鍵按下 和 鬆開事件

1         // 滑鼠左鍵按下鬆開事件  - 偵聽物件 document
2         document.addEventListener("mousedown",mouseHandler)  
3         document.addEventListener("mouseup",mouseHandler)
4 
5         // 事件回撥函式
6         function mouseHandler(e){
7                 console.log(e.type) 
8         }    

當按下滑鼠左鍵觸發 mousedown 事件,鬆開滑鼠左鍵觸發 mouseup 事件:

右鍵事件也是如上新增。

 

五:表單事件

  1:focus - 聚焦事件 和 blur - 失焦 事件

 1 <body>
 2         <input type="text" class="input">
 3 
 4 <script>
 5         // 獲取dom元素
 6         var input = document.querySelector('.input')
 7         // 新增 focus - 聚焦事件 和 blur - 失焦 事件
 8         input.addEventListener('focus',focusHandler)
 9         input.addEventListener('blur',focusHandler)
10 
11         // 事件回撥函式
12         function focusHandler(e){
13                 console.log(e.type)
14         }
15 </script>
16 </body>

當表單聚焦時,觸發 focus 事件,失焦時觸發 blur 事件:

  2:表單內容改變事件 - change 和 表單輸入事件 input

    2.1  change事件

 1 <body>
 2         <input type="text" class="input">
 3 
 4 <script>
 5         // 獲取dom元素
 6         var input = document.querySelector('.input')
 7         // 新增 change - 表單內容改變事件 
 8         input.addEventListener('change',changeHandler)
 9         // change事件回撥函式
10         function changeHandler(e){
11                 console.log(e.type,input.value)  // 列印觸發的事件和表單內容
12         }
13 </script> 
14 </body>

請注意,失焦時觸發!!

  2.2:input 事件  (一般input輸入事件都會配合 節流,因為輸入事件只要輸入一個字元都會觸發,比較耗效能。)

 1 <body>
 2          <input type="text" class="input">
 3 
 4 <script>
 5        // 獲取dom元素
 6        var input = document.querySelector('.input')
 7        // 新增 input - 表單輸入事件 
 8        input.addEventListener('input ',inputHandler)
 9        // input事件回撥函式
10        function inputHandler(e){
11               console.log(e.type,input.value)  // 列印觸發的事件和表單內容
12        }
13 </script> 
14 </body>

 

六:鍵盤事件

  1:keydown  按下鍵 和 keyup 鬆開鍵

  e.keyCode :鍵碼,鍵盤的每一個鍵都有對應的編碼,根據碼來辨別按下的是什麼鍵。

  e.code:鍵名

1      // 建立 按鍵偵聽事件 - 偵聽物件 document
2      document.addEventListener('keydown',keydownHandler)    // 按下鍵事件
3      document.addEventListener('keyup',keydownHandler)      // 鬆開鍵事件
4  
5      // 按鍵事件回撥函式
6      function keydownHandler(e){
7          console.log(e.type,e.code,e.keyCode)   // 列印事件型別和鍵名,鍵碼  
8      }

試試按下鍵盤上的 上下左右鍵,效果如下:

相關文章