js使用函數(shù)綁定技術(shù)改變事件處理程序的作用域
function eventHandler() {
alert("當(dāng)前作用域是 input 元素本身");
}
<input type="button" value="單擊我" onclick="eventHandler(this)"/>
第二種方式就是將一個(gè)函數(shù)賦值給一個(gè)事件處理程序?qū)傩?。這種方式首先的獲取到這個(gè)元素對(duì)象,一般代碼如下:
<input id="myEventHandlerScope" type="button" value="單擊我"/>
<script type="text/javascript">
function eventHandler() {
alert("當(dāng)前作用域是 input 元素本身");
}
var mybtn = document.getElementById("myEventHandlerScope");
mybtn.onclick = eventHandler;
</script>
第三種方式,就是理由DOM2級(jí)別的事件處理方法 addEventListener和removeEventListener,針對(duì)ie瀏覽器對(duì)應(yīng)的方法是attachEvent 和 detachEvent。注冊(cè)事件的代碼如下:
<input id="myEventHandlerScope" type="button" value="單擊我"/>
<script type="text/javascript">
//定義一個(gè)注冊(cè)事件的方法
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("當(dāng)前作用域是 input 元素本身");
}
var mybtn = document.getElementById("myEventHandlerScope");
addHandler(mybtn,'click',eventHandler);//為對(duì)象注冊(cè)事件
</script>

通過(guò)以上3種方式為input元素注冊(cè)一個(gè) click 事件處理程序都有一個(gè)缺點(diǎn)就是這個(gè)處理程序的作用域(this)始終處于input對(duì)象。在面向?qū)ο缶幊痰臅r(shí)候,就需要明確的指定this在特定的作用域下面。 為了改變this的作用域,就得用到j(luò)s的一種綁定函數(shù)技術(shù)。
所謂“綁定函數(shù)”就是要?jiǎng)?chuàng)建一個(gè)函數(shù),可以在特定環(huán)境中以指定參數(shù)調(diào)用另一個(gè)函數(shù),他能很好的與事件處理程序一起使用,以便在將函數(shù)作為變量傳遞的同時(shí)保持函數(shù)的作用域(也是this的執(zhí)行環(huán)境)。綁定函數(shù)的定義形式如下代碼:
function bind(fn,scope) {
return fn.apply(scope||this,arguments);
}
這個(gè)綁定函數(shù)接受兩個(gè)參數(shù),第一個(gè)是需要執(zhí)行的函數(shù),第二個(gè)是特定的執(zhí)行環(huán)境,并返回一個(gè)在給定作用域中調(diào)用給定函數(shù),并將所有參數(shù)一同傳遞過(guò)去。利用綁定函數(shù)技術(shù)和DOM2級(jí)的事件處理程序就能很好的為元素注冊(cè)一個(gè)在特定作用域下執(zhí)行的事件處理函數(shù)。具體的處理方式如下:
首先修改先前定義的注冊(cè)事件的方法如下代碼:
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 || {};//這里為需要注冊(cè)事件處理程序的對(duì)象定義一個(gè)保存事件的hash對(duì)象,并把事件處理程序和作用域保存在該事件類(lèi)型的隊(duì)列里面
(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;
}
}
使用修改后的注冊(cè)事件方法就可以使元素的事件處理程序在指定的環(huán)境里面執(zhí)行了。
<input id="myEventHandlerScope" type="button" value="單擊我"/>
<script type="text/javascript">
function eventHandler() {
this;
alert("當(dāng)前作用域是 window 元素本身");
}
var mybtn = document.getElementById("myEventHandlerScope");
addHandler(mybtn, 'click', eventHandler,window);
</script>
執(zhí)行上面這段代碼,處理程序eventHandler的this作用域就處在了window對(duì)象下面。

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;
}
}
}
}
到這里就介紹完了使用函數(shù)綁定技術(shù)注冊(cè)特定執(zhí)行環(huán)境的事件處理程序。同樣,利用函數(shù)綁定還能使回調(diào)函數(shù)在給定的執(zhí)行環(huán)境里面執(zhí)行。
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
- 深入Javascript函數(shù)、遞歸與閉包(執(zhí)行環(huán)境、變量對(duì)象與作用域鏈)使用詳解
- javascript 函數(shù)及作用域總結(jié)介紹
- 關(guān)于javascript 回調(diào)函數(shù)中變量作用域的討論
- js 函數(shù)的執(zhí)行環(huán)境和作用域鏈的深入解析
- js函數(shù)內(nèi)變量的作用域分析
- JavaScript匿名函數(shù)之模仿塊級(jí)作用域
- javascript函數(shù)作用域?qū)W習(xí)示例(js作用域)
- javascript的函數(shù)作用域
- 淺談JavaScript的函數(shù)及作用域
- JavaScript函數(shù)作用域鏈分析
- 詳談JavaScript 匿名函數(shù)及閉包
- JavaScript 函數(shù)用法詳解【函數(shù)定義、參數(shù)、綁定、作用域、閉包等】
相關(guān)文章
使用原生js實(shí)現(xiàn)頁(yè)面蒙灰(mask)效果示例代碼
像js的框架Extjs的mask()和unmask()功能提供了蒙灰效果,當(dāng)然jquery也提供了這種蒙灰方法,下面有個(gè)示例,大家可以參考下2014-06-06
詳解bootstrap導(dǎo)航欄.nav與.navbar區(qū)別
本篇文章主要介紹了詳解bootstrap導(dǎo)航欄.nav與.navbar區(qū)別,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
JS字節(jié)數(shù)組轉(zhuǎn)數(shù)字及數(shù)字轉(zhuǎn)字節(jié)數(shù)組的方法
本文將深入解析長(zhǎng)整數(shù)與字節(jié)數(shù)組互轉(zhuǎn)的技術(shù)原理,提供ES6(現(xiàn)代瀏覽器/Node.js)與ES5(兼容舊環(huán)境)兩套實(shí)現(xiàn)方案,感興趣的朋友一起看看吧2025-04-04
JavaScript實(shí)現(xiàn)維吉尼亞(Vigenere)密碼算法實(shí)例
Vigenere密碼就是一種傳統(tǒng)加密技術(shù),它是多表代換密碼,能夠有效改進(jìn)單表代換密碼的詞頻分布特征問(wèn)題,本文用JavaScript實(shí)現(xiàn)維吉尼亞(Vigenere)密碼算法2013-11-11

