ClayKaboom ClayKaboom - 5 months ago 16
jQuery Question

Override/Intercept all jQuery functions

I was trying to override all jQuery functions to perform an action whenever jQuery was called (for auditing purposes or other reasons). However I probably need to get the same parameters a function receives in order to make the following code work:



function __wrapjQuery () {
var wrapper = this;


alert('Wrapping');


var functions = Object.getOwnPropertyNames($.fn).filter(function (p) {
return ( typeof( $.fn[p] ) === 'function');
});

for (var i = 0; i < functions.length; i++) {
wrapper.oldTempjQueryFunction = $.fn[functions[i]];
$.fn[functions[i]] = function () {
var self = this;
self.wrappedFunction = wrapper.oldTempjQueryFunction;
var returnVar = self.wrappedFunction.call(this);
alert('jQuery was called');
return returnVar;
}
}

}

$().ready(self.__wrapjQuery);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv" style="background-color:#FF0000">
ELEMENT
</div>

<button onclick="$('#myDiv').remove()">Remove Element</button>





However the code below, where I specify the function to override (
remove
) ,works (maybe because of the parameters):



function __wrapjQuery () {
var wrapper = this;

alert('Wrapping');
wrapper.wrappedRemoveFunction = $.fn.remove;
$.fn.remove = function () {
var self = this;
var returnVar = wrapper.wrappedRemoveFunction.call(this);
alert('jQuery was called to remove');
return returnVar;
}

}

$().ready(self.__wrapjQuery);

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv" style="background-color:#FF0000">
ELEMENT
</div>

<button onclick="$('#myDiv').remove()">Remove Element</button>





How would I replace all functions (even those with parameters, like
each
) and keep jQuery working normally? Let's say I want to audit the most used methods from jQuery.

Answer

You can wrap all jQuery object methods to collect whatever statistics you want with code like this:

// place this right after jQuery and any jQuery plugins are installed
(function($) {
    Object.getOwnPropertyNames($.fn).filter(function (p)   {
        return ( typeof( $.fn[p] ) === 'function' && p !== "init");
    }).forEach(function(funcName) {
        var orig = $.fn[funcName];
        $.fn[funcName] = function() {
            console.log(funcName + " jQuery method called");
            return orig.apply(this, arguments);
        }
    });
})(jQuery);

Working demo here: https://jsfiddle.net/jfriend00/7Ls0qkvb/

If you also wanted to include static methods, you could do a similar enumeration of the methods on the jQuery object.


Note, because $.fn.init() is called as a constructor and thus needs different treatment in how it is handled (you can't use .apply() with a constructor), I bypassed recording that method. I have not searched through jQuery to find any other methods called as a constructor, but they would likely need special treatment also.


Here's a more advanced version that can even log .init() and any other method called as a constructor: https://jsfiddle.net/jfriend00/uf531xzb/. It detects if a method is called with new and acts accordingly.