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 相关文章推荐
div当滚动到页面顶部的时候固定在顶部实例代码
May 27 Javascript
Windows8下搭建Node.js开发环境教程
Sep 03 Javascript
jquery简单实现网页层的展开与收缩效果
Aug 07 Javascript
jQuery.ajax 跨域请求webapi设置headers的解决方案
Aug 08 Javascript
js倒计时小实例(多次定时)
Dec 08 Javascript
Bootstrap select实现下拉框多选效果
Dec 23 Javascript
ES6使用let命令更简单的实现块级作用域实例分析
Mar 31 Javascript
JS基于正则表达式实现的密码强度验证功能示例
Sep 21 Javascript
使用async、enterproxy控制并发数量的方法详解
Jan 02 Javascript
使用socket.io实现简单聊天室案例
Jan 02 Javascript
jQuery实现DIV响应鼠标滑过由下向上展开效果示例【测试可用】
Apr 26 jQuery
js全屏事件fullscreenchange 实现全屏、退出全屏操作
Sep 17 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之数组(遍历顺序)  Laruence原创
2012/06/13 PHP
php使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
php绘图之生成饼状图的方法
2015/01/24 PHP
PHP常用字符串操作函数实例总结(trim、nl2br、addcslashes、uudecode、md5等)
2016/01/09 PHP
PHP实现二维数组中的查找算法小结
2018/06/09 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
Laravel开启跨域请求的方法
2019/10/13 PHP
select组合框option的捕捉实例代码
2008/09/30 Javascript
jquery 事件对象属性小结
2010/04/27 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
2011/04/16 Javascript
jquery 回车事件实现代码
2011/08/23 Javascript
jQuery移动和复制dom节点实用DOM操作案例
2012/12/17 Javascript
jquery动态调整div大小使其宽度始终为浏览器宽度
2014/06/06 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
基于jQuery实现的扇形定时器附源码下载
2015/10/20 Javascript
深入理解JavaScript中的块级作用域、私有变量与模块模式
2016/10/31 Javascript
jQuery中 bind的用法简单介绍
2017/02/13 Javascript
详解angularjs 关于ui-router分层使用
2017/06/12 Javascript
vue动态路由实现多级嵌套面包屑的思路与方法
2017/08/16 Javascript
js时间戳与日期格式之间相互转换
2017/12/11 Javascript
js实现直播点击飘心效果
2020/08/19 Javascript
python显示生日是星期几的方法
2015/05/27 Python
Random 在 Python 中的使用方法
2018/08/09 Python
Python enumerate函数功能与用法示例
2019/03/01 Python
使用python实现滑动验证码功能
2019/08/05 Python
Python通过kerberos安全认证操作kafka方式
2020/06/06 Python
python语言的优势是什么
2020/06/17 Python
matplotlib bar()实现百分比堆积柱状图
2021/02/24 Python
意大利简约的休闲品牌:Aspesi
2018/02/08 全球购物
100%羊绒:NakedCashmere
2020/08/26 全球购物
在子网210.27.48.21/30种有多少个可用地址?分别是什么?
2014/07/27 面试题
小学岗位竞聘方案
2014/01/22 职场文书
大学迎新生欢迎词
2015/09/29 职场文书
《月光曲》教学反思
2016/02/16 职场文书
解决Jupyter-notebook不弹出默认浏览器的问题
2021/03/30 Python
为了顺利买到演唱会的票用Python制作了自动抢票的脚本
2021/10/16 Python