2016-07-04 78 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