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

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


通过以上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对象下面。

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

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

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

(0)

相关推荐

  • javascript 基础篇3 类,回调函数,内置对象,事件处理

    复制代码 代码如下: function 类名(参数表){ this.属性; ...... this.函数; } 这样,函数和数据成员都是用"this."来实现. 我们自己定义一个简单类student好了,然后再去构造它,并且实现一个输出函数. 复制代码 代码如下: <script LANGUAGE="JavaScript"> <!-- function student(a,b){ this.name = a; this.age=b; this.ou

  • JavaScript事件处理的方式(三种)

    最近这段时间因为每天要修改网站,为网站做特效,所以看了很多的js接触事件,自己只会使用一小部分,有时用的时候也比较混乱,现在系统的整理了一下,特此分享到我们平台供大家参考下! 一.什么是JavaScript事件? 事件(Event)是JavaScript应用跳动的心脏,也是把所有东西粘在一起的胶水,当我们与浏览器中Web页面进行某些类型的交互时,事件就发生了. 事件可能是用户在某些内容上的点击.鼠标经过某个特定元素或按下键盘上的某些按键,事件还可能是Web浏览器中发生的事情,比如说某个Web页面

  • JavaScript事件处理器中的event参数使用介绍

    在大部分浏览器中,当一个事件处理器被触发时,名为Event的类实例会作为第一个参数传入处理器中.而一直占据主流地位的ie却以自己专的方式行事,将Event实例保存到一个名为event的全局属性中. 复制代码 代码如下: if (!event) event=window.event; 上面的语句用来检测event参数是否为undefined或者null,如果是的话把window的event属性赋值给它,从而消除了浏览器差异. 为了获取目标元素的引用,在标准兼容的浏览器中使用target属性,在ie

  • Ext javascript建立超链接,进行事件处理的实现方法

    1,如何在javasript建立超链接 <script type="text/JavaScript"> //方法一: location.href='网址'; //方法二: document.write('<a href="网址">文字</a>'); </script> 2,应用到Ext中的树控件事件处理 tree_03.js 复制代码 代码如下: Ext.onReady(function(){ var root = n

  • 浅谈Javascript事件处理程序的几种方式

    事件就是用户或浏览器自身执行的某种动作.比如说click,mouseover,都是事件的名字.而相应某个事件的函数就叫事件处理程序(或事件侦听器).为事件指定处理程序的方式有好几种. 一:HTML事件处理程序. 如: 复制代码 代码如下: <script type="text/javascript"> function show(){ alert('hello world!'); } </script> <input type="button&q

  • javascript 事件处理、鼠标拖动效果实现方法详解

    先看看要拖动的层(模拟窗口)的效果图吧. 要实现的拖动效果:鼠标左键在窗口上方的标题栏上按下,同时移动鼠标,窗口跟着移动.窗口: 复制代码 代码如下: <div id="win"> <div id="win_header"></div> </div> 一点准备工作: 要让窗口能自由移动,那么窗口的定位(position)应该采用绝对定位(absolute): 给窗口添加标题栏,这里使用一个放在窗口顶部的层实现,同时将标

  • Vue.js每天必学之方法与事件处理器

    方法处理器 可以用 v-on 指令监听 DOM 事件: <div id="example"> <button v-on:click="greet">Greet</button> </div> 我们绑定了一个单击事件处理器到一个方法 greet.下面在 Vue 实例中定义这个方法: var vm = new Vue({ el: '#example', data: { name: 'Vue.js' }, // 在 `met

  • JavaScript中的事件处理

    事件处理概述  事件处理是对象化编程的一个很重要的环节,没有了事件处理,程序就会变得很死,缺乏灵活性.事件处理的过程可以这样表示:发生事件 - 启动事件处理程序 - 事件处理程序作出反应.其中,要使事件处理程序能够启动,必须先告诉对象,如果发生了什么事情,要启动什么处理程序,否则这个流程就不能进行下去.事件的处理程序可以是任意 JavaScript 语句,但是我们一般用特定的自定义函数(function)来处理事情. 指定事件处理程序有三种方法: 方法一 直接在 HTML 标记中指定.这种方法是

  • JavaScript事件处理程序详解

    本文实例为大家分享了js事件处理程序的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>DOM0级DOM2级</title> </head> <body> <input id="btn1" type="butto

  • JavaScript事件处理程序(事件侦听器)

    我们知道,javascript与HTML之间的交互是通过事件来实现的,事件就是用户或浏览器自身执行的某种动作,比如click.mounseover.load--,而响应事件的函数就叫做事件处理函数(或事件侦听器). event util test var eventUtil = { addListener: function(element, type, hander) { if (element.addEventListener) { element.addEventListener(type

随机推荐