Search code examples
mootoolsmootools-events

How to extend a native mootools method


Is it possible to extend the addEvent function in mootools to do something and also calls the normal addEvent method? Or if someone has a better way to do what I need I'm all years.

I have different 'click' handlers depending on which page I'm on the site. Also, there might be more than one on each page. I want to have every click on the page execute a piece of code, besides doing whatever that click listener will do. Adding that two lines on each of the handlers, would be a PITA to say the least, so I thought about overriding the addEvent that every time I add a 'click' listener it will create a new function executing the code and then calling the function.

Any idea how I could do it?


Solution

  • Whereas this is not impossible, it's a questionable practice--changing mootools internal apis. Unless you are well versed with mootools and follow dev direction on github and know your change won't break future compatibility, I would recommend against it.

    The way I see it, you have two routes:

    1. make a new Element method via implement that does your logic. eg: Element.addMyEvent that does your thing, then calls the normal element.addEvent after. this is preferable and has no real adverse effects (see above)

    2. change the prototype directly. means you don't get to refactor any code and it will just work. this can mean others that get to work with your code will have difficulties following it as well as difficulties tracing/troubleshooting- think, somebody who knows mootools and the standard addEvent behaviour won't even think to check the prototypes if they get problems.

    3. mootools 2.0 coming will likely INVALIDATE method 2 above if mootools moves away from Element.prototype modification in favour of a wrapper (for compatibility with other frameworks). Go back to method 1 :)

    I think solution 1 is better and obvious.

    as for 2: http://jsfiddle.net/dimitar/aTukP/

    (function() {
        // setup a proxy via the Element prototype.
        var oldProto = Element.prototype.addEvent;
    
        // you really need [Element, Document, Window] but this is fine.
        Element.prototype.addEvent = function(type, fn, internal){
            console.log("added " + type, this); // add new logic here. 'this' == element.
            oldProto.apply(this, arguments);
        };
    
    })();
    
    document.id("foo").addEvent("click", function(e) {
        e.stop();
        console.log("clicked");
        console.log(e);
    });
    

    it is that simple. keep in mind Element.events also should go to document and window. also, this won't change the Events class mixin, for that you need to refactor Events.addEvent instead.