Hijacking JavaScript/jQuery methods February 13, 2010 3 Comments
Some people often wonder: “Hey, when a user calls $(‘body’).css(‘background’, ‘something-awesome’); is there a way I can run some code before that happens?”. The answer is yes and it’s not very hard to do. If there is a name for this technique, I’m not aware of it so I’m just going to call it “hijacking”.
UPDATE: I have an expanded version of this technique. It includes a destroy() method to restore the original function/method. Check out the gist on github.
The process would be to create a function that returns the method along with some custom arguments that have been tampered with (scary, I know). Here is something basic to achieve this effect:
jQuery.fn.css = (function(_jQueryCSS){ return function(){ // Run some custom code here and alter the arguments passed in return _jQueryCSS.call(this, arguments); } })(jQuery.fn.css);
This technique has been done before by other developers. James Padolsey implements this technique in his cross-domain-ajax plugin and over-writes the jQuery.ajax method.
Normally I would stay clear of methods under another namespace (Don’t modify objects you don’t own -Nicholas Zakas) but sometimes it makes sense to over-write them to add your own custom bits like in James’ case (just be careful
, he’s not hurting the current functionality of jQuery.ajax, he’s simply augmenting it. I’ve created a simple function to handle this type of hijacking.
The hijack function
/** * Allows you to alter with arguments before the method is actually called * @param {Function} method A method/function to call after doing some tampering * @param {Function} cb A callback that is passed the arguments for you to play with */ function hijack(method, cb){ // A function needs to be passed or there will be hell to pay if(Object.prototype.toString.call(cb) !== "[object Function]"){ throw new Error('An anonymous function must be passed as the second parameter!'); } return function(){ // Turn arguments into a true array var args = Array.prototype.slice.call(arguments); // Call the copied method and pass it some 'tampered' arguments from our callback return method.apply(this, cb.call(this, args) || args); }; }
Usage
Here is a simple use-case of how you would hijack the CSS method in jQuery.
// Hijack the CSS method in jQuery jQuery.fn.css = hijack(jQuery.fn.css, function(user_args){ // Now store the arguments passed in by the user var args = user_args; // Do some checking and alter the arguments if(args[0] == 'background' && args[1] == 'this-will-be-replaced-with-green'){ args[1] = 'green'; } return args; });
So now when I call:
$('body').css('background', 'this-will-be-replaced-with-green');
It will run through my hijacked function and replace ‘this-will-be-replaced-with-green’ with ‘green’. And voila, your background is green.

just make it into one bundle plugin
regards