原生js之DOM事件相關

前端學習的東西有不少,現代前端開發,前端工程化的東西要懂,基礎的原生js也要懂,畢竟,框架都是有生命週期的,更替很是快,然而卻有這麼一個框架,它是最輕量的前端框架,每一個瀏覽器都內置,它叫vanilla.js。好吧,其實vanilla.js就是原生js,不過是網上的一個玩笑而已,可是卻能說明一個很重要的問題,就是原生js很重要,因此這部分文章是關於前端開發中原生js的一系列問題的,這篇談一談DOM事件。javascript

DOM事件級別

DOM分四個級別,一級,二級,三級,沒有零級可是一般把DOM1規範造成以前的稱爲DOM0。而因爲1級DOM標準中並無定義事件相關的內容,因此DOM事件級別只包括DOM0級,DOM2級和DOM3級三種。html

首先來看不須要操控DOM的事件前端

<button type="button" onclick="log()"></button>
<script>
    function log() {
        console.log('Hello World');
    }
</script>

這段代碼你們確定都見過,不須要控制DOM,事件處理時間的函數直接寫在html屬性中。固然實際開發中應該沒有人這樣寫了,理由也很簡單,html和js強耦合,不管是編寫仍是維護都沒有任何好處,因而就有了DOM事件處理。java

DOM0級事件

一樣以上面的程序爲例,使用DOM0事件處理就是下面的樣子git

<button id="btn" type="button"></button>
<script>
    var btn = document.getElementById('btn');
    btn.onclick = function() {
        console.log('Hello World');
    }
</script>

一樣很簡單,前端開發者必定都不陌生,DOM0事件定義須要兩部,先找到DOM節點,而後把處理函數賦值給該節點對象的事件屬性。若是想解除事件,那麼只要把null賦值給事件屬性便可。DOM0級事件沒法給一個事件添加多個處理函數,github

DOM2級事件

上面的程序使用DOM2級事件處理就是這樣的前端工程化

<button id="btn" type="button"></button>
<script>
    var btn = document.getElementById('btn');
    function log() {
        console.log('Hello World');
    }
    btn.addEventListener('click', log, false);
</script>

DOM2級事件使用addEventListener,裏面有三個參數,第一個參數是事件名,就是事件屬性去掉on,第二個參數是事件處理函數,第三個參數是是否在事件捕獲階段執行(關於事件冒泡和事件捕獲下面會介紹)。使用DOM2事件能夠隨意添加多個處理函數,移除DOM2事件要用removeEventListener,傳入的三個參數與添加事件徹底相同。特別的舊版本IE瀏覽器(IE8及一下),須要使用attachEvent和detachEvent來添加和移除事件,傳入兩個參數第一個是事件屬性(包含on),第二個是處理函數,不支持事件捕獲因此沒有第三個參數。瀏覽器

DOM3級事件

DOM3級事件就是在DOM2基礎上增長了更多的事件類型前端框架

  • UI事件,當用戶與頁面上的元素交互時觸發,如:load、scroll
  • 焦點事件,當元素得到或失去焦點時觸發,如:blur、focus
  • 鼠標事件,當用戶經過鼠標在頁面執行操做時觸發如:dbclick、mouseup
  • 滾輪事件,當使用鼠標滾輪或相似設備時觸發,如:mousewheel
  • 文本事件,當在文檔中輸入文本時觸發,如:textInput
  • 鍵盤事件,當用戶經過鍵盤在頁面上執行操做時觸發,如:keydown、keypress
  • 合成事件,當爲IME(輸入法編輯器)輸入字符時觸發,如:compositionstart
  • 變更事件,當底層DOM結構發生變化時觸發,如:DOMsubtreeModified

DOM事件級別的發展使得事件處理更加完整豐富,而下一個問題就是以前提到的事件冒泡和事件捕獲。框架

事件冒泡和事件捕獲

有如下HTML結構

<html>
    <body>
        <div>
            <span>
                我是目標內容
            </span>
        </div>
    </body>
</html>

如今給最裏面的目標內容綁定事件,就會有一個從事件源和目標之間的事件流,此例中,事件流的方向爲window -> document -> html -> body -> div -> span -> 目標 -> span -> div -> body -> html -> document -> window ,整個事件流分爲兩個部分,以事件目標爲界限,從window到目標這個過程爲事件捕獲,從目標回到window的過程叫事件冒泡。如圖所示:

事件默認的處理階段爲冒泡階段,能夠把addEventListener第三個參數設置爲true來讓時間在捕獲階段被處理,不過一般不建議這樣作。實際開發中,常常會利用到事件冒泡,也常常須要阻止事件冒泡,這就涉及到事件對象event的相關內置方法和屬性了。

event對象

事件處理函數會回調一個參數event,表明當前事件對象,event中有不少經常使用的方法和屬性

  • preventDefault 阻止默認行爲,好比當點擊submit按鈕時候,能夠採用此方法阻止表單提交。
  • stopPropagation 中止事件冒泡,須要防止事件冒泡帶來的負面影響的時候就要使用該方法。
  • stopImmediatePropagation 阻止後續事件,該方法除了阻止事件冒泡外在當前事件被綁定多個處理程序的時候,後續的處理程序也會被阻止。
  • currentTarget 此屬性返回當前事件所綁定的對象。
  • target 此屬性返回當前觸發事件的對象,注意target是觸發事件的對象,是真正的事件源,一樣以上面的HTML爲例,給div綁定一個事件,點擊帶文字的span後,target是span,而currentTarget是div。

事件冒泡和target屬性能作不少事情,好比考慮下面的結構

<ul id="click">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
  </ul>

若是想要實現點擊每一個li標籤就能打印出文本內容,咱們能夠不用給每一個li綁定事件,只須要利用事件冒泡便可

var click = document.getElementById('click');
  click.addEventListener('click', log, false);
  function log(e) {
    console.log(e.target.innerText);
  }

自定義事件

除了系統內置的事件外,咱們還能夠自定義事件,因爲平時使用的很少可能感受會很高端,其實自定義事件並不複雜

var myEvent = new Event('myEvent');
  document.addEventListener('myEvent', log, false);
  function log() {
    console.log('hello event');
  }
  document.dispatchEvent(myEvent);

經過建立Event對象來建立事件,經過dispatchEvent函數派發事件。自定義事件能夠綁定到任意DOM元素上,此處選擇document只是爲了演示方便。


以上就是關於DOM事件的相關內容總結,接下來後面還會有其餘技術的相關文章。
歡迎關注https://fx109138.github.io/

相關文章
相關標籤/搜索