在javascript和JQuery之中,都有事件的處理方式,在咱們編寫程序實現某些功能的時候,咱們會發現使用原生的DOM事件與JQuery中封裝的事件都能實現一樣的效果,那麼也許咱們會認爲他們之間的區別不是很大,甚至說基本沒有區別。這種觀點是錯誤的,其實在事件函數的底層設計時,他們賦予元素的事件屬性是經過不一樣的事件綁定機制來實現的。javascript
咱們先從表面理解:咱們都知道,JQuery是javascript的一個函數庫,他是基於javascript原生設計的。就是說JQuery中的事件,都是經過javascript來編寫的。這是其中的一點;還有最重要的一點就是他們綁定事件的方式不同,javascript和JQuery中則採用事件機制不一樣。這是他們之間主要的不一樣點,接下來咱們細細講講。前端
( 一 ) javascript 事件java
一 .DOM事件及其傳輸機制api
首先咱們要了解的事件的一些知識了,事件的組成,事件有3部分構成的,分別是事件源,事件,和事件處理。事件源和事件是最簡本的要求,可也沒有處理程序。瀏覽器
1.事件源:框架
簡單的說,就是被綁定事件的元素,dom
2.事件函數
在Javascript中event對象中有不少的事件,例如onload,onclick,onmouse等,可是咱們知道javascript中有內置的事件和Dom中event的事件,他們中有不少的相同事件,可是DOM對象event對象中相比較多出的不少的鍵盤/鼠標事件,和一些關於IE的私有事件(僅僅IE能使用)。性能
3.事件處理學習
當事件被觸發時,所要執行的javascript的代碼段,去完成某項功能。能夠不添處理程序。
(———)「事件冒泡」
在學習c語言時都知道冒泡排序,「事件冒泡」和它是徹底不一樣的,所謂的事件冒泡就是說,當咱們觸發事件時,事件會一級級的向它的祖先元素傳遞,一直到最高級,它的傳遞順序對於不一樣瀏覽器,也有所不一樣;
對於IE:觸發事件元素——祖先元素——body—— HTML——document;
高級瀏覽器:觸發事件元素——祖先元素——body——document——window;
也就是說事件一開始先從根節點流向目標事件(稱爲事件捕獲),而後在目標事件上被觸發(目標階段),以後再回到文檔根節點(事件冒泡)。事件冒泡是頗有用的,他能將咱們從事件的監聽中釋放出來,同時咱們也能夠監聽目標事件的祖先元素。又是由於事件冒泡的特色,這樣就會形成咱們的各個模塊之間會相互的影響,因此必需要消除他的影響。
(-----)事件捕獲階段
與事件冒泡不一樣,事件捕獲是事件的第一個階段,事件從文檔根節點出發,隨着DOM樹向事件目標流去,通過DOM的各個節點,一直流到事件目標位置,事件捕獲的主要做用就是創建一個路徑,在冒泡階段,事件會沿着這條路徑回到跟節點。
(----)目標階段
當事件到達目標節點時,事件就進入的目標階段。事件在目標節點上被觸發,而後向上傳播,直到回到文檔根節點。
清除事件影響,能夠經過event對象下的event.stopPropagation()函數來清除,對於IE,使用event.cancelBubble=true;來清除影響。
在說一種清除事件冒泡的辦法:preventDefault();這個函數也是event對象的辦法,他和stopPropagation()有一些區別的;
preventDefult(),他僅僅阻止事件的處理程序不在執行,卻不能阻止冒泡機制,
stopPropagation(),他能阻止冒泡機制,同事不影響事件的處理程序。
二.事件阻止
上面說了對事件的阻止最多見的兩種辦法,1.preventDefault();2.stopPropagation();咱們來細細說說他們的差異
一、preventDefault()
preventDefault()函數是用來阻止瀏覽器的默認行爲,那麼什麼是瀏覽器默認行爲呢?舉個例子,咱們一超連接link的<a>標籤爲例,當咱們點擊<a>標籤時,就觸發了瀏覽器默認click事件,經過冒泡機制,一直傳遞到document,而後由瀏覽器解析href內容,並在導航欄中打開地址。
經過preventDefault()函數,咱們能夠阻止不少瀏覽器的默認行爲,好比敲擊空格鍵的時頁面滾動。
2.stopPropagation()
調用event.stopPropagation()只會阻止傳播鏈中後續的回調函數被觸發(阻止了冒泡階段)。它不會阻止事件處理函數的行爲。
三. 自定義事件
瀏覽器並非能惟一觸發dom事件的載體,咱們能夠建立自定義的事件並把它們分派給你文檔中的任意節點。這些自定義的事件和一般的DOM事件有相同的行爲。這也就是咱們最最經常使用的綁定事件的方法,好比:li.onclick,div.onmouseover,都是一些常見的自定義事件。
四.代理事件
代理事件監聽可讓你使用一個事件監聽器去監聽大量的DOM節點的事件,在這種狀況下,它是一種更加方便而且高性能的事件監聽方法。舉例來講,若是有一個列表<ul>包含了100個子元素<li>,它們都須要對click事件作出類似的響應,那麼咱們可能須要查詢這100個子元素,並分別爲他們添加上事件監聽器。這樣的話,咱們就會產生100個獨立的事件監聽器。若是有一個新的元素被添加進去,咱們也須要爲它添加一樣的監聽器。這種方式不但代價比較大,維護起來也比較麻煩。
代理事件監聽可讓咱們更簡單的處理這種狀況。咱們不去監聽全部的子元素的click事件,相反,咱們監聽他們的父元素<ul>。當一個<li>元素被點擊的時候,這個事件會向上冒泡至<ul>,觸發回調函數。咱們能夠經過檢查事件的event.target屬性來判斷具體是哪個<li>被點擊了。
五 事件監聽和移除監聽機制
(—):事件監聽
在過去,瀏覽器的事件監聽機制是不盡相同的,可是隨着瀏覽器的逐漸的標準化,事件監聽機制也相對統一了,可是要是你要監聽IE瀏覽器的話,最好使用一些前端的框架,如jQuery,由於這些前端的框架封裝了很好的兼容問題。
事件的監聽函數:element.addEventListener(<event-name>, <callback>, <use-capture>);
參數:<event-name> 是咱們要監聽的事件,他能夠是任何Dom的標準事件(click,mousedown,);
參數:<callback> 是一個回調函數,當事件被觸發的時候,相應的事件對象和數據,會做爲一個參數傳遞給這個函數。
參數:<event-capture> 這個參數返回布爾值,它用來觀測回調函數是否在」事件捕獲階段「被觸發,
(二):移除事件監聽
咱們使用 element.removeEventListener()
方法來移除事件監聽;
element.removeEventListener(<event-name>, <callback>, <use-capture>);
可是removeElementListener
有一點須要注意的是:你必需要有這個被綁定的回調函數的引用。簡單地調用
element.removeEventListener('click');
是不能達到想要的效果的。也就是說,在移除事件監聽時,必需要有回調函數的調用,也就是說匿名函數不能做爲回調函數來使用的。
最後咱們來講一下DOM事件從被觸發到事假結束的所有過程:
對與自定義的事件: 一旦事件被觸發,經過事件監聽機制,瀏覽器開始「事件捕獲」階段,到達「目標階段「 ,而後執行相應函數處理,在經過」冒泡機制「將事件傳遞給根目錄。
而瀏覽器的默認行爲的執行過程與上面的差很少,只不過它是由瀏覽的默認綁定的函數處理方式來執行的,不會受你的控制。
( 二 )JQuery 事件
其實相對於DOM的事件的綁定系統和原理,JQuery的事件機制是很是的簡單的。由於jQuery 是對一些js代碼的封裝,他在封裝的過程當中爲咱們解決了不少的問題,好比最棘手的兼容問題,因此直接使用jQuery框架是很是方便的。
JQuery的事件綁定有兩種方式:1.綁定事件,2:觸發事件;
1.綁定事件
在jQuery中,他爲咱們提供了許多諸如click(),形式的API,這種事件就是所謂的綁定事件,這種事件的綁定方式非常僵硬,不靈活。
因此爲了實現綁定多個事件,JQuery又提供了on()這種綁定事件的方式,它容許咱們同時給對象綁定一個或多個事件。還有一個API,bind()
它也能夠綁定一個或多個事件,可是bind()和on()的不一樣之處就在與;on()只對匹配對象綁定事件,而bind()是對全部的匹配元素綁定事件,因此推薦使用on()的方式;
2.觸發事件
trigger() 在每一個匹配元素上觸發某類事件,同時這個函數也會致使瀏覽器同名的默認行爲的執行,因此在使用時爲了避免影響其餘部分,咱們須要返回值爲false。這種事件是間接的綁定事件,也就是說,在沒有觸發以前,並無事件綁定的。
triggerHandler() 具備trigger()的功能,可是他不會觸發瀏覽器的默認行爲;
補充:事件代理
jQuery 提供的api delegates()函數是用來作事件代理。給指定的元素(屬於被選元素的子元素)添加一個或多個事件處理程序,並規定當這些事件發生時運行的函數。
jQuery事件解綁
off():用來解除on()方式綁定的事件;
unbind():用來解除bind()方式綁定的事件;
undelegates():用來解除以delegates()方式事件委派任務。
事件的範疇不少,可是咱們常常用到的也就那些,只要平時稍加留意學習,總會加深對事件的理解,當中可能會出現一些表述不清的狀況,就須要咱們去查找資料去參考學習了。
困擾個人問題,總的想辦法解決,可是不免出錯,歡迎您的斧正
但願你們共同窗習 共同進步 共同維護前端的一片天!!!