2011-06-03 8 views
5

En Java, C#, Actionscript etc. Los eventos son para clases mientras que en Javascript parece restringido a dom. He leído aquí una muestra para hacerlo con jquery http://www.west-wind.com/weblog/posts/2010/May/27/NonDom-Element-Event-Binding-with-jQueryCómo agregar EventListener a elementos no dom en javascript?

pero si no necesito jquery y si quiero entender el mecanismo, ¿cómo lo harías?

+0

¿Qué es exactamente lo que quieres hacer? ¿Qué tal una implementación clásica de 'Observer'? –

+0

Probablemente quiera un [EventEmitter] (https://github.com/Wolfy87/EventEmitter). – Thai

+0

@Thai ¡gracias parece genial! – user310291

Respuesta

1

en él es el más simple el mecanismo es algo así como:

function PubSub() { 
    this.subs = {}; 
    this.subscribe = function(channel, sub) { 
     this.subs[channel] = this.subs[channel] || []; //create array for channel 
     this.subs[channel].push(sub); 
    }; 
    this.publish = function(channel) { 
     var args = [].slice.call(arguments, 1); //pop off channel argument 
     this.subs[channel].forEach(function(sub) { 
      sub.apply(void 0, args); //call each method listening on the channel 
     }); 
    }; 
} 

demostración aquí: http://jsfiddle.net/3PNtR/

3

Hay al menos dos maneras de lograr esto:

- Si usted es un usuario jQuery (Actualmente, no), puede envolver su objeto JavaScript simple con JQuery, luego como elementos DOM, puede escuchar eventos. Este método ya tiene un answerhere. No estoy seguro de cómo funciona este método bajo el capó, planeo investigar más adelante, y usted puede investigar por su cuenta.

- Con VanillaJS, puede lograr el mismo efecto creando una "clase" agitada desde la cual se derivarán/crearán todos los objetos que estén dispuestos a interactuar. Entonces todas las instancias de esa clase podrán registrar, emitir y emitir un evento. Tomando en cuenta la semántica de DOM API y AngularJS, he escrito un ejemplo que demuestra cómo se puede hacer y cómo se puede usar. Aquí está:

/** 
 
* EventfulObject constructor/base. 
 
* @type EventfulObject_L7.EventfulObjectConstructor|Function 
 
*/ 
 
var EventfulObject = function() { 
 
    /** 
 
    * Map from event name to a list of subscribers. 
 
    * @type Object 
 
    */ 
 
    var event = {}; 
 
    /** 
 
    * List of all instances of the EventfulObject type. 
 
    * @type Array 
 
    */ 
 
    var instances = []; 
 
    /** 
 
    * @returns {EventfulObject_L1.EventfulObjectConstructor} An `EventfulObject`. 
 
    */ 
 
    var EventfulObjectConstructor = function() { 
 
    instances.push(this); 
 
    }; 
 
    EventfulObjectConstructor.prototype = { 
 
    /** 
 
    * Broadcasts an event of the given name. 
 
    * All instances that wish to receive a broadcast must implement the `receiveBroadcast` method, the event that is being broadcast will be passed to the implementation. 
 
    * @param {String} name Event name. 
 
    * @returns {undefined} 
 
    */ 
 
    broadcast: function(name) { 
 
     instances.forEach(function(instance) { 
 
     (instance.hasOwnProperty("receiveBroadcast") && typeof instance["receiveBroadcast"] === "function") && 
 
     instance["receiveBroadcast"](name); 
 
     }); 
 
    }, 
 
    /** 
 
    * Emits an event of the given name only to instances that are subscribed to it. 
 
    * @param {String} name Event name. 
 
    * @returns {undefined} 
 
    */ 
 
    emit: function(name) { 
 
     event.hasOwnProperty(name) && event[name].forEach(function(subscription) { 
 
     subscription.process.call(subscription.context); 
 
     }); 
 
    }, 
 
    /** 
 
    * Registers the given action as a listener to the named event. 
 
    * This method will first create an event identified by the given name if one does not exist already. 
 
    * @param {String} name Event name. 
 
    * @param {Function} action Listener. 
 
    * @returns {Function} A deregistration function for this listener. 
 
    */ 
 
    on: function(name, action) { 
 
     event.hasOwnProperty(name) || (event[name] = []); 
 
     event[name].push({ 
 
     context: this, 
 
     process: action 
 
     }); 
 

 
     var subscriptionIndex = event[name].length - 1; 
 

 
     return function() { 
 
     event[name].splice(subscriptionIndex, 1); 
 
     }; 
 
    } 
 
    }; 
 

 
    return EventfulObjectConstructor; 
 
}(); 
 

 
var Model = function(id) { 
 
    EventfulObject.call(this); 
 
    this.id = id; 
 
    this.receiveBroadcast = function(name) { 
 
    console.log("I smell another " + name + "; and I'm model " + this.id); 
 
    }; 
 
}; 
 
Model.prototype = Object.create(EventfulObject.prototype); 
 
Model.prototype.constructor = Model; 
 

 
// ---------- TEST AND USAGE (hopefully it's clear enough...) 
 
// ---------- note: I'm not testing event deregistration. 
 

 
var ob1 = new EventfulObject(); 
 
ob1.on("crap", function() { 
 
    console.log("Speaking about craps on a broadcast? - Count me out!"); 
 
}); 
 

 
var model1 = new Model(1); 
 

 
var model2 = new Model(2); 
 
model2.on("bust", function() { 
 
    console.log("I'm model2 and I'm busting!"); 
 
}); 
 

 
var ob2 = new EventfulObject(); 
 
ob2.on("bust", function() { 
 
    console.log("I'm ob2 - busted!!!"); 
 
}); 
 
ob2.receiveBroadcast = function() { 
 
    console.log("If it zips, I'll catch it. - That's me ob2."); 
 
}; 
 

 
console.log("start:BROADCAST\n---------------"); 
 
model1.broadcast("crap"); 
 
console.log("end :BROADCAST\n---------------\n-\n-\n"); 
 
console.log("start:EMIT\n---------------"); 
 
ob1.emit("bust"); 
 
console.log("end:EMIT\n---------------");
<h1>THE CODE IS IN the JavaScript pane!</h1> 
 
<h3>AND... THE SHOW IS ON YOUR CONSOLE!</h3>

Usted puede usar eso como una base para una solución más robusta.

Cuestiones relacionadas