覆盖 Jquery 的功能

Override Jquery's function

我有一个巨大的应用程序,其中 jqueryaddClassremoveClass 在代码中的许多地方使用。我想根据 class 正在 added/removed 对正在更改的元素 class 执行一些工作。更长的路线是在 addClassremoveClass 之后的应用程序中的任何地方添加我的代码,但我在想如果我能以某种方式覆盖这些 jquery 的功能,那么我的生活将会很多更轻松。我试过下面的代码。

var oAddClass = jQuery.fn.addClass;
jQuery.fn.addClass = function (arg) {
    alert(this);
    alert(arg);

    // Now go back to jQuery's original size()
    return oAddClass.apply(this, arg);
};

但在 return oAddClass.apply(this, arg);

出现错误“Function.prototype.apply:参数不是对象

有人可以帮我解决一下吗。

您试图将包装函数的第一个参数仅传递给 .apply(),但 .apply() 的第二个参数应该是一个数组。您可以从 arguments 对象创建一个数组:

  var args = [];
  for (var i = 0; i < arguments.length; ++i) args[i] = arguments[i];
  oAddClass.apply(this, args);

arguments对象是运行时在每个函数中初始化的特殊对象。这是一件棘手的事情,它会导致代码优化问题,但上面的简单使用是安全的。

.apply 的第二个参数必须是类数组对象。

return oAddClass.apply(this, arguments);

出于可维护性的原因,我建议不要这样做:如果另一个开发人员查看代码并看到 jQuery .addClass,如果它除了删除 class 之外还做了其他事情,那将非常混乱].

我会用你自己的规则编写一个辅助函数来调用 addClass and/or removeClass.

鉴于jQuery.addClass is documented to receive a single argument I believe that .call should be used instead of .apply

尽管如此:jQuery 没有记录其内部自用模式,因此您永远不知道何时会调用替换的 addClass 方法(下面的切换 class 示例)。

(function () {
  var oAddClass = jQuery.fn.addClass;
  jQuery.fn.addClass = function(arg) {
    return oAddClass.call(this, arg);
  };
}());

$('#foo').addClass('foo bar');

$('span').addClass(function(index) {
  if (index == 0) {
    return 'bar';
  }
  return 'foo';
});

$('button').on('click', function () {
    $('#foo').toggleClass('foo');
});
.foo {
  background-color: green;
}
.bar {
  color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="foo">Hello World</div>
<span>Span 1</span>
<br />
<span>Span 2</span>
<br />
<button>Toggle .foo on the div</button>