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 相关文章推荐
parseInt parseFloat js字符串转换数字
Aug 01 Javascript
基于JQuery的简单实现折叠菜单代码
Sep 15 Javascript
JavaScript中数组对象的那些自带方法介绍
Mar 12 Javascript
JS中的this变量的使用介绍
Oct 21 Javascript
简介JavaScript中的getUTCFullYear()方法的使用
Jun 10 Javascript
jquery二级目录选中当前页的css样式
Dec 08 Javascript
jQuery读取本地的json文件(实例讲解)
Oct 31 jQuery
详解最新vue-cli 2.9.1的webpack存在问题
Dec 16 Javascript
Vue的土著指令和自定义指令实例详解
Feb 04 Javascript
JavaScript指定断点操作实例教程
Sep 18 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
May 28 jQuery
vue 解除鼠标的监听事件的方法
Nov 13 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检查字符串中是否包含7位GSM字符的方法
2015/03/17 PHP
PHP中实现crontab代码分享
2015/03/26 PHP
(仅IE下有效)关于checkbox 三态
2007/05/12 Javascript
javascript flash下fromCharCode和charCodeAt方法使用说明
2008/01/12 Javascript
Firefox和IE浏览器兼容JS脚本写法小结
2008/07/07 Javascript
javascript 获取元素位置的快速方法 getBoundingClientRect()
2009/11/26 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
json格式的时间显示为正常年月日的方法
2013/09/08 Javascript
js模仿hover的具体实现代码
2013/12/30 Javascript
JQuery中DOM事件绑定用法详解
2015/06/13 Javascript
BootStrap便签页的简单应用
2017/01/06 Javascript
jQuery实现搜索页面关键字的功能
2017/02/16 Javascript
JS装饰器函数用法总结
2018/04/21 Javascript
浅析JS中回调函数及用法
2018/07/25 Javascript
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
详解Vue组件插槽的使用以及调用组件内的方法
2018/11/13 Javascript
让 babel webpack vue 配置文件支持智能提示的方法
2019/06/22 Javascript
JS前端知识点总结之内置对象,日期对象和定时器相关操作
2019/07/05 Javascript
layui 弹出层值回传解决方式
2019/11/14 Javascript
[04:26]2014DOTA2国际邀请赛-Newbee顺利进入胜者组决赛 独家专访战神7
2014/07/19 DOTA
给Python初学者的一些编程技巧
2015/04/03 Python
在Django框架中编写Contact表单的教程
2015/07/17 Python
Python中序列的修改、散列与切片详解
2017/08/27 Python
itchat接口使用示例
2017/10/23 Python
python用plt画图时,cmp设置方法
2018/12/13 Python
tensor和numpy的互相转换的实现示例
2019/08/02 Python
Python中无限循环需要什么条件
2020/05/27 Python
Win10下配置tensorflow-gpu的详细教程(无VS2015/2017)
2020/07/14 Python
全面介绍python中很常用的单元测试框架unitest
2020/12/14 Python
CSS3 translate导致字体模糊的实例代码
2019/08/30 HTML / CSS
英国轻奢珠宝品牌:Astley Clarke
2016/12/18 全球购物
Tretorn美国官网:瑞典外套和鞋类品牌,抵御风雨
2018/07/19 全球购物
法国在线药房:DoctiPharma
2020/10/21 全球购物
打架检讨书范文
2015/01/27 职场文书
学期个人工作总结
2015/02/13 职场文书
Redis性能监控的实现
2021/07/09 Redis