Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prototype custom event NOT on a DOM element

Same as this question, but Prototype library specific:

I've got a Browser class, and I want to fire and observe custom events for this class. Prototype's custom event system only lets me bind to and fire events on DOM elements. Here's my first idea as to an alternative:

function Browser() {
    this.event = new Element('span');
}
Browser.prototype.render = function() {
    this.event.fire('browser:render');
}

var browser = new Browser();
browser.event.observe('browser:render', function() { ... });

Is there a better way to do this?

like image 577
Trevor Dixon Avatar asked Feb 17 '26 11:02

Trevor Dixon


2 Answers

Thanks in part to Frits van Campen's advice, I made my own that serves my needs, a little more sophisticated than Frits' sample.

function EventManager(target) {
    var target = target || window,
        events = {};
    this.observe = function(eventName, cb) {
        if (events[eventName]) events[eventName].push(cb);
        else events[eventName] = new Array(cb);
        return target;
    };
    this.stopObserving = function(eventName, cb) {
        if (events[eventName]) {
            var i = events[eventName].indexOf(cb);
            if (i > -1) events[eventName].splice(i, 1);
            else return false;
            return true;
        }
        else return false;
    };
    this.fire = function(eventName) {
        if (!events[eventName]) return false;
        for (var i = 0; i < events[eventName].length; i++) {
            events[eventName][i].apply(target, Array.prototype.slice.call(arguments, 1));
        }
    };
}

Then I can do:

Function Browser() {
    this.event = new EventManager(this);
}
Browser.prototype.render = function() {
    this.event.fire("render");
}   

browser = new Browser();
browser.event.observe("render", function() { alert("Rendered"); });
like image 102
Trevor Dixon Avatar answered Feb 18 '26 23:02

Trevor Dixon


Why not just build your own event handling system? It really doesn't take much.

function MyClass() {
    this.handlers = {};
}
MyClass.prototype.registerHandler = function(event, callback) {
    this.handlers[event] = callback;
};
MyClass.prototype.fire = function(event) {
    this.handlers[event]();
};

var instance = new MyClass();
instance.registerHandler('an event', function () {
    alert('hi!');
});
instance.fire('an event');
like image 27
Halcyon Avatar answered Feb 19 '26 01:02

Halcyon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!