覆盖/拦截所有jQuery函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了覆盖/拦截所有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的最常用的方法。

答案

你可以用所有的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和相应地动作。

另一答案

我如何将取代所有功能(即使是那些参数,如每个),并保持jQuery的正常工作?

您可以检索jquery-migrate-1.4.1.js插件,包括线354-373的使用利用deprecated jQuery.sub()能力。

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>

以上是关于覆盖/拦截所有jQuery函数的主要内容,如果未能解决你的问题,请参考以下文章

覆盖一个常见的片段帮助其他标签片段

jQuery - 拦截所有Ajax请求(统一处理超时返回结果错误状态码 )

js入口函数跟jQuery入口函数的区别

覆盖 jQuery 函数

如何覆盖 jQuery 函数或阻止它执行

内联 onclick 覆盖 JQuery click()