JavaScript — event介紹以及兼容處理

JavaScript — event介紹以及兼容處理

1.事件流

瀏覽器發(fā)展到第四代時(shí)(IE4及 Netscape Communicator 4)蛛勉,瀏覽器開發(fā)團(tuán)隊(duì)遇到一個(gè)問題:頁面的哪個(gè)部分會擁有某個(gè)特定的事件怠噪?可以想象在一張紙上的一組同心圓樱溉,如果把手指放在圓心上咨演,那么你的手指指向的不是一個(gè)圓,而是紙上的所有圓奥帘。即在點(diǎn)擊一個(gè)按鈕時(shí)繁调,不僅點(diǎn)擊了按鈕,也點(diǎn)擊了整個(gè)頁面颗搂。

事件流描述的是從頁面中接收事件的順序担猛。不過IE 和 Netscape 開發(fā)團(tuán)隊(duì)提出的想法差不多完全相反。

IE的事件流是事件冒泡流丢氢,而 Netscape Communicator 的事件流是事件捕獲流毁习。

1.1 事件冒泡

IE的事件流叫做事件冒泡(event bubbling),即事件開始時(shí)是由最具體的元素接收卖丸,然后逐級向上傳播到較為不具體的節(jié)點(diǎn)纺且。

備注:所有現(xiàn)代的瀏覽器都支持事件冒泡,但是在具體實(shí)現(xiàn)上還有一些差別稍浆。IE5.5 以及更早的版本中的事件冒泡會跳過 html 元素载碌,即從body直接到 document猜嘱。而IE9、Firefox嫁艇、Chrome和Safari則將事件一直冒泡到window對象朗伶。

1.2 事件捕獲

Netscape Communicator 團(tuán)隊(duì)提出的另一種事件流叫做事件捕獲。思想是不太具體的節(jié)點(diǎn)應(yīng)該更早的接收到事件步咪,而最具體的節(jié)點(diǎn)應(yīng)該最后接收到事件论皆。

事件捕獲的用意在于事件到達(dá)預(yù)定目標(biāo)之前捕獲它。

雖然 事件捕獲 是Netscape Communicator 唯一支持的事件流模型猾漫,但是IE9点晴、Firefox、Opera悯周、Chrome和Safari目前也都支持這種事件流模型粒督。

盡管“DOM2級事件”規(guī)范要求事件應(yīng)該從document對象開始傳播,但是這些瀏覽器都是從window對象開始捕獲事件的禽翼。

由于老版本的瀏覽器不支持屠橄,因此很少有人使用事件捕獲。

1.3 DOM 事件流

“DOM2級事件”規(guī)定的事件流包括三個(gè)階段:事件捕獲階段闰挡、處于目標(biāo)階段和事件冒泡階段锐墙。首先發(fā)生的是事件捕獲,這為截獲事件提供了機(jī)會长酗。然后是實(shí)際的目標(biāo)接收到事件贮匕。最后一個(gè)階段是冒泡階段,可以在這個(gè)階段對事件作出響應(yīng)花枫。

2. 事件處理程序

2.1 HTML 事件處理程序

如下:

<input type="button" value="click" onclick="alert('hello')" />

2.2 DOM0級事件處理程序

通過JavaScript指定事件處理程序的傳統(tǒng)方式刻盐,就是將一個(gè)函數(shù)賦值給一個(gè)事件處理程序?qū)傩浴_@種為事件處理程序賦值的方法是在第四代Web瀏覽器中出現(xiàn)的劳翰,而且至今仍然為所有現(xiàn)代瀏覽器支持敦锌。一是簡單,二是具有跨瀏覽器優(yōu)勢佳簸。

每個(gè)元素都有自己的事件處理程序?qū)傩砸仪剑@些屬性通常全部小寫,例如:onclick生均。將這種屬性的值設(shè)置為一個(gè)函數(shù)听想,就可以制定事件處理程序。

如下例:

var btn = document.getElementById("myBtn");
btn.onclick = function(){
    alert(this.id); // "myBtn"
}
btn.onclick = null; // 刪除事件處理程序

以這種方式添加的事件處理程序會在事件流的冒泡階段被處理马胧。

2.3 DOM2級事件處理程序

“DOM2級事件”定義了兩個(gè)方法汉买,用于處理指定和刪除事件處理程序的操作:addEventListener()和removeEventListener()。都接受三個(gè)參數(shù):要處理的事件名佩脊、作為事件處理程序的函數(shù)和一個(gè)布爾值蛙粘。最后這個(gè)布爾值參數(shù)如果是true垫卤,表示在捕獲階段調(diào)用事件處理程序;如果是false出牧,表示在冒泡階段調(diào)用事件處理程序穴肘。默認(rèn)是 false。

使用DOM2級方法添加事件處理程序的主要好處是可以添加多個(gè)事件處理程序舔痕。

var btn = document.getElementById("myBtn");
btn.addEventListener("click",function(){alert(this.id)}) // this 指的是元素本身
btn.addEventListener("click",function(){alert("hello word!"))})

通過 addEventListener 添加的事件评抚,只能通過 removeEventListener 移除掉,移除時(shí)的參數(shù)需要和傳入的參數(shù)相同伯复。這也意味著傳入的匿名參數(shù)無法移除慨代。因此盡量避免使用匿名函數(shù)。

大多數(shù)情況下边翼,都是把事件處理程序添加到事件流的冒泡階段,這樣可以最大限度的兼容各種瀏覽器鸣剪。萬不得已的時(shí)候组底,再添加到捕獲階段。

2.4 IE事件處理程序

IE實(shí)現(xiàn)了與DOM中類似的兩個(gè)方法筐骇,attachEvent() 和 detachEvent()债鸡。這兩個(gè)方法接收兩個(gè)參數(shù),因?yàn)橹恢С置芭荨?br> 與addEventListener 和 removeEventListener 不同的是铛纬,接受的第一個(gè)參數(shù)厌均,必須帶on。如單擊事件告唆,為"onclick"棺弊;還有添加多個(gè)事件的時(shí)候,此方法按照添加的順序反向執(zhí)行擒悬。

此方法與DOM0級方法的主要區(qū)別是在于事件處理程序的作用域模她。此方法的事件處理程序會在全局作用域中運(yùn)行,其中的this為window

2.5 跨瀏覽器的事件處理程序

因?yàn)椴煌瑸g覽器對于事件的處理不一樣懂牧,所以可以手寫一些事件兼容方法侈净。如下:

var EventUtil = {
    // 添加事件處理程序
    addHandler: function(element, type, handler) {
        if (element.addEventListener) { // DOM2級 事件處理程序,this 指向元素本身僧凤。按照添加的順序正向執(zhí)行
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) { // IE 事件處理程序畜侦,this 指向 window。按照添加的順序反向執(zhí)行
            element.attachEvent("on" + type, handler);
        } else { // DOM0級 事件處理程序躯保。只能綁定一個(gè)事件處理程序
            element["on" + type] = handler;
        }
    },
    // 移除事件處理程序
    removeHandler: function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent("on" + type, handler);
        } else {
            element["on" + type] = null;
        }
    },
    // 獲取 event 對象旋膳。window.event 為 IE 瀏覽器的獲取方式
    getEvent: function(event) {
        return event ? event : window.event;
    },
    // 獲取event的target。 event.srcElement 只對老版本的 IE 瀏覽器有效
    getTarget: function(event) {
        return event.target || event.srcElement;
    },
    // 取消事件的默認(rèn)行為
    preventDefault: function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false; // IE
        }
    },
    // 阻止事件冒泡
    stopPropagation: function(event) {
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true; // IE
        }
    }
}

3.事件對象小記

3.1 非IE瀏覽器

  1. target 和 currentTarget 意義不同途事。 currentTarget 指的是處理這個(gè)事件的節(jié)點(diǎn)溺忧;target 指的是 觸發(fā)事件的實(shí)際目標(biāo)咏连。
  2. preventDefault 可以阻止特定事件的默認(rèn)行為。如a標(biāo)簽的跳轉(zhuǎn)鲁森,form表單的提交祟滴,復(fù)選框的選中等等。但是只有 cancelable 為true的才可以使用歌溉。
  3. stopPropagation 可以阻止事件冒泡垄懂。比如 button 和 body都有對click事件的處理程序,如果不作特殊處理痛垛,這兩個(gè)事件處理程序都會執(zhí)行草慧,而是用stopPropagation則會阻止body中事件的觸發(fā);

3.2 IE中事件對象略有不同:

  1. cancelBubble匙头,默認(rèn)值為false漫谷,將其設(shè)置為true,可阻止事件冒泡蹂析;類比stopPropagation
  2. returnValue舔示,默認(rèn)值為true,將其設(shè)置為false电抚,可以阻止事件的默認(rèn)行為惕稻;類比preventDefault
  3. IE的DOM0級事件,添加事件處理程序的時(shí)候蝙叛,event是作為window的一個(gè)屬性而存在俺祠,即需要通過window.event來獲取借帘;
  4. 如果是使用 attachEvent() 的方法添加事件處理程序蜘渣,會有一個(gè)event對象作為參數(shù)傳遞到方法中互广,同時(shí)也可以通過 window.event來獲燃绲;
  5. srcElement與DOM中的target屬性相同专缠。

備注:事件處理程序的作用域是根據(jù)指定他的方式確定的狰挡,所以不能認(rèn)為this始終等于時(shí)間目標(biāo)捂龄。還是使用 srcElement 保險(xiǎn)。

如下例:

<button id="myBtn">event</button>
<script>
    var btn = document.getElementById('myBtn');
    btn.onclick = function (){
        alert(window.event.srcElement === this); // true
    }
    btn.attachEvent('onclick',function(event){
        alert(event.srcElement === this) // false
        alert(this === window) // true
    })
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末加叁,一起剝皮案震驚了整個(gè)濱河市倦沧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌它匕,老刑警劉巖展融,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異豫柬,居然都是意外死亡告希,警方通過查閱死者的電腦和手機(jī)扑浸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燕偶,“玉大人喝噪,你說我怎么就攤上這事≈该矗” “怎么了酝惧?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長伯诬。 經(jīng)常有香客問我晚唇,道長,這世上最難降的妖魔是什么盗似? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任哩陕,我火速辦了婚禮,結(jié)果婚禮上赫舒,老公的妹妹穿的比我還像新娘悍及。我一直安慰自己,他們只是感情好号阿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布并鸵。 她就那樣靜靜地躺著鸳粉,像睡著了一般扔涧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上届谈,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天枯夜,我揣著相機(jī)與錄音,去河邊找鬼艰山。 笑死湖雹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曙搬。 我是一名探鬼主播摔吏,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纵装!你這毒婦竟也來了征讲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤橡娄,失蹤者是張志新(化名)和其女友劉穎诗箍,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽唉,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滤祖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年筷狼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片匠童。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡埂材,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俏让,到底是詐尸還是另有隱情楞遏,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布首昔,位于F島的核電站寡喝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏勒奇。R本人自食惡果不足惜预鬓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赊颠。 院中可真熱鬧格二,春花似錦、人聲如沸竣蹦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痘括。三九已至长窄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纲菌,已是汗流浹背挠日。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翰舌,地道東北人嚣潜。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像椅贱,于是被迫代替她去往敵國和親懂算。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件女器,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,474評論 1 11
  • JavaScript 程序采用了異步事件驅(qū)動編程模型酸役。在這種程序設(shè)計(jì)風(fēng)格下,當(dāng)文檔、瀏覽器涣澡、元素或與之相關(guān)的對象發(fā)...
    劼哥stone閱讀 1,252評論 3 11
  • JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的贱呐。事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特定的交互瞬...
    threetowns閱讀 339評論 0 0
  • js之事件機(jī)制 1入桂、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驅(qū)動...
    道無虛閱讀 2,338評論 1 3
  • 事件流 JavaScript與HTML之間的交互是通過事件實(shí)現(xiàn)的奄薇。事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特定的交互...
    DHFE閱讀 824評論 0 3