成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

javascript 之 事件篇

Forest10 / 1217人閱讀

摘要:處于目標(biāo)階段事件在上發(fā)生并處理。冒泡階段事件又傳播回文檔。不支持捕獲事件的??偨Y(jié)二使用事件委托新添加的元素還會(huì)有之前的事件。事件對(duì)象在觸發(fā)某個(gè)事件時(shí),會(huì)產(chǎn)生一個(gè)事件對(duì)象。

js 是采用異步事件驅(qū)動(dòng)的機(jī)制來(lái)響應(yīng)用戶(hù)操作的,也就是說(shuō)當(dāng)用戶(hù)對(duì)某個(gè)html元素進(jìn)行操作的時(shí)候,會(huì)產(chǎn)生一個(gè)事件,該事件會(huì)驅(qū)動(dòng)某些函數(shù)來(lái)處理。
事件源:產(chǎn)生事件的地方(html元素,窗口,其他等等);
事件:鼠標(biāo)事件,鍵盤(pán)操作、HTML事件等等;
事件對(duì)象:當(dāng)某個(gè)事件發(fā)生時(shí),可能會(huì)產(chǎn)生一個(gè) 事件對(duì)象,該事件對(duì)象會(huì)封裝好該事件的信息,傳遞給事件處理程序;
事件處理程序:響應(yīng)用戶(hù)事件的代碼;
事件流:頁(yè)面中接受事件的順序。

事件流

JS事件流最早要從IE和網(wǎng)景公司的瀏覽器大戰(zhàn)說(shuō)起,IE提出的冒泡型事件流和Netscape 提出捕獲型事件流。

事件冒泡

事件冒泡是指事件是按照特定的事件目標(biāo)到最不特定的事件目標(biāo)的順序觸發(fā), 即從DOM樹(shù)的葉子到根。當(dāng)用戶(hù)點(diǎn)擊了一個(gè)

元素,click事件將按照
—>—>—>document的順序進(jìn)行傳播。若在
和上都定義了click事件,


    
s2s2s2s2

點(diǎn)擊s2輸出:
s2 冒泡模式下
s1 冒泡模式下

事件捕獲

事件捕獲是指事件的傳播是從最不特定的事件目標(biāo)到最特定的事件目標(biāo),即從DOM樹(shù)的根到葉子。當(dāng)用戶(hù)點(diǎn)擊了一個(gè)

元素,采用事件捕獲,則click事件將按照document—>—>—>
的順序進(jìn)行傳播。


    
s2s2s2s2

點(diǎn)擊s2:
s1 捕獲模式下
s2 捕獲模式下

DOM事件流

在W3C組織的統(tǒng)一之下,JS支持了冒泡流和捕獲流,但是目前低版本的IE瀏覽器還是只能支持冒泡流(IE6,7,8);
js事件流原理圖如下:

DOM2級(jí)事件流被分為三個(gè)階段:事件捕獲階段,處于目標(biāo)階段和事件冒泡階段。
事件捕獲階段:實(shí)際目標(biāo)(

)在捕獲階段不會(huì)接收事件。也就是在捕獲階段,事件從document到再到就停止了。
處于目標(biāo)階段:事件在
上發(fā)生并處理。但是事件處理會(huì)被看成是冒泡階段的一部分。
冒泡階段:事件又傳播回文檔。
也就是說(shuō)一個(gè)js事件流是從window開(kāi)始,最后回到window的一個(gè)過(guò)程。

但是,注意上述描述的是DOM2級(jí)事件流的原理,也就是說(shuō)不是所有的JS的事件流都是根據(jù)上圖所示的過(guò)程推進(jìn)的。

DOM level0不支持捕獲事件的。

DOM level ???

DOM0:將要添加的事件處理程序直接賦給該對(duì)象的事件處理程序?qū)傩浴?/p>


    

使用IE8,firefox,chrome瀏覽器測(cè)試:

點(diǎn)擊按鈕彈出:‘DOM0點(diǎn)擊事件 2’ 和 ‘wrapper 點(diǎn)擊事件‘;
點(diǎn)擊div彈出:‘wrapper 點(diǎn)擊事件’;

從運(yùn)行結(jié)果可以得出以下結(jié)論:
1、在DOM Level 0中的只能一個(gè)元素只能綁定一個(gè)事件,多個(gè)事件,后面的會(huì)覆蓋掉前面的事件。
2、DOM Level 0不會(huì)阻止事件冒泡的發(fā)生,但是不支持事件捕獲。
2、所有瀏覽器均支持。

DOM2級(jí)事件定義了兩個(gè)方法,addEventListener()方法和removeEventListener()方法來(lái)處理和刪除事件處理程序,當(dāng)然,這個(gè)是標(biāo)準(zhǔn)的。
它們可以接收三個(gè)參數(shù),
第一個(gè)參數(shù):要處理的事件名,是一個(gè)字符串,但是要記得不要加“on”作為前綴,
第二個(gè)參數(shù):作為事件處理的函數(shù),
第三個(gè)參數(shù):一個(gè)布爾值,這個(gè)布爾值為true時(shí),那就在事件捕獲階段調(diào)用事件處理程序,如果是false那就在冒泡階段調(diào)用事件處理程序。

    
        
s2s2s2s2

使用chrome瀏覽器測(cè)試,彈出內(nèi)容:
s1 捕獲模式下
s2 捕獲模式下
s2 冒泡模式下
s1 冒泡模式下

由此可以看出:
1、DOM Level 2可以在一個(gè)元素上面注冊(cè)多個(gè)事件。
2、DOM Level 2支持事件捕獲也支持事件冒泡,但捕獲事件要比冒泡事件先觸發(fā)。

上面是用chrome測(cè)試的,現(xiàn)在我們用IE8測(cè)試一下,點(diǎn)擊了下,沒(méi)有任何彈層,IE8以下瀏覽器不支持addEventListener函數(shù),

事件委托(或稱(chēng)事件代理)

事件委托是冒泡型事件流的典型應(yīng)用啊,什么是事件委托呢?也就是利用冒泡的原理,把事件加到父級(jí)上,觸發(fā)執(zhí)行效果。
上一段代碼,方法一:

  • 111
  • 222
  • 333
  • 444

很簡(jiǎn)單的代碼,現(xiàn)在分析一下DOM是怎么執(zhí)行的,首先找到ul,然后遍歷li,點(diǎn)擊li的時(shí)候,找到目標(biāo)li的位置,執(zhí)行點(diǎn)擊事件,這樣每次點(diǎn)擊都要找一次 li 哦,那我們使用事件委托如何處理呢?
方法二:

(function(){
        var wrapper = document.getElementById("wrapper");
        wrapper.onclick=function(e){
            var e=e || window.event;
            var target= e.target || e.srcElement;
            if(target.nodeName.toLocaleLowerCase()==="li"){
                alert(target.getAttribute("url"));
            }
        }
 })();

用父級(jí)ul做事件處理,當(dāng)li被點(diǎn)擊時(shí),由于冒泡原理,事件就會(huì)冒泡到ul上,因?yàn)閡l上有點(diǎn)擊事件,所以事件就會(huì)觸發(fā),當(dāng)然,這里當(dāng)點(diǎn)擊ul的時(shí)候,也是會(huì)觸發(fā)的,所以我們?cè)谏厦婕恿艘粋€(gè)判斷,event 對(duì)象提供了一個(gè)屬性target,可以返回事件的目標(biāo)節(jié)點(diǎn),也就是說(shuō),target就可以表示為當(dāng)前的事件操作的DOM,但是不是真正操作DOM。

點(diǎn)擊li會(huì)觸發(fā)事件了,且每次只執(zhí)行一次dom操作,如果li數(shù)量很多的話(huà),將大大減少dom的操作,優(yōu)化的性能可想而知!

總結(jié)一:使用事件委托可以提高性能。

在項(xiàng)目中我們的DOM有時(shí)候是動(dòng)態(tài)生成的,我們現(xiàn)在使用方法一,

(function(){
        var wrapper = document.getElementById("wrapper");
        var lists = wrapper.getElementsByTagName("li");
        
        for(var i=0;i

你會(huì)發(fā)現(xiàn),新增的li 是沒(méi)有事件的,說(shuō)明添加子節(jié)點(diǎn)的時(shí)候,事件沒(méi)有一起添加進(jìn)去的,這要怎么辦呢?
解決問(wèn)題方法是使用事件代理機(jī)制,當(dāng)事件被拋到更上層的父節(jié)點(diǎn)的時(shí)候,我們通過(guò)檢查事件的目標(biāo)對(duì)象(target)來(lái)判斷并獲取事件源Li。

總結(jié)二:使用事件委托新添加的元素還會(huì)有之前的事件。

事件對(duì)象event

在觸發(fā)某個(gè)事件時(shí),會(huì)產(chǎn)生一個(gè)事件對(duì)象event。事件對(duì)象的作用是用來(lái)記錄事件發(fā)生是一些相關(guān)的信息,注意事件對(duì)象只有在事件發(fā)生時(shí)才會(huì)產(chǎn)生,我們無(wú)法手動(dòng)創(chuàng)建,event對(duì)象只有在事件處理程序執(zhí)行期間,才會(huì)存在,執(zhí)行完畢即銷(xiāo)毀。

所有瀏覽器都支持event對(duì)象,event對(duì)象會(huì)傳入DOM0級(jí),DOM2級(jí),HTML指定,的事件處理程序中,但支持的方式不同,所以也會(huì)涉及跨瀏覽器的部分。

DOM中的事件對(duì)象:
IE中將Event視作window對(duì)象屬性,NetScape直接看做Event對(duì)象;瀏覽器兼容方法:

var e = event || window.event;

HTML事件處理程序中的event:


事件對(duì)象重要屬性和方法

event對(duì)象包含與創(chuàng)建它的特定事件有關(guān)的屬性和方法。觸發(fā)的事件類(lèi)型不一樣,可用的屬性和方法也不一樣。不過(guò)所有事件都會(huì)包括下表列出的成員:

type: 事件的類(lèi)型,如onlick中的click;
IE屬性-> srcElement,標(biāo)準(zhǔn)屬性->target: 觸發(fā)事件的元素
更多事件屬性和方法:http://www.w3school.com.cn/js...

事件處理程序 HTML事件處理程序

點(diǎn)擊

DOM0級(jí)事件處理程序

獲取對(duì)這個(gè)元素DOM對(duì)象的引用,用DOM的getElementById()等這種方式獲取到對(duì)這個(gè)元素對(duì)象的引用,然后就是每個(gè)事件都在這個(gè)對(duì)象上用相應(yīng)的屬性,例如click事件,那么這個(gè)對(duì)象就有一個(gè)onclick屬性與之對(duì)應(yīng),那你在這個(gè)對(duì)象的屬性上綁定事件處理程序。



顯示內(nèi)容:第二個(gè)點(diǎn)擊事件!
DOM0中每個(gè)事件元素目標(biāo)對(duì)于每個(gè)事件類(lèi)型只能最多注冊(cè)一個(gè)事件處理程序,若注冊(cè)多個(gè)后面的會(huì)覆蓋前面的,前面這個(gè)注冊(cè)程序就不會(huì)執(zhí)行了。

刪除這個(gè)事件處理程序:

s1.onclick=null; 
DOM2級(jí)事件處理程序

DOM2級(jí)事件定義了兩個(gè)方法,addEventListener()方法和removeEventListener()方法來(lái)處理和刪除事件處理程序。
它們可以接收三個(gè)參數(shù),第一個(gè)參數(shù):要處理的事件名,是一個(gè)字符串,但是要記得不要加“on”作為前綴,第二個(gè)參數(shù):作為事件處理的函數(shù),第三個(gè)參數(shù):一個(gè)布爾值,這個(gè)布爾值為true時(shí),那就在事件捕獲階段調(diào)用事件處理程序,如果是false那就在冒泡階段調(diào)用事件處理程序。


主要優(yōu)點(diǎn)是可以為同一個(gè)對(duì)象的同一個(gè)事件綁定多個(gè)事件處理程序。并且注冊(cè)的多個(gè)事件是按順序執(zhí)行的;
通過(guò)addEventListener添加的事件處理程序必須通過(guò)removeEventListener刪除,且參數(shù)一致。
那么我們?cè)谏厦娲a基礎(chǔ)上添加移除事件:

s1.removeEventListener("click",function(){
    console.log("取消點(diǎn)擊事件");
},false);

再次點(diǎn)擊還是顯示:
第一個(gè)點(diǎn)擊事件!
第二個(gè)點(diǎn)擊事件!
并未去掉點(diǎn)擊事件顯示‘取消點(diǎn)擊事件’,這又是怎么回事???
是因?yàn)椋和ㄟ^(guò)addEventListener添加的匿名函數(shù)將無(wú)法刪除
修改代碼:

function firstClick(){
    console.log("第一個(gè)點(diǎn)擊事件!");
}
function secClick(){
     console.log("第二個(gè)點(diǎn)擊事件!")
}
s1.addEventListener("click",firstClick,false);
s1.addEventListener("click",secClick,false);
s1.removeEventListener("click",secClick,false);

輸出:第一個(gè)點(diǎn)擊事件!

但是,這兩個(gè)方法不支持除IE8及以下的其他版本的所有瀏覽器,那IE事件處理程序又改如何寫(xiě)呢???

IE事件處理程序

IE8及以下的瀏覽器實(shí)現(xiàn)了類(lèi)似的添加移除方法:attachEvent()和detachEvent()。

這兩個(gè)方法都需要兩個(gè)參數(shù):事件處理程序名稱(chēng)和事件處理程序函數(shù)。注意是事件處理名稱(chēng),所以需要加‘on’,由于IE8及以下版本的瀏覽器只支持事件冒泡,所以通過(guò)attachEvent()添加的事件處理程序都是冒泡事件。

s1.attachEvent("onclick",function(){
   alert("第一個(gè)點(diǎn)擊事件!");
});
s1.attachEvent("onclick",function(){
    alert("第二個(gè)點(diǎn)擊事件!");
});

IE8及以下彈出的是:
第二個(gè)點(diǎn)擊事件!
第一個(gè)點(diǎn)擊事件!
detachEvent刪除事件和removeEventListener刪除事件一樣,添加的匿名函數(shù)無(wú)法刪除。

跨瀏覽器的事件處理程序
var eventUtil={
    addEvent:function(el,type,handler){
         if(el.addEventListener){
              el.addEventListener(type,handler,false);
         }else if(el.attachEvent){
              el.attachEvent("on"+type,handler)
         }else {
               element["on"+type]=handler;
          }
       },
    removeEvent:function(el,type,handler){
          if(el.removeEventListener){
               el.removeEventListener(type,handler,false)
          }else if(el.detachEvent){
               el.detach("on"+type,handler)
          }else {
               el["on"+type]=null;
          }
     }
  }

參考的文檔:
http://www.jb51.net/article/7...
http://blog.csdn.net/jsdcheny...
http://www.cnblogs.com/todayh...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/88372.html

相關(guān)文章

  • JS基礎(chǔ)--JSonunload、onbeforeunload事件詳解

    摘要:事件事件在用戶(hù)退出頁(yè)面時(shí)發(fā)生。注意事件同樣觸發(fā)了頁(yè)面載入事件事件。如圖所示大體一句話(huà)描述和支持事件但是或者不支持該事件。瀏覽器兼容情況完美支持不支持文字提醒信息不支持如圖所示使用遇到的凡是標(biāo)簽都會(huì)觸發(fā)事件包括這種。 簡(jiǎn)介 onunload,onbeforeunload都是在刷新或關(guān)閉時(shí)調(diào)用,可以在腳本中通過(guò) window.onunload來(lái)調(diào)用。區(qū)別在于onbeforeunload在o...

    rollback 評(píng)論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁(yè)面加載速度的方法隨筆分類(lèi)中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁(yè)性能管理詳解離線緩存簡(jiǎn)介系列編寫(xiě)高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問(wèn)性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁(yè)面加載速度的方法 隨筆分類(lèi) - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁(yè)性能管理詳解 HTML5 ...

    jsbintask 評(píng)論0 收藏0
  • 前端文檔收集

    摘要:系列種優(yōu)化頁(yè)面加載速度的方法隨筆分類(lèi)中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁(yè)性能管理詳解離線緩存簡(jiǎn)介系列編寫(xiě)高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問(wèn)性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁(yè)面加載速度的方法 隨筆分類(lèi) - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁(yè)性能管理詳解 HTML5 ...

    muddyway 評(píng)論0 收藏0
  • 前端面試Js

    摘要:作為構(gòu)造函數(shù)使用,綁定到新創(chuàng)建的對(duì)象。內(nèi)部實(shí)現(xiàn)類(lèi)和類(lèi)的繼承構(gòu)造函數(shù)構(gòu)造函數(shù)調(diào)用父類(lèi)構(gòu)造函數(shù)參考請(qǐng)盡可能詳盡的解釋的工作原理的原理簡(jiǎn)單來(lái)說(shuō)通過(guò)對(duì)象來(lái)向服務(wù)器發(fā)異步請(qǐng)求,從服務(wù)器獲得數(shù)據(jù),然后用來(lái)操作而更新頁(yè)面。 1 . 請(qǐng)解釋事件代理 (event delegation) 當(dāng)需要對(duì)很多元素添加事件的時(shí),可以通過(guò)將事件添加到它們的父節(jié)點(diǎn)通過(guò)委托來(lái)觸發(fā)處理函數(shù)。其中利用到了瀏覽器的事件冒泡機(jī)...

    anyway 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<