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 相关文章推荐
自己的js工具 Event封装
Aug 21 Javascript
jQuery学习笔记(2)--用jquery实现各种模态提示框代码及项目构架
Apr 08 Javascript
点击显示指定元素隐藏其他同辈元素的方法
Feb 19 Javascript
利用JS实现点击按钮后图片自动切换的简单方法
Oct 24 Javascript
js自定义QQ菜单效果
Jan 10 Javascript
ES6新增数据结构WeakSet的用法详解
Aug 07 Javascript
纯JS实现的读取excel文件内容功能示例【支持所有浏览器】
Jun 23 Javascript
vue使用原生js实现滚动页面跟踪导航高亮的示例代码
Oct 25 Javascript
Node.js 的 GC 机制详解
Jun 03 Javascript
JavaScript进阶(二)词法作用域与作用域链实例分析
May 09 Javascript
vue自定义指令和动态路由实现权限控制
Aug 28 Javascript
vue2.0 watch里面的 deep和immediate用法说明
Oct 30 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
JavaScript网页制作特殊效果用随机数
2007/05/22 Javascript
JS判断不同分辨率调用不同的CSS样式文件实现思路及测试代码
2013/01/23 Javascript
QQ空间顶部折页撕开效果示例代码
2014/06/15 Javascript
JavaScript数组前面插入元素的方法
2015/04/06 Javascript
javascript中JSON对象与JSON字符串相互转换实例
2015/07/11 Javascript
JS实现下拉菜单赋值到文本框的方法
2015/08/18 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
详解JavaScript函数对象
2015/11/15 Javascript
解决WordPress使用CDN后博文无法评论的错误
2015/12/15 Javascript
jquery对复选框(checkbox)的操作汇总
2016/01/13 Javascript
Laravel中常见的错误与解决方法小结
2016/08/30 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
AngularJS辅助库browserTrigger用法示例
2016/11/03 Javascript
JavaScript如何一次性展示几万条数据
2017/03/30 Javascript
详解基于Koa2开发微信二维码扫码支付相关流程
2018/05/16 Javascript
利用Angular2的Observables实现交互控制的方法
2018/12/27 Javascript
详解滑动穿透(锁body)终极探索
2019/04/16 Javascript
Layui点击图片弹框预览的实现方法
2019/09/16 Javascript
layui动态渲染生成select的option值方法
2019/09/23 Javascript
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
实例讲解python中的序列化知识点
2018/10/08 Python
Python代码打开本地.mp4格式文件的方法
2019/01/03 Python
python如何获取列表中每个元素的下标位置
2019/07/01 Python
python移位运算的实现
2019/07/15 Python
django中账号密码验证登陆功能的实现方法
2019/07/15 Python
python中的subprocess.Popen()使用详解
2019/12/25 Python
Python Merge函数原理及用法解析
2020/09/16 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
MATCHESFASHION.COM法国官网:英国奢侈品零售商
2018/01/04 全球购物
风险评估实施方案
2014/03/09 职场文书
“向国旗敬礼”主题班会活动设计方案
2014/09/27 职场文书
党员作风建设自查报告
2014/10/23 职场文书
2016春节家属慰问信
2015/03/25 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
2019年最新证婚词精选集!
2019/06/28 职场文书
python实现图片批量压缩
2021/04/24 Python