js也可以有自定义事件 注入就是这么爽

js

  在c#中有delegate,还有特殊的可以直接应用于事件编程的delegate,那就是event。而在js中没有c#的event,更没有delegate,有的只是dom元素内置的的native的不可扩展的event,比如无法为input元素添加事件,只能在其拥有的事件(如onclick=handler)上扩展应用。那么能不能做到自定义的事件模拟效果呢?答案是肯定的,也就是本文的主题。
  首先弄明白一下事件的意图——可以在发生一件事的时候执行额外的代码,如document.attachEvent('onclick', function(){alert('u click document')}),当点击页面时(事件发生了),就会执行我们为其挂接的其它代码(js中以function为语句集合,以下称为function),当然我们可以在一个事件上挂接任意多的function,这样就实现了一种灵活的可扩展编程接口。试想如果可以像在元素事件扩展应用一样可以在任意对象的任意方法上扩展,那对于js编程来讲就更加灵活了。先看一个例子,平时我们把相对对立的一个功能命名为一个function,并在需要的地方(通常是另一个function)调用以实现代码复用:
function F(){
    this.method = function(){
        alert('f.method is called')
        g();
    }
}
function g(){
    alert(123)
}
var f = new F();
f.method()

我们把f.method中直接调用g改写一下,封装到一个Event对象中达到一样的效果,代码如下:
var Event = {
    __list:[],
    observe:function(obj, ev, fun){
        this.__list.push({o:obj, e:ev, f:fun})
    },
    occor:function(obj, method){
        var arr = []
        for(var i=0; i<this.__list.length; i++){
            if(this.__list[i].o==obj && this.__list[i].e==method) arr.push(this.__list[i]);
        }
        for(var i=0; i<arr.length; i++){
            arr[i].f();
        }
    }
}

function F(){
    this.method = function(){
        alert('f.method is called')
        Event.occor(this, 'method');
    }
}

var f = new F();
Event.observe(f, 'method', function(){alert(123)})
f.method()这样乍看上去好像费了“太多”功夫,但却把“在f中调用g的写法”更通用化了,如果要在f中调用h则只需要多些一行Event.occor(this, 'methodName'),写到这里你肯定也注意到methodName的写法和最开始的写法是一样的,都是硬编的不具灵活性,如果在每个类的方法中都写入Event.occor(this, 'method')就太不雅观了,也背离了我们的初衷,动态修改一下method把它加到最后一行就ok了,下一步就是解决它,改进代码如下:

var Event = {
    __list:[],
    observe:function(obj, ev, fun){
        this.__list.push({o:obj, e:ev, f:fun})
    },
    occor:function(obj, method){
        var arr = []
        for(var i=0; i<this.__list.length; i++){
            if(this.__list[i].o==obj && this.__list[i].e==method) arr.push(this.__list[i]);
        }
        for(var i=0; i<arr.length; i++){
            arr[i].f();
        }
    },
    inject:function(obj){
        for(var p in obj){
            obj[p] = new Function(obj[p].toString().replace('function(){', '').replace('}', 'Event.occor(this,p)'))
        }
    }
}

function F(){
    this.method = function(){
        alert('f.method is called')
    }
}

var f = new F();
Event.inject(f);
Event.observe(f, 'method', function(){alert(123)})
f.method()我们把显示的在被调用方法体内调用Event.occor改写到Event.inject中。到此我们就简单(还有一些安全代码没有处理,如没有判断obj[p]是否需要被改写、没有测试效率问题,没有处理更多添加Event.occor时的逻辑判断,下一步准备把它实现为一个Observeable对象,就更加灵活了)的完成了自定义事件。

时间: 2024-09-26 12:27:24

js也可以有自定义事件 注入就是这么爽的相关文章

AS3与JS之间的简单自定义参数通讯

一直没去深入研究下AS3与JS的交互开发也就是SWF在html中的通信,最近出于项目要求被迫投入了,也在这里做个汇总. 一:HTML中最快速的传值方式 在HTML中插SWF时,可以跟个参数,比如: files/home.swf?id="21″ 在AS3里可以这样去接收 var id:String=stage.loaderInfo.parameters["id"]; 这种传值方式其实AS2的时候也是这样做的,到AS3时使用parameters 属性替换了AS1.0 和2.0 提

百度有啊前端框架分析(自定义事件)

      今天早晨从酒店出来,外面下着鹅毛大雪,我的妈呀,我来的时候只穿了一件秋衣,昨天晚上好像所有的天气预报都没有报告今天会下雪,我操,我们的天气预报的仙人们天天在那里说的跟真的一样,这不是骗人吗,但是也没有办法,只能自己想办法怎么能事自己变得更暖和些.          JavaScript中的事件也是如此,浏览器内置的事件不可能帮你把所有的事情都做了,因此遇到特殊事件,必须我们自定义把他实现,那么我们就来来看百度有啊前端JavaScript框架的自定义事件是如何实现的.        

js自定义事件及事件交互原理概述(一)_javascript技巧

在JS中事件是JS与浏览器交互的主要途径.事件是一种叫做观察者的设计模式,这是一种创建松散耦合代码的技术.对象可以发布事件,用来表示在该对象生命周期中某个有趣的时刻到了.然后其他对象可以观察该对象,等待这些有趣的时刻到来并通过运行代码来响应. 观察者模式有两类对象组成:主题和观察者.主体负责发布事件,同时观察者通过订阅这些事件来观察该主体.该模式的一个关键概念是主体并不知道观察者的任何事情,也就是说它可以独自存在并正常运作即使观察者不存在.从另一方面说,观察者知道主体并能注册事件的回调函数(事件

js自定义事件及事件交互原理概述(二)_javascript技巧

js自定义事件(一)的目的只是让大家简单的理解自定事件是如何模拟出来的,大家不难发现会有很多缺陷,比如: 1.此事件对象只能注册一个事件,不能提供多个事件 2.注册方法没有返回的一些信息 下面我们就来解决这些问题.如下为MyEvent.js源代码: 复制代码 代码如下: function MyEvent(){ this.handlers={}; } MyEvent.prototype={ addHandler:function(type,handler) { if(typeof this.han

nodejs 中模拟实现 emmiter 自定义事件_node.js

nodejs 中模拟实现 emmiter 自定义事件 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script> function Emitter() { this.events = {}; //存放事件的地方 } Emitter.prototype.on = function(type, cb) { var

Nodejs中自定义事件实例_node.js

其实就是继承events的EventEmitter就可以了,然后就可以通过on去注册事件:emit去触发事件,removeListener去移除事件,简单例子如下: var util = require('util'); var Et = require('events').EventEmitter; function Ticker() { var self = this; setInterval(function(){self.emit("tick")},1000); } util.

jQuery自定义事件

在JS中,消息的通知是通过事件表达的,当代码库增长到一定的规模就需要考虑将行为和自定义事件进行解耦,通过事件机制可以将类设计为独立的模块,通过事件对外通信提高了程序的开发效率. 了解自定义事件的概念: 类似 DOM 的行为:你在 DOM 节点(包括 document 对象)监听并触发自定义事件.这些事件既可以冒泡,也可以被拦截.这正是 Prototype.jQuery 和 MooTools 所做的.如果事件不能扩散,就必须在触发事件的对象上进行监听. 命名空间:一些框架需要你为事件指定命名空间,

JavaScript使用自定义事件实现简单的模块化开发

WEB前端最常见驱动方式就是事件了, 所有交互等等都是通过事件,前端的常见事件有:     UI事件: 焦点事件: 鼠标事件: 滚轮事件: 文本事件: 键盘事件: 变动事件: 现在网页上有一个输入框, 如果我们要对用户输入的字符串进行过滤, 或者是截获用户的输入进行处理的话, 我们要肿么办  同学们纷纷举手说:"老师,我知道,是使用添加事件", 老师也很欣慰地点了点头, 这群家伙真的是越来越聪明了, 老师又问了"如果要取消用户的输入怎么办了", 坐在最前排眼睛最小的

用EventDispatcher自定义事件

原来也研究过EventDispatcher,但是最近用的比较多,没想到这么好用,不用定义那么多全局变量. 我不做过多的说明,想要深入了解的同学请看帮助,我只告诉大家怎么定义自己的事件,而且大家马上就能用这些代码定义自己的事件. 下面看代码: //首先我们要导入EventDispatcherimport mx.events.EventDispatcher;class testEvent extends MovieClip{ function testEvent(){//在构造函数中初始化 Even