摘要:同樣還是用上面冒泡例子,則事件的傳播順序則是特別說(shuō)明之前不支持事件捕獲,,,,,目前支持良好。取決于指定事件處理程序的方法。
第一次在segmentfault寫文章,希望通過(guò)這種方式來(lái)鞏固所學(xué)的知識(shí),也歡迎童鞋們指正其中有不對(duì)和錯(cuò)誤的地方。^+^
事件流
事件流:頁(yè)面中接收事件的順序,即當(dāng)一個(gè)事件發(fā)生時(shí),該事件的傳播過(guò)程便叫做事件流
事件流的種類事件冒泡
事件由最具體的元素開(kāi)始逐級(jí)向上傳播至較為不具體的節(jié)點(diǎn)(文檔)
點(diǎn)我
當(dāng)我們點(diǎn)擊id為box的div時(shí),該點(diǎn)擊事件傳播順序如下
div --> body --> html -->document
特別說(shuō)明:IE5.5及更早的版本將繞過(guò)html節(jié)點(diǎn)直接到document,IE9,F(xiàn)irefox,chrome和safari將冒泡到window對(duì)象
事件捕獲
事件捕獲和事件冒泡似乎截然相反,由不太具體的節(jié)點(diǎn)先接收到事件 -->再到最具體的節(jié)點(diǎn)。同樣還是用上面冒泡例子,則事件的傳播順序則是:
document --> html -->body -->div
特別說(shuō)明:ie8之前不支持事件捕獲,IE9,safari,chrome,opera,firefox目前支持良好。并且這些瀏覽器不是從document開(kāi)始捕獲,而是從window對(duì)象開(kāi)始。
DOM事件流階段捕獲階段
目標(biāo)階段
冒泡階段
以上面的代碼為例子,由圖可以很清晰地看出首先發(fā)生的是事件捕獲-->實(shí)際的目標(biāo)接收事件-->事件冒泡
特別說(shuō)明:在DOM事件流中,實(shí)際的目標(biāo)不會(huì)在捕獲階段接收到事件,即捕獲階段到body就停止,"下一階段"是目標(biāo)階段,該階段可以看成是事件冒泡的一部分,最終事件又被傳播會(huì)document。
BUT :我們的各大瀏覽器總是不喜歡按照規(guī)范來(lái),IE9,Safari,chrome,firefox及其更高的版本中都會(huì)在捕獲階段出發(fā)事件對(duì)象上的事件,最后導(dǎo)致有兩個(gè)機(jī)會(huì)在目標(biāo)對(duì)象上操作事件。
事件處理程序
事件:用戶或者瀏覽器自身執(zhí)行的某個(gè)動(dòng)作,比如load,click,mousemove等
事件處理程序:相應(yīng)某個(gè)事件的函數(shù)叫做事件處理函數(shù)(也叫做事件偵聽(tīng)器)
1 html事件處理程序:某個(gè)元素支持的某個(gè)事件可以用與事件處理程序同名的html特性來(lái)指定,該特性的值是能夠執(zhí)行的javascript代碼。
/* 當(dāng)點(diǎn)擊該按鈕的時(shí)候,瀏覽器會(huì)彈出"我被點(diǎn)擊了"; */
當(dāng)然也可以給onclick賦值頁(yè)面中其他地方定義的腳本
優(yōu)點(diǎn):簡(jiǎn)單明了,省去獲取元素等一系列前提操作
缺點(diǎn):html代碼與js代碼高度耦合,不符合分離原則
2 DOM0級(jí)別事件處理函數(shù):使用 element.on[eventname]=fn的方式給元素添加事件
3 DOM2級(jí)事件處理程序:DOM2級(jí)添加了addEventListener(添加事件處理程序)和removeEventListener(移除事件處理程序)
添加事件處理函數(shù)
移除事件處理函數(shù):如果事件處理函數(shù)是有名函數(shù),則可以通過(guò)名字來(lái)移除,匿名函數(shù)無(wú)法移除。
4IE事件處理程序:ie實(shí)現(xiàn)了與dom類似的兩個(gè)方法,attachEvent(添加),detachEvent(刪除)
添加事件處理函數(shù)
刪除事件處理函數(shù)
事件函數(shù)封裝
綁定 為了解決attachEvent的this指向問(wèn)題,并且可以通過(guò)有名稱的函數(shù)來(lái)解除事件綁定,現(xiàn)在處理如下
// function bind(obj,eventName,fn){ var _fn=fn; fn=function(){ _fn.call(obj);//改變this指向 }; if(obj.addEventListener){ obj.addEventListener(eventName,fn,false); }else{ obj.attachEvent("on"+eventName,fn); } return fn;//用于事件解除 }
解除
function unbind(obj,eventName,fn){ if(obj.removeEventListener){ obj.removeEventListener(eventName,fn); }else{ obj.detachEvent("on"+eventName,fn); } }
使用方式
//給input添加和移除事件 //添加 function show( ){ alert(this); } function show2( ){ alert(this.id); } var removeFn=bind("box","click",show);//需要移除的事件處理程序,不是原程序名稱show bind("box","click",show2); unbind("box","click",removeFn); //最后只會(huì)彈出 box事件對(duì)象
DOM中的事件對(duì)象當(dāng)觸發(fā)DOM上面的某個(gè)事件的時(shí)候,會(huì)產(chǎn)生一個(gè)事件對(duì)象event,這個(gè)對(duì)象中包含著所有與事件對(duì)象有關(guān)的信息。例如該事件類型,導(dǎo)致事件的元素等
DOM中的事件對(duì)象:兼容DOM的瀏覽器會(huì)將event對(duì)象傳入到事件處理程序中,無(wú)論指定事件處理程序用什么方式(html方式,DOM0級(jí)方式,DOM2級(jí)方式)
//html方法 click var oBox=document.getElementById("box"); //DOM0級(jí)別方法 click oBox.onclick=function(ev){ console.log(ev.type);//click } ///DOM2級(jí)別方法 click oBox.addEventListener("click",function(ev){ console.log(ev.type);//click })
總的來(lái)說(shuō)event對(duì)象包含與創(chuàng)建他的特定事件有關(guān)的屬性和方法,但是觸發(fā)的事件類型不同,則可用的屬性和方法也不一樣。但是都會(huì)包含以下成員
屬性/方法 | 類型 | 讀/寫 | 說(shuō)明 | |
---|---|---|---|---|
currentTarget | element | 只讀 | 事件處理程序當(dāng)前正在處理程序的那個(gè)元素,我的理解是事件的直接綁定者 | |
target | element | 只讀 | 事件的目標(biāo) | |
cancelable | boolean | 只讀 | 表示是否可以取消事件的默認(rèn)行為 | |
preventDefault() | function | 只讀 | 取消事件的默認(rèn)行為 ,前提是cancelable為true | |
bubbles | boolean | 只讀 | 表明事件是否可以冒泡 | |
stopPropagation() | function | 只讀 | 取消事件的進(jìn)一步冒泡或者捕獲,前提是bubbles為true | |
type | boolean | 只讀 | 事件類型 | |
view | abstractView | 只讀 | 與事件關(guān)聯(lián)的抽象視圖,等同于發(fā)生事件的window對(duì)象 | |
detail | integer | 只讀 | 與事件相關(guān)的細(xì)節(jié)信息 | |
eventPhase | integer | 只讀 | 調(diào)用事件處理程序的階段,1::捕獲,2:“處于目標(biāo)”,3:冒泡 | |
trusted | boolean | 只讀 | 為true表示事件是由瀏覽器生成的,為false表示事件是由開(kāi)發(fā)人員通過(guò)js生成的。(DOM3) | |
stopImmediatePropagation() | function | 只讀 | 取消事件的進(jìn)一步捕獲或者冒泡,同時(shí)阻止任何事件處理程序被調(diào)用(DOM3) |
特別說(shuō)明:只有在事件處理程序被執(zhí)行的期間,event對(duì)象才會(huì)存在,一旦事件處理程序執(zhí)行完成,其就會(huì)被銷毀。
IE中的事件對(duì)象與訪問(wèn)DOM中的事件對(duì)象不同,要訪問(wèn)IE中的event對(duì)象有幾種不同的方式。取決于指定事件處理程序的方法。
html event
函數(shù)參數(shù)
window.event
同樣IE中的event對(duì)象也包含著與創(chuàng)建他的事件相關(guān)的屬性和方法,其中很多的屬性和方法都有對(duì)應(yīng)的或者是相關(guān)的DOM屬性和方法。當(dāng)然也會(huì)事件的不同,其屬性和方法也會(huì)有所不同,但是都會(huì)包含下表內(nèi)容
屬性/方法 | 類型 | 讀/寫 | 說(shuō)明 | |
---|---|---|---|---|
srcElement | element | 只讀 | 事件的目標(biāo)(與DOM中的target屬性相同) | |
type | string | 只讀 | 事件的類型 | |
cancelBubble | boolean | 只讀 | 默認(rèn)為false,設(shè)置為true表示取消冒泡(與stopPropagation()作用相同) | |
returnValue | boolean | 只讀 | 默認(rèn)為true,設(shè)置為false就可以取消默認(rèn)行為(與preventDefault()作用相同) |
我們?yōu)閑ventUtil添加幾個(gè)方法,以此來(lái)達(dá)到有關(guān)event對(duì)象的常用的跨瀏覽器的使用目標(biāo)
getEvent() 獲取事件對(duì)象
getTarget()獲取事件源
stopPropagation() 取消冒泡
preventDefault() 阻止默認(rèn)行為
var eventUtil={ getEvent:function(ev){ return ev || window.event;//獲取事件對(duì)象 }, getTarget:function(ev){ return ev.target || ev.srcElement;//獲取事件源 }, stopPropagation:function(ev){//阻止冒泡 if(ev.stopPropagation){ ev.stopPropagation(); }else{ ev.cancelBubble=true; } }, preventDefault:function(ev){//阻止默認(rèn)行為 if(ev.preventDefault){ ev.preventDefault(); }else{ ev.returnValue=true; } } }常見(jiàn)應(yīng)用之事件委托
說(shuō)明:需要給頁(yè)面中成百上千個(gè)li綁定一個(gè)事件并且輸出當(dāng)前元素的innerHTML
常見(jiàn)做法
這種方式通過(guò)遍歷DOM節(jié)點(diǎn)的方式添加事件處理程序有諸多缺點(diǎn),比如性能大大減低,新添加的li不具備click事件等。
利用事件委托(冒泡原理)
var oUl//假設(shè)oUl是li的父節(jié)點(diǎn) oUL.onclick=fuction(ev){ var ev=eventUtil.getEvent(ev); var target=eventUtil.getTarget(ev); console.log(target.innerHTML); }
利用事件委托可以大大地提高性能,后面隨時(shí)添加的元素都可以擁有這個(gè)點(diǎn)擊事件等
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86046.html
摘要:取消事件的默認(rèn)行為。阻止事件的派發(fā)包括了捕獲和冒泡阻止同一個(gè)事件的其他監(jiān)聽(tīng)函數(shù)被調(diào)用。 事件模型 DOM0 級(jí)事件模型 -沒(méi)有事件流,這種方式兼容所有瀏覽器 // 方式一 將事件直接通過(guò)屬性綁定在元素上 / 方式二 獲取到頁(yè)面元素后,通過(guò) onclick 等事件,將觸發(fā)的方法指定為元素的事件 var btn = document.getElementById(btn) btn....
摘要:使用級(jí)方法指定的事件處理程序被認(rèn)為是元素的方法。用于立即停止事件在中的傳播,取消進(jìn)一步的事件捕獲或冒泡。捕獲事件目標(biāo)對(duì)象冒泡只有在事件處理程序執(zhí)行期間,對(duì)象才會(huì)存在,執(zhí)行完成后,對(duì)象就會(huì)被銷毀。 引用 事件是我認(rèn)為前端最特別的地方,這是唯一其他語(yǔ)言不一樣的地方,我們通過(guò)它與頁(yè)面進(jìn)行交互。 事件流 事件流描述的是從頁(yè)面中接收事件的順序。IE和網(wǎng)景團(tuán)隊(duì)提出流相反的事件流概念。IE事件流是事...
摘要:使用級(jí)方法指定的事件處理程序被認(rèn)為是元素的方法。用于立即停止事件在中的傳播,取消進(jìn)一步的事件捕獲或冒泡。捕獲事件目標(biāo)對(duì)象冒泡只有在事件處理程序執(zhí)行期間,對(duì)象才會(huì)存在,執(zhí)行完成后,對(duì)象就會(huì)被銷毀。 引用 事件是我認(rèn)為前端最特別的地方,這是唯一其他語(yǔ)言不一樣的地方,我們通過(guò)它與頁(yè)面進(jìn)行交互。 事件流 事件流描述的是從頁(yè)面中接收事件的順序。IE和網(wǎng)景團(tuán)隊(duì)提出流相反的事件流概念。IE事件流是事...
摘要:緩沖模塊起初就是為瀏覽器而設(shè)計(jì)的,所以能很好的處理編碼的字符串,但不能很好的處理二進(jìn)制數(shù)據(jù)。有如下三個(gè)主要的流標(biāo)準(zhǔn)輸入標(biāo)準(zhǔn)輸出標(biāo)準(zhǔn)錯(cuò)誤可讀流如果說(shuō),緩沖區(qū)是處理原始數(shù)據(jù)的方式的話,那么流通常是移動(dòng)數(shù)據(jù)的方式。該方法讓可讀流繼續(xù)觸發(fā)事件。 緩沖(buffer)模塊 js起初就是為瀏覽器而設(shè)計(jì)的,所以能很好的處理unicode編碼的字符串,但不能很好的處理二進(jìn)制數(shù)據(jù)。這是Node.js的...
閱讀 2461·2021-10-08 10:17
閱讀 1837·2021-09-06 15:02
閱讀 2552·2019-08-29 17:30
閱讀 2676·2019-08-29 13:24
閱讀 1535·2019-08-29 11:12
閱讀 3349·2019-08-28 17:52
閱讀 676·2019-08-26 11:30
閱讀 3586·2019-08-26 11:01