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

資訊專欄INFORMATION COLUMN

[學習筆記] 事件(上篇)

RayKr / 3567人閱讀

摘要:指定事件處理程序指定事件處理程序主要有兩種方式級事件處理程序級事件處理程序。添加事件處理程序注意這里是哦或移除事件處理程序使用移除事件處理程序的條件與方法相同必須提供相同的參數(shù),從而添加的匿名函數(shù)也無法被移除。

今天看書又看到事件,遂決定小總結(jié)一下~

JavaScript與HTML之間的交互是通過事件實現(xiàn)的。事件,就是文檔或瀏覽器窗口中發(fā)生的一些特定的交互瞬間??梢允褂帽O(jiān)聽器(事件處理程序)來監(jiān)聽事件,以便事件發(fā)生時執(zhí)行相應的代碼。

本文主要講事件流事件處理程序。后續(xù)會再寫一篇文章,總結(jié)事件類型。


事件流

大家都舉同心圓的栗子,我在這里也說說咯~想象畫在一張紙上的一組同心圓,如果把手指放在圓心上,那么手指碰觸的不是一個圓,而是紙上所有的圓。這和點擊HTML頁面上的元素原理是一樣的,如果頁面上有個按鈕,你點擊按鈕的同時,也點擊了按鈕的容器元素,點擊了容器元素的容器元素……點擊了整個頁面。

事件流描述的是從頁面中接收事件的順序。現(xiàn)存兩種事件流:

事件冒泡流——IE

事件捕獲流——Netscape

事件冒泡

接收事件的順序是:事件由最具體的元素接收,逐級向上傳播到較為不具體的節(jié)點。

如果頁面中有個div,點擊了div之后,事件的傳播順序如下:
(1) div
(2) body
(3) html
(4) document

事件冒泡的過程如下圖:

所有現(xiàn)代瀏覽器都支持事件冒泡,而且IE9,F(xiàn)irefox、Chrome、Safari都將事件一直冒泡到window對象。

事件捕獲

接收事件的順序是:事件由最不具體的元素接收,逐級向下傳播到最具體的節(jié)點。

如果頁面中有個div,點擊了div之后,事件的傳播順序如下:
(1) document
(2) html
(3) body
(4) div

事件捕獲的過程如下圖:

IE9,F(xiàn)irefox、Chrome、Safari都支持這種事件流模型,而且是從window對象開始捕獲事件的。

DOM事件流

“DOM2級事件”規(guī)定事件流包含3個階段:事件捕獲階段、處于目標階段、事件冒泡階段
如下圖:

在DOM事件流中,捕獲階段包括1,2,3。冒泡階段包括4,5,6,7。其中4是處理目標階段,在事件處理中被看成是冒泡階段的一部分。

雖然“DOM級事件”規(guī)范明確規(guī)定捕獲階段不涉及事件目標,但是IE9,F(xiàn)irefox、Chrome、Safari和Opera9.5及以上版本都會在捕獲階段觸發(fā)事件對象上的事件,這就意味著有兩個機會在目標對象上面操作事件。

IE9,F(xiàn)irefox、Chrome、Safari、Opera都支持DOM事件流,IE8及更早版本不支持DOM事件流。即IE9,F(xiàn)irefox、Chrome、Safari、Opera及支持冒泡又支持捕獲,而IE8及以前版本僅支持冒泡。

需要說明的是,在實際中,大多數(shù)都使用冒泡事件,僅在有特殊需要時才使用捕獲事件。

事件處理程序

在說事件處理程序之前,先簡單介紹下事件對象。什么是事件對象呢?
在觸發(fā)DOM上的某個事件時,會產(chǎn)生一個對象,這個對象中包含所有與事件有關的信息,如導致事件的元素、事件的類型以及其他與特定事件相關的信息,這個對象就是事件對象。所有的事件處理程序都可以訪問事件對象,但是訪問的方式不盡相同,一種是將事件對象作為事件處理程序的參數(shù),另一種是事件對象作為window的屬性,通過window.event來訪問。這里就介紹到這里,先有個概念~

回歸正題,click,loadmouseover都是事件的名字,而響應某個事件的函數(shù)就叫做事件處理程序,事件處理程序的名字以“on”開頭。

那么該怎樣為事件指定處理程序呢?主要有兩類方法:HTML事件處理程序JavaScript指定事件處理程序

HTML特性指定事件處理程序

某個HTML元素支持的每種事件,都可以使用一個與相應事件處理程序同名的HTML特性來指定。這個特性的值是能夠執(zhí)行的JavaScript代碼。

具體指定方式
  



這種方式中,事件處理程序中的代碼在執(zhí)行時,有權(quán)訪問全局作用域中的任何代碼。

本質(zhì)

這樣的事件處理程序在執(zhí)行的時候,會創(chuàng)建一個封裝著元素屬性值的函數(shù),然后執(zhí)行這個函數(shù)。就是說,

   

當單擊按鈕的時候,先創(chuàng)建一個函數(shù)function () { console.log("hello"); },然后立即執(zhí)行該函數(shù)。

這個函數(shù)有以下3個特點
1) 函數(shù)中會有一個局部變量event,即事件對象。
注意:event是局部變量,可以在函數(shù)中直接訪問,既不用自己定義,也不是從參數(shù)列表中讀取。這點與后面其他指定事件處理程序的方式有所不同,記得區(qū)分。
2) 函數(shù)內(nèi)部,this值等于事件的目標元素。
3)這個動態(tài)創(chuàng)建的函數(shù)使用with擴展作用域:

function () {
    with(document) {
        with(this) {
          // 元素屬性值,如 console.log("hello");
        }
    }
}

從而該函數(shù)可以訪問document及該元素本身的任何成員。這也是為什么“采用這種方式指定的事件處理程序中的代碼在執(zhí)行時,有權(quán)訪問全局作用域中的任何代碼?!?,因為作用域中有document

取消事件默認行為的方法

實質(zhì)上就是讓動態(tài)創(chuàng)建的函數(shù)return false,所以要這樣寫:

baidu



baidu

第二種方式一定要注意,return false是加在onclick屬性值里面的,如果放到show()里是不起作用的哦,因為是要“讓動態(tài)創(chuàng)建的函數(shù)return false

3個缺點

時差問題
用戶可能會在HTML元素一出現(xiàn)就在頁面上觸發(fā)相應的事件,但當時的事件處理程序有可能尚不具備執(zhí)行的條件,從而引發(fā)錯誤。比如上面的show()函數(shù),如果用戶單擊按鈕的時候,function show(){}還沒有執(zhí)行,就會導致錯誤。

這樣擴展事件處理程序的作用域鏈在不同的瀏覽器中會導致不同的結(jié)果。

HTML與JavaScript代碼緊密耦合,所以實際中這種方法使用的比較少。

JavaScript指定事件處理程序

JavaScript指定事件處理程序主要有兩種方式:DOM0 級事件處理程序、DOM2 級事件處理程序。使用JavaScript指定事件處理程序,首先必須取得對一個操作對象的引用。

DOM0 級事件處理程序

每個元素(包括windowdocument)都有自己的事件處理程序?qū)傩?,這些屬性通常全部小寫,如onclick,將這種屬性賦值為一個函數(shù),就是DOM0 級事件處理程序的指定方式。如下:

var btn = document.getElementById("myBtn"); // 取得對操作對象的引用
btn.onclick = function () { // 為onclick賦值一個函數(shù),指定事件處理程序
    console.log("hello");
}
移除事件處理程序:
btn.onclick = null; // 只需將屬性置空
特點:

1)添加事件處理程序的代碼只有在運行完之后才會為元素綁定事件處理程序,因此如果該段代碼未執(zhí)行單擊按鈕是沒有反應的。
2)事件處理程序中的this引用當前元素,即綁定了該事件的元素。
3)以這種方式添加的事件處理程序會在事件流的冒泡階段被處理。
4)所有的瀏覽器都支持DOM0 級事件處理程序。

DOM2 級事件處理程序

“DOM2 級事件處理程序”定義了兩個方法,用來指定和刪除事件處理程序:addEventListener()removeEventListener()。這兩個方法都接受3個參數(shù):要處理的事件名、作為事件處理程序的函數(shù)、一個布爾值,這個布爾值參數(shù)如果為true表示在捕獲階段調(diào)用事件處理程序,為false表示在冒泡階段調(diào)用事件處理程序,一般設為false。

添加事件處理程序:
var btn = document.getElementById("myBtn"); // 取得對操作對象的引用
btn.addEventListener("click", function(){ // 注意是 click 哦~
    console.log("hello");
}, false);

function show() {
    console.log("hello");
}

var btn = document.getElementById("myBtn"); // 取得對操作對象的引用
btn.addEventListener("click", show, false);
移除事件處理程序:

移除事件處理程序有一個要求就是:移除時傳入的參數(shù)必須與添加事件處理程序時使用相同的參數(shù)。從而通過addEventListener()添加的匿名函數(shù)將無法移除。

移除上面第二種方式綁定的事件處理程序代碼:

var btn = document.getElementById("myBtn"); // 取得對操作對象的引用
btn.removeEventListener("click", show, false);

要說明的是:通過addEventListener添加的事件處理程序只能通過removeEventListener()來移除。

特點

1)只有運行完addEventListener()才為元素綁定了事件處理程序。
2)事件處理程序中的this引用當前元素,即綁定了該事件的元素。
3)通過設置第三個參數(shù)為truefalse可以設定在捕獲階段還是冒泡階段調(diào)用事件處理程序。
4)可以為同一個元素綁定多個事件處理程序,綁定的事件處理程序會按照它們添加的先后順序依次觸發(fā)。這是DOM0 級事件處理程序不支持的哦~ DOM0 級只能添加一個事件處理程序,后添加的會覆蓋先添加的。
5)IE9、Firefox、Safari、Chrome和Opera都支持DOM2 級事件處理程序。

IE事件處理程序

上面特地加粗了IE9,那么IE8及以前版本怎么辦呢?IE實現(xiàn)了與DOM中類似的兩個方法:attachEvent()detachEvent()。這兩個方法僅接受兩個參數(shù):事件處理程序名稱事件處理程序函數(shù)。IE8及之前版本僅支持事件冒泡,所以通過attachEvent()添加的事件處理程序會在冒泡階段調(diào)用。

注:IE10及之前版本支持attachEvent()detachEvent()方法,IE11不再支持,一般IE9及以上都使用DOM方法,這兩個方法僅對IE8及以下版本使用。

添加事件處理程序:
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function () { // 注意這里是 onclick 哦~
    console.log("hello");
});

function show() {
    console.log("hello");
}

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", show);
移除事件處理程序:

使用detachEvent移除事件處理程序的條件與DOM方法相同——必須提供相同的參數(shù),從而添加的匿名函數(shù)也無法被移除。

var btn = document.getElementById("myBtn");
btn.detachEvent("onclick", show);
特點:

1)只有運行完attachEvent()才為元素綁定了事件處理程序。
2)事件處理程序會在全局作用域中運行,從而事件處理程序中的this指向全局對象window。這與之前的都不同哦~所以不能認為this始終等于事件目標,當使用attachEvent()的時候,thiswindow,不過其他時候,this是等于事件目標的~
3)可以為同一個元素綁定多個事件處理程序,綁定的事件處理程序會按照它們添加順序的相反次序被觸發(fā),即先添加后執(zhí)行,后添加的先執(zhí)行。

是不是覺得IE太奇葩呢,如果沒有IE,前端世界會和諧很多吧~還好IE9以上都是按照DOM標準來了,不再我行我素。

事件對象event

這里順便簡單說下事件對象,對比來看,會更清晰~
前面介紹過事件對象,這里不再贅述。

事件處理程序中訪問事件對象的方式

HTML特性指定事件處理程序
事件處理程序中會有個局部變量event,這個event就是事件對象。

JavaScript指定事件處理程序
無論指定事件處理程序采用的是DOM0 級還是DOM2 級方法,事件對象都會作為事件處理程序的參數(shù)傳入到事件處理程序中。

奇葩的IE
在使用DOM0 級方法添加事件處理程序時,事件對象作為window對象的屬性存在,通過window.event訪問。
如果使用attachEvent()添加事件處理程序,事件對象會作為參數(shù)傳入到事件處理程序中。

取消默認行為和阻止事件冒泡

DOM中的事件對象(兩個方法)
preventDefault()方法用來取消事件默認行為,stopPropagation()方法用來阻止事件進一步捕獲或冒泡

// 假設事件對象傳入給參數(shù)event
event.preventDefault(); // 取消事件默認行為
event.stopPropagation(); // 阻止事件進一步捕獲或冒泡

IE8及以下中的事件對象(兩個屬性)
returnValue屬性用來設置事件的默認行為。默認值為true,當設置為false時,就會取消事件的默認行為。
cancelBubble屬性用來取消事件冒泡。默認值為false,當設置為true時,就會阻止事件冒泡。

event.returnValue = false; // 取消事件的默認行為
event.cancelBubble = true; // 阻止事件冒泡

注:這兩個屬性僅IE8及以下版本支持,IE9+使用這兩個屬性會報錯。


終于寫完了,這篇寫得時間好長……這樣整理完知識脈絡會清晰一點吧~

本文主要參考《js高級程序設計》事件一章。如有不妥之處,還請指正。謝謝!

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

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

相關文章

  • [學習筆記] 事件上篇

    摘要:指定事件處理程序指定事件處理程序主要有兩種方式級事件處理程序級事件處理程序。添加事件處理程序注意這里是哦或移除事件處理程序使用移除事件處理程序的條件與方法相同必須提供相同的參數(shù),從而添加的匿名函數(shù)也無法被移除。 今天看書又看到事件,遂決定小總結(jié)一下~ JavaScript與HTML之間的交互是通過事件實現(xiàn)的。事件,就是文檔或瀏覽器窗口中發(fā)生的一些特定的交互瞬間??梢允褂帽O(jiān)聽器(事件處...

    wangym 評論0 收藏0
  • Laravel學習筆記之Model Observer模型觀察者

    摘要:說明本文主要學習下的模型觀察者,把一點點經(jīng)驗分享出來希望對別人能有幫助。模型觀察者這個功能能做很多事情,比如模型更新時發(fā)個通知??偨Y(jié)本篇文章主要學了下的模型觀察者,發(fā)現(xiàn)這個功能也能使代碼結(jié)構(gòu)更清晰,覺得挺好的。 說明:本文主要學習下Laravel的Model Observer模型觀察者,把一點點經(jīng)驗分享出來希望對別人能有幫助。同時,作者會將開發(fā)過程中的一些截圖和代碼黏上去,提高閱讀效率...

    Crazy_Coder 評論0 收藏0
  • AJAX的學習筆記(二)

    摘要:與不同的是,應該以發(fā)送的數(shù)據(jù)作為請求的主體。有了這些不同的事件支持,開發(fā)者可以免去檢查之類的工作,更加的方便。其中事件和事件比較重要。而事件則會為在瀏覽器接收數(shù)據(jù)期間周期性地觸發(fā)。 在上篇筆記中,我們主要談了一些概述和跨域的問題,這一次我們聊聊請求和響應的具體內(nèi)容。 向服務器發(fā)起請求 我們在創(chuàng)建了XHR對象后,接著需要用兩個方法來發(fā)送請求:open()和send(),這兩個方法有點像賽...

    Charles 評論0 收藏0
  • 前端補集 - 收藏集 - 掘金

    摘要:原文地址一個非常適合入門學習的博客項目前端掘金一個非常適合入門學習的項目,代碼清晰結(jié)構(gòu)合理新聞前端掘金介紹一個由編寫的新聞。深入淺出讀書筆記知乎專欄前端專欄前端掘金去年的一篇老文章,恰好今天專欄開通,遷移過來。 破解前端面試(80% 應聘者不及格系列):從閉包說起 - 掘金修訂說明:發(fā)布《80% 應聘者都不及格的 JS 面試題》之后,全網(wǎng)閱讀量超過 6W,在知乎、掘金、cnodejs ...

    YorkChen 評論0 收藏0
  • 前端補集 - 收藏集 - 掘金

    摘要:原文地址一個非常適合入門學習的博客項目前端掘金一個非常適合入門學習的項目,代碼清晰結(jié)構(gòu)合理新聞前端掘金介紹一個由編寫的新聞。深入淺出讀書筆記知乎專欄前端專欄前端掘金去年的一篇老文章,恰好今天專欄開通,遷移過來。 破解前端面試(80% 應聘者不及格系列):從閉包說起 - 掘金修訂說明:發(fā)布《80% 應聘者都不及格的 JS 面試題》之后,全網(wǎng)閱讀量超過 6W,在知乎、掘金、cnodejs ...

    AbnerMing 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<