2016-07-04 77 views
1

我试图覆盖所有jQuery函数,以便在调用jQuery(用于审计目的或其他原因)时执行操作。但是我可能需要获得以使下面的代码工作的功能接收到相同的参数:覆盖/拦截所有jQuery函数

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>

但是下面的代码,在那里我指定函数重载(remove)可以(因为参数的可能):

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>

我将如何替换所有功能(即使是那些带参数的功能,如each),并保持jQuery正常工作?假设我想审核jQuery中最常用的方法。

+0

第一个明显的问题是为什么?你想解决什么问题? – charlietfl

+0

@charlietfl假设我想审核jQuery中最常用的方法。 – ClayKaboom

+0

那么当你删除'&& $ .fn [p] ==“remove”'并尝试使用'$ .fn.each'时会发生什么?或者当你尝试链接方法? – charlietfl

回答

2

你可以用所有的jQuery对象方法来收集你想使用如下代码什么的统计数据:

// 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); 

工作演示在这里:https://jsfiddle.net/jfriend00/7Ls0qkvb/

如果你也想包含静态方法,你可以做一个类似枚举jQuery对象上的方法。


注意,因为$.fn.init()被称为构造函数,因此它是如何处理的,需要不同的处理(不能使用.apply()有构造函数),我绕过记录该方法。我没有通过jQuery来查找任何其他称为构造函数的方法,但他们也可能需要特殊处理。


下面是一个更高级的版本,即使可以登录.init(),并呼吁作为构造任何其他方法:https://jsfiddle.net/jfriend00/uf531xzb/。它检测是否用new调用方法并相应地执行。

+0

'arguments'从哪里来? – ClayKaboom

+2

@ClayKaboom - 它内置于每个函数中:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments – jfriend00

1

我该如何替换所有函数(即使是那些带参数的函数,如 ),并保持jQuery正常工作?

可以retieve jquery-migrate-1.4.1.js插件,包括使用利用deprecatedjQuery.sub()能力行354-373

jQuery.sub()返回jQuery

说明:创建jQuery的,其属性和方法 可以在不影响原有的jQuery对象被修改的新副本。

// https://code.jquery.com/jquery-migrate-1.4.1.js, lines 354-373 
 
jQuery.sub = function() { 
 
    function jQuerySub(selector, context) { 
 
    return new jQuerySub.fn.init(selector, context); 
 
    } 
 
    jQuery.extend(true, jQuerySub, this); 
 
    jQuerySub.superclass = this; 
 
    jQuerySub.fn = jQuerySub.prototype = this(); 
 
    jQuerySub.fn.constructor = jQuerySub; 
 
    jQuerySub.sub = this.sub; 
 
    jQuerySub.fn.init = function init(selector, context) { 
 
    var instance = jQuery.fn.init.call(this, selector, context, rootjQuerySub); 
 
    return instance instanceof jQuerySub ? 
 
     instance : 
 
     jQuerySub(instance); 
 
    }; 
 
    jQuerySub.fn.init.prototype = jQuerySub.fn; 
 
    var rootjQuerySub = jQuerySub(document); 
 
    // migrateWarn("jQuery.sub() is deprecated"); 
 
    return jQuerySub; 
 
}; 
 

 

 
// do stuff with copy of jQuery 
 
var __wrapjQuery = jQuery.sub(); 
 
__wrapjQuery.pluginName = "wrapper"; 
 
__wrapjQuery.fn.remove = function() { 
 
    console.log(__wrapjQuery.fn.remove, $.fn.remove); 
 
    alert(__wrapjQuery.pluginName); 
 
} 
 

 
__wrapjQuery(".wrapper").click(function() { 
 
    __wrapjQuery(this).remove() 
 
}); 
 

 

 
$(".jquery").click(function() { 
 
    console.log($.fn.remove, __wrapjQuery.fn.remove); 
 
    $(this).remove(); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<button class="wrapper">wrapper <code>.remove()</code> 
 
</button> 
 
<button class="jquery">jQuery <code>.remove()</code> 
 
</button>

+0

非常有帮助!这对未来的参考很有用!谢谢! – ClayKaboom