DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> js使用函數綁定技術改變事件處理程序的作用域
js使用函數綁定技術改變事件處理程序的作用域
編輯:關於JavaScript     
第一種,也是 最常見的,就是直接在html標簽裡面通過指定事件處理程序同名的HTML屬性來注冊事件,代碼如下:
復制代碼 代碼如下:
function eventHandler() {
alert("當前作用域是 input 元素本身");
}
<input type="button" value="單擊我" onclick="eventHandler(this)"/>

第二種方式就是將一個函數賦值給一個事件處理程序屬性。這種方式首先的獲取到這個元素對象,一般代碼如下:
復制代碼 代碼如下:
<input id="myEventHandlerScope" type="button" value="單擊我"/>
<script type="text/javascript">
function eventHandler() {
alert("當前作用域是 input 元素本身");
}
var mybtn = document.getElementById("myEventHandlerScope");
mybtn.onclick = eventHandler;
</script>

第三種方式,就是理由DOM2級別的事件處理方法 addEventListener和removeEventListener,針對ie浏覽器對應的方法是attachEvent 和 detachEvent。注冊事件的代碼如下:
復制代碼 代碼如下:
<input id="myEventHandlerScope" type="button" value="單擊我"/>
<script type="text/javascript">
//定義一個注冊事件的方法
function addHandler(obj, type, handler) {
if (obj.addEventListener) {
obj.addEventListener(type, handler, false);
} else if (obj.attachEvent) {
obj.attachEvent("on" + type, handler);
} else {
obj["on" + type] = handler;
}
}
function eventHandler() {
alert("當前作用域是 input 元素本身");
}
var mybtn = document.getElementById("myEventHandlerScope");
addHandler(mybtn,'click',eventHandler);//為對象注冊事件
</script>

input對象的Click事件執行環境截圖
通過以上3種方式為input元素注冊一個 click 事件處理程序都有一個缺點就是這個處理程序的作用域(this)始終處於input對象。在面向對象編程的時候,就需要明確的指定this在特定的作用域下面。 為了改變this的作用域,就得用到js的一種綁定函數技術。
所謂“綁定函數”就是要創建一個函數,可以在特定環境中以指定參數調用另一個函數,他能很好的與事件處理程序一起使用,以便在將函數作為變量傳遞的同時保持函數的作用域(也是this的執行環境)。綁定函數的定義形式如下代碼:
復制代碼 代碼如下:
function bind(fn,scope) {
return fn.apply(scope||this,arguments);
}

這個綁定函數接受兩個參數,第一個是需要執行的函數,第二個是特定的執行環境,並返回一個在給定作用域中調用給定函數,並將所有參數一同傳遞過去。利用綁定函數技術和DOM2級的事件處理程序就能很好的為元素注冊一個在特定作用域下執行的事件處理函數。具體的處理方式如下:
首先修改先前定義的注冊事件的方法如下代碼:
復制代碼 代碼如下:
function addHandler(obj, type, handler, scope) {
function fn(event) {
var evt = event ? event : window.event;
evt.target = event.target || event.srcElement;
return handler.apply(scope || this,arguments);
}
obj.eventHash = obj.eventHash || {};//這裡為需要注冊事件處理程序的對象定義一個保存事件的hash對象,並把事件處理程序和作用域保存在該事件類型的隊列裡面
(obj.eventHash [type] = obj.eventHash [type] || []).push({ "name": type, "handler": handler, "fn": fn, "scope": scope });
if (obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj.attachEvent) {
obj.attachEvent("on" + type, fn);
} else {
obj["on" + type] = fn;
}
}

使用修改後的注冊事件方法就可以使元素的事件處理程序在指定的環境裡面執行了。
復制代碼 代碼如下:
<input id="myEventHandlerScope" type="button" value="單擊我"/>
<script type="text/javascript">
function eventHandler() {
this;
alert("當前作用域是 window 元素本身");
}
var mybtn = document.getElementById("myEventHandlerScope");
addHandler(mybtn, 'click', eventHandler,window);
</script>

執行上面這段代碼,處理程序eventHandler的this作用域就處在了window對象下面。

this在window對象下的執行環境截圖

在前面介紹的通過綁定函數注冊事件是為元素對象創建了一個事件的hash對象用來保存事件處理程序,這個hash對象在元素移除事件處理程序的時候起到了非常總要左右,根據他就能准確的移除對應的事件處理程序。移除事件處理程序的代碼如下:
復制代碼 代碼如下:
function removeHandler (obj, type, handler, scope) {
obj.eventHash = obj.eventHash || {};
var evtList = obj.eventHash [type] || [], len = evtList.length;
if (len > 0) {
for (; len--; ) {
var curEvtObj = evtList[len];
if (curEvtObj.name == type && curEvtObj.handler === handler && curEvtObj.scope === scope) {
if (obj.removeEventListener) {
obj.removeEventListener(type, curEvtObj.fn, false);
} else if (obj.detachEvent) {
obj.detachEvent("on" + type, curEvtObj.fn);
} else {
obj["on" + type] = null;
}
evtList.splice(len, 1);
break;
}
}
}
}

到這裡就介紹完了使用函數綁定技術注冊特定執行環境的事件處理程序。同樣,利用函數綁定還能使回調函數在給定的執行環境裡面執行。

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved