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 相关文章推荐
取键盘键位ASCII码的网页
Jul 30 Javascript
js类中获取外部函数名的方法与代码
Sep 12 Javascript
JavaScript获取flash对象与网上的有所不同
Apr 21 Javascript
js星星评分效果
Jul 24 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
Sep 25 Javascript
详解javascript事件冒泡
Jan 09 Javascript
限制只能输入数字的实现代码
May 16 Javascript
JS动态添加选项案例分析
Oct 17 Javascript
js实现音乐播放控制条
Sep 09 Javascript
详解JavaScript作用域和作用域链
Mar 19 Javascript
解决vue-cli@3.xx安装不成功的问题及搭建ts-vue项目
Feb 09 Javascript
OpenLayers3实现地图显示功能
Sep 25 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缩略图等比例无损压缩,可填充空白区域补充色
2011/06/10 PHP
php入门学习知识点四 PHP正则表达式基本应用
2011/07/14 PHP
PHP封装分页函数实现文本分页和数字分页
2014/10/23 PHP
php.ini中的request_order推荐设置
2015/05/10 PHP
php生成高清缩略图实例详解
2015/12/07 PHP
PHP7之Mongodb API使用详解
2015/12/26 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
2016/10/18 PHP
Laravel构建即时应用的一种实现方法详解
2017/08/31 PHP
javascript 设计模式之单体模式 面向对象学习基础
2010/04/18 Javascript
JavaScript 开发规范要求(图文并茂)
2010/06/11 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
js弹出模式对话框,并接收回传值的方法
2013/03/12 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
Angularjs中使用Filters详解
2016/03/11 Javascript
NodeJS遍历文件生产文件列表功能示例
2017/01/22 NodeJs
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
利用Webpack实现小程序多项目管理的方法
2019/02/25 Javascript
使用jquery实现轮播图效果
2021/01/02 jQuery
跟老齐学Python之Python文档
2014/10/10 Python
详解Django中的ifequal和ifnotequal标签使用
2015/07/16 Python
Python基于identicon库创建类似Github上用的头像功能
2017/09/25 Python
Python实现的质因式分解算法示例
2018/05/03 Python
修改python plot折线图的坐标轴刻度方法
2018/12/13 Python
详解python的argpare和click模块小结
2019/03/31 Python
浅析Python 简单工厂模式和工厂方法模式的优缺点
2020/07/13 Python
详解python的super()的作用和原理
2020/10/29 Python
用gpu训练好的神经网络,用tensorflow-cpu跑出错的原因及解决方案
2021/03/03 Python
详解Html5 Canvas画线有毛边解决方法
2018/03/01 HTML / CSS
迪梵英国官方网站:Darphin英国
2017/12/06 全球购物
Nili Lotan官网:Nili Lotan同名品牌
2018/01/07 全球购物
擅自离岗检讨书
2014/02/11 职场文书
学校爱国卫生月活动总结
2014/06/25 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书
毕业生就业推荐表自我评价
2015/03/02 职场文书
详解python网络进程
2021/06/15 Python
python可视化分析绘制带趋势线的散点图和边缘直方图
2022/06/25 Python