Event Listener On Non-dom Elements
I'm trying to implement a little MVC framework and now I'm implementing the view-model binder, I mean, when the model changes, trigger a refresh/render/whatever on the model. So, I
Solution 1:
If you are already using jQuery, you can use its built-in event handling facilities.
It's a little known fact that you can also put any kind of Javascript objects into a jQuery collection, not just DOM elements. Then you can use a limited set of jQuery methods (.data()
, .prop()
, .on()
, .off()
, .trigger()
and .triggerHandler()
) on these objects.
//create the model - it can be any kind of objectvar model = {};
//pass it to the jQuery function and you have a jQuery collection//you can put an event handler on the object
$(model).on('customEvent', function () { console.log('hehe'); });
//and trigger it
$(model).trigger('customEvent');
- Read more in the Manual
- Try the Demo
Solution 2:
For those who are not using jQuery and are interested in wiring their own stuf, here's how you may achieve similar aim:
/**
* EventfulObject constructor/base.
* @type EventfulObject_L7.EventfulObjectConstructor|Function
*/varEventfulObject = function() {
/**
* Map from event name to a list of subscribers.
* @typeObject
*/var event = {};
/**
* List of all instances of the EventfulObject type.
* @typeArray
*/var instances = [];
/**
* @returns {EventfulObject_L1.EventfulObjectConstructor} An `EventfulObject`.
*/varEventfulObjectConstructor = 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;
returnfunction() {
event[name].splice(subscriptionIndex, 1);
};
}
};
returnEventfulObjectConstructor;
}();
varModel = 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 = newEventfulObject();
ob1.on("crap", function() {
console.log("Speaking about craps on a broadcast? - Count me out!");
});
var model1 = newModel(1);
var model2 = newModel(2);
model2.on("bust", function() {
console.log("I'm model2 and I'm busting!");
});
var ob2 = newEventfulObject();
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 SECTION!</h1><h3>AND... THE SHOW IS ON YOUR CONSOLE!</h3>
Post a Comment for "Event Listener On Non-dom Elements"