js使用函数绑定技术改变事件处理程序的作用域


Posted in Javascript onDecember 26, 2011

第一种,也是 最常见的,就是直接在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>

js使用函数绑定技术改变事件处理程序的作用域
通过以上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对象下面。

js使用函数绑定技术改变事件处理程序的作用域

在前面介绍的通过绑定函数注册事件是为元素对象创建了一个事件的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; 
} 
} 
} 
}

到这里就介绍完了使用函数绑定技术注册特定执行环境的事件处理程序。同样,利用函数绑定还能使回调函数在给定的执行环境里面执行。

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Javascript 相关文章推荐
jQuery Validation实例代码 让验证变得如此容易
Oct 18 Javascript
jQuery 表单验证扩展(四)
Oct 20 Javascript
JavaScript表达式:URL 协议介绍
Mar 10 Javascript
JS建造者模式基本用法实例分析
Jun 30 Javascript
js,jq,css多方面实现简易下拉菜单功能
May 13 Javascript
详解jQuery中的isPlainObject()使用方法
Feb 27 jQuery
vue和webpack项目构建过程常用的npm命令详解
Jun 15 Javascript
浅析vue.js数组的变异方法
Jun 30 Javascript
D3.js实现拓扑图的示例代码
Jun 30 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
Node.js EventEmmitter事件监听器用法实例分析
Jan 07 Javascript
ES6扩展运算符和rest运算符用法实例分析
May 23 Javascript
JavaScript中的property和attribute介绍
Dec 26 #Javascript
JavaScript打字小游戏代码
Dec 26 #Javascript
js bind 函数 使用闭包保存执行上下文
Dec 26 #Javascript
js 函数调用模式小结
Dec 26 #Javascript
JavaScript 原型继承
Dec 26 #Javascript
jquery事件机制扩展插件 jquery鼠标右键事件。
Dec 26 #Javascript
查看源码的工具 学习jQuery源码不错的工具
Dec 26 #Javascript
You might like
用PHP实现验证码功能
2006/10/09 PHP
一个MYSQL操作类
2006/11/16 PHP
php从数据库中获取数据用ajax传送到前台的方法
2018/08/20 PHP
PHP children()函数讲解
2019/02/03 PHP
利用NodeJS和PhantomJS抓取网站页面信息以及网站截图
2013/11/18 NodeJs
js实现进度条的方法
2015/02/13 Javascript
jquery实现用户打分评分特效
2015/05/28 Javascript
JS实现动态表格的添加,修改,删除功能(推荐)
2016/06/15 Javascript
JS实用技巧小结(屏蔽错误、div滚动条设置、背景图片位置等)
2016/06/16 Javascript
jQuery获取radio选中项的值实例
2016/06/18 Javascript
Jq通过td获取同行其它列td的方法
2016/10/05 Javascript
React Native如何消除启动时白屏的方法
2017/08/08 Javascript
swiper动态改变滑动内容的实现方法
2018/01/17 Javascript
彻底揭秘keep-alive原理(小结)
2019/05/05 Javascript
[01:53]DOTA2超级联赛专访Zhou 五年职业青春成长
2013/05/29 DOTA
python实现得到一个给定类的虚函数
2014/09/28 Python
在Python的Django框架中实现Hacker News的一些功能
2015/04/17 Python
Python中http请求方法库汇总
2016/01/06 Python
Python实现读写INI配置文件的方法示例
2018/06/09 Python
python和opencv实现抠图
2018/07/18 Python
Python使用googletrans报错的解决方法
2018/09/25 Python
Python经典五人分鱼实例讲解
2021/01/04 Python
巴西最大的玩具连锁店:Ri Happy
2020/06/17 全球购物
PHP两种查询函数array/row的区别
2013/06/03 面试题
联想C++笔试题
2012/06/13 面试题
家具促销活动方案
2014/02/16 职场文书
升国旗仪式主持词
2014/03/19 职场文书
个人委托书怎么写
2014/04/04 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
学校创先争优活动总结
2014/08/28 职场文书
个人先进事迹材料范文
2014/12/29 职场文书
综合素质评价个性与发展自我评价
2015/03/06 职场文书
爱岗敬业先进典型事迹材料(2016推荐版)
2016/02/26 职场文书
创业计划书之都市休闲农庄
2019/12/28 职场文书
pycharm无法导入lxml的解决办法
2021/03/31 Python
Django分页器的用法你都了解吗
2021/05/26 Python