JavaScript常見(jiàn)事件處理程序?qū)嵗偨Y(jié)
本文實(shí)例總結(jié)了JavaScript常見(jiàn)事件處理程序。分享給大家供大家參考,具體如下:
事件指的是使用者或者瀏覽器自身執(zhí)行的某種動(dòng)作(比如點(diǎn)擊事件)。響應(yīng)這些事件的函數(shù)就叫做事件處理程序(或者叫事件監(jiān)聽(tīng)器)。事件處理程序的名字以“on”為前綴,比如 click 事件的事件處理程序就是 onclick。
1 HTML 事件處理程序
如果某個(gè)元素支持某個(gè)事件,那么它都有一個(gè)與相應(yīng)的事件處理程序同名的 HTML 屬性,我們可以通過(guò)這個(gè)屬性來(lái)指定 JS:
<input type="button" value="點(diǎn)我" onclick="alert('點(diǎn)擊過(guò)咯')"/>
因?yàn)檫@里的腳本是嵌入在 HTML 元素的屬性中,所以使用了單引號(hào)!
也可以調(diào)用在頁(yè)面的其他地方定義的腳本:
<input type="button" value="Click me" onclick="showMessage()"> <script type="text/javascript"> function showMessage() { console.log("Hello World!"); } </script>
事件處理程序的代碼在執(zhí)行時(shí),可以訪問(wèn)到全局作用域中的任何代碼!
這樣指定的事件處理程序,會(huì)創(chuàng)建一個(gè)封裝著元素屬性值的函數(shù),它有一個(gè)局部變量 event,就是事件對(duì)象:
<input type="button" value="點(diǎn)我" onclick="alert(event.type)"/>
通過(guò) event 變量,可以直接訪問(wèn)事件對(duì)象。在這個(gè)函數(shù)內(nèi)部,this 值等于事件的目標(biāo)元素:
<input type="button" value="點(diǎn)我" onclick="alert(this.value)"/>
可以通過(guò)這個(gè)動(dòng)態(tài)創(chuàng)建的函數(shù),來(lái)擴(kuò)展它的作用域。在這個(gè)函數(shù)內(nèi)部,可以訪問(wèn) document 以及該元素本身的成員,這個(gè)函數(shù)是像這樣使用 with 來(lái)擴(kuò)展作用域的:
function(){ with(document){ with(this){ //元素屬性值 } } }
所以,在事件處理程序中,要訪問(wèn)自己的屬性就變得很容易啦 O(∩_∩)O~:
<!-- 輸出 “點(diǎn)我” --> <input type="button" value="點(diǎn)我" onclick="alert(value)"/>
如果當(dāng)前元素是一個(gè)表單輸入元素,則作用域中還會(huì)包含訪問(wèn)表單元素(父元素)的入口,所以這個(gè)函數(shù)應(yīng)該是這樣的:
function(){ with(document){ with(this.form){ with(this){ //元素屬性值 } } } }
這樣事件處理程序就無(wú)需引用表單元素,就可以直接訪問(wèn)到表單中的其他字段啦O(∩_∩)O~:
<form method="post"> <input type="text" name="username" value=""> <input type="button" value="Echo Usernmame" onclick="console.log(username.value);"> </form>
在 HTML 中直接指定事件處理程序會(huì)有這些缺點(diǎn):
- 時(shí)差問(wèn)題——假設(shè)函數(shù)是定義在頁(yè)面最底部,如果用戶在頁(yè)面還未解析到這個(gè)函數(shù)時(shí),就點(diǎn)擊了按鈕,就會(huì)引發(fā)錯(cuò)誤。所以很多 HTML 事件處理程序都會(huì)被封裝在 try-catch 塊中:
<input type="button" value="點(diǎn)我" onclick="try{alert(value);} catch(ex){}"/>
- 擴(kuò)展事件處理程序的作用域鏈,在不同的瀏覽器中結(jié)果可能會(huì)不同。
- HTML 與 JavaScript 代碼緊密耦合。要修改事件處理程序,就需要修改兩個(gè)地方,所以很多開(kāi)發(fā)人員轉(zhuǎn)而使用 JavaScript 來(lái)指定事件處理程序。
2 DOM0 級(jí)事件處理程序
它是通過(guò)將一個(gè)函數(shù)賦值給事件處理程序的屬性,來(lái)指定事件處理程序的。要使用這種方法,必須先取得一個(gè)要操作的對(duì)象的引用。
每個(gè)元素(包括 window 和 document) 都有自己的事件處理程序?qū)傩?,它們通常是小?xiě),比如 onclick。將屬性的值設(shè)置為函數(shù),就指定了事件處理程序。
DOM0 級(jí)事件處理程序是元素的方法,它是在元素的作用域內(nèi)運(yùn)行的,因此程序中的 this 引用的是當(dāng)前元素:
<button id="myBtn">點(diǎn)我</button> <script type="text/javascript"> var btn = document.getElementById("myBtn"); btn.onclick = function () { console.log(this.id);//myBtn } </script>
可以通過(guò) this 訪問(wèn)元素的任何屬性和方法。DOM0 級(jí)事件處理程序會(huì)在事件流的冒泡階段被處理。
也可以像這樣刪除這樣指定的事件處理程序:
btn.onclick = null; //刪除指定的事件處理程序
注意: 如果使用的是 HTML 指定的事件處理程序,那么 onclick 屬性的值就是一個(gè)包含著在同名 HTML 特性中指定的代碼函數(shù)。將相應(yīng)的屬性設(shè)置為 null,也可以刪除以這種方式指定的事件處理程序。
3 DOM2 級(jí)事件處理程序
- addEventListener():指定事件處理程序。
- removeEventListener():刪除事件處理程序。
所有的 DOM 節(jié)點(diǎn)都包含這兩個(gè)方法。它們都接受 3 個(gè)參數(shù):要處理的事件名、事件處理程序函數(shù)、布爾值。最后一個(gè)參數(shù)如果是 true,表示在捕獲階段調(diào)用事件處理程序;如果是 false,表示在冒泡階段調(diào)用事件處理程序。
DOM2 級(jí)事件處理程序可以很方便地添加多個(gè)事件處理程序:
var btn = document.getElementById("myBtn"); btn.addEventListener("click", function () { console.log(this.id); }, false); btn.addEventListener("click", function () { console.log("Hello world!"); }, false);
這些事件處理程序會(huì)按照添加它們的順序依序觸發(fā)。
通過(guò) addEventListener()
添加的事件處理程序只能使用 removeEventListener()
移除!移除時(shí)傳入的參數(shù)必須與添加時(shí)的參數(shù)相同。這也就意味著通過(guò) addEventListener()
添加的匿名函數(shù)將無(wú)法被移除:
var handler = function () { console.log("Hi deniro"); }; btn.addEventListener("click", handler, false); btn.removeEventListener("click", handler, false);//移除成功
大多數(shù)情況下,都是將事件處理程序添加到事件流的冒泡階段,這樣可以最大限度地兼容瀏覽器。所以如果不是特別需要,請(qǐng)不要在事件捕獲階段注冊(cè)事件處理程序。
注意: IE9、Firefox、Safari、Chrome 和 Opera 支持 DOM2 級(jí)事件處理程序。
4 IE 事件處理程序
IE 實(shí)現(xiàn)了與 DOM 類(lèi)似的方法:attachEvent()
和 detachEvent()
。它們接受兩個(gè)參數(shù):事件處理程序名稱和事件處理程序函數(shù)。因?yàn)?IE8 及早期版本只支持事件冒泡,所以使用 attachEvent()
添加的事件處理程序會(huì)被添加到冒泡階段。
這樣為按鈕添加一個(gè)事件處理程序:
var btn = document.getElementById("myBtn"); btn.attachEvent("onclick", function () { });
IE 的 attachEvent()
與 DOM0 級(jí)方法的區(qū)別是事件處理程序的作用域不同。 DOM0 級(jí)方法中,事件處理程序會(huì)在其所屬元素的作用域內(nèi)運(yùn)行;而使用 attachEvent()
,事件處理程序會(huì)在全局作用域中運(yùn)行,所以 this 等于 window:
var btn = document.getElementById("myBtn"); btn.attachEvent("onclick", function () { console.log("Clicked"); console.log(this === window);//true;this 為全局作用域 });
也可以為一個(gè)元素添加多個(gè)事件處理程序:
var btn = document.getElementById("myBtn"); btn.attachEvent("onclick", function () { console.log("Clicked"); console.log(this === window);//true;this 為全局作用域 }); //IE10 中多個(gè)事件是按照事件定義的順序執(zhí)行 btn.attachEvent("onclick", function () { console.log("Hello world!"); });
IE8 及之前的版本,是以添加它們的相反順序進(jìn)行,IE9 修復(fù)了這個(gè)問(wèn)題。
可以通過(guò) detachEvent()
來(lái)移除添加的事件處理程序,但必須提供相同的參數(shù)。所以它也不能移除之前通過(guò)匿名函數(shù)添加的事件處理程序。只要能夠?qū)?duì)相同函數(shù)的引用作為參數(shù),就可以移除添加的事件處理程序咯:
<button id="myBtn">點(diǎn)我</button> <script type="text/javascript"> var btn = document.getElementById("myBtn"); var handler = function () { console.log("Clicked"); } btn.attachEvent("onclick", handler); btn.detachEvent("onclick", handler); </script>
注意: IE 和 Opera 支持 IE 事件處理程序。
5 跨瀏覽器的事件處理程序
只要恰當(dāng)?shù)剡\(yùn)用能力檢測(cè),就能寫(xiě)出跨瀏覽器的事件處理程序。
var EventUtil = { /** * 添加事件 * @param element 要操作的元素 * @param type 事件名稱 * @param handler 事件處理函數(shù) */ addHandler: function (element, type, handler) { if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } }, /** * 移除事件 * @param element 要操作的元素 * @param type 事件名稱 * @param handler 事件處理函數(shù) */ 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; } } }
這樣使用:
<button id="myBtn">點(diǎn)我</button> <script type="text/javascript" src="EventUtil.js"/> <script type="text/javascript"> var btn = document.getElementById("myBtn"); var handler = function () { console.log("Clicked"); } EventUtil.addHandler(btn, "click", handler); EventUtil.removeHandler(btn, "click", handler); </script>
還有一點(diǎn),DOM0 級(jí)對(duì)每一個(gè)事件只支持一個(gè)事件處理程序,好在現(xiàn)在只支持 DOM0 級(jí)事件處理程序的瀏覽器幾乎已經(jīng)沒(méi)有咯,所以不用擔(dān)心啦 O(∩_∩)O~
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《JavaScript事件相關(guān)操作與技巧大全》、《JavaScript操作DOM技巧總結(jié)》、《JavaScript頁(yè)面元素操作技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- JavaScript中的事件處理程序
- JS事件流與事件處理程序?qū)嵗治?/a>
- JavaScript事件處理程序詳解
- 深入理解在JS中通過(guò)四種設(shè)置事件處理程序的方法
- JavaScript的事件代理和委托實(shí)例分析
- js中的事件委托或是事件代理使用詳解
- JavaScript事件代理和委托詳解
- js事件委托和事件代理案例分享
- JavaScript通過(guò)事件代理高亮顯示表格行的方法
- JS實(shí)現(xiàn)為動(dòng)態(tài)添加的元素增加事件功能示例【基于事件委托】
- javascript事件委托的方式綁定詳解
- JS事件處理機(jī)制及事件代理(事件委托)實(shí)例詳解
相關(guān)文章
javascript字符串循環(huán)匹配實(shí)例分析
這篇文章主要介紹了javascript字符串循環(huán)匹配,實(shí)例分析三種常用的字符串循環(huán)匹配的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07Javascript正則控制文本框只能輸入整數(shù)或浮點(diǎn)數(shù)
這篇文章主要介紹Javascript正則如何控制文本框只能輸入整數(shù)或浮點(diǎn)數(shù),需要的朋友可以參考下2014-09-09Bootstrap導(dǎo)航條學(xué)習(xí)使用(一)
這篇文章主要為大家詳細(xì)介紹了Bootstrap導(dǎo)航條的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02