【问题标题】:Override jQuery functions simply by extending?简单地通过扩展来覆盖 jQuery 函数?
【发布时间】:2014-07-21 03:22:54
【问题描述】:

这与另一个 SO Q&A Override jQuery functions 有关,但不是重复。

从上述问题的答案中可以清楚地看出,覆盖 jQuery 函数的模式是:

(function($){

    // store original reference to the method
    var _old = $.fn.method;

    $.fn.method = function(arg1,arg2){

        if ( ... condition ... ) {
           return  ....
        } else {           // do the default
           return _old.apply(this,arguments);
        }
    };
})(jQuery);

但是为什么!?

我已经能够简单地通过在$.extend$.fn.extend 中定义一个与要被覆盖的函数同名的函数来覆盖一个jQuery 函数。

考虑一下:

// random example showing jquery function overriding
$.fn.extend({
    hide: function() {
        $(this).css({"color":"red"});
    }
});

$("#test").hide(); // this will actually paint the #test element red!

jsFiddle

我想了解为什么_old.apply(this,arguments) 是覆盖 jQuery 函数的首选方式,如 herehere 所列。

【问题讨论】:

  • 那么你遇到了什么问题?
  • fn 是 jQuery 对 prototype 的快捷方式,因此您只需执行 $.fn.hide(或 $.prototype.hide)即可创建一个名为 hide 的新原型属性,该属性将覆盖之前的 hide ,并且要了解您可能应该前往 MDN 并阅读有关对象和原型的内容,因为这与 jQuery 关系不大。
  • 问题是我错过了证明.apply 将是覆盖 jQuery 函数的首选方式的原因。
  • 显然 jQuery 参数是在数组中提供的。而不是覆盖我会使用中间人:tech.zumba.com/middleman.js

标签: javascript jquery


【解决方案1】:

通过查看原始帖子中提供的参考资料,模式摘要可能是保持“旧”和“新”方法都可用?

编辑、更新

对不起,我不明白。据我所见,对覆盖方法的引用保存在闭包中的局部变量中 毫无疑问,在关闭之外丢失了。你能解释一下“老” 方法还可以吗? –SNag

我想了解为什么 _old.apply(this,arguments) 会是 覆盖 jQuery 函数的首选方法,如 herehere.

利用上面第一个链接的模式,如果正确解释片段,出现argumentstest在“自执行匿名函数”中的jquery方法的if语句中确定“旧”或“新”的返回值(新包含;覆盖)jquery 方法?

例如,尝试

html

<div>abc</div>

js

// See http://www.paulirish.com/2010/duck-punching-with-jquery/ , at
// `First we start off with a self-executing anonymous function,
// that makes a happy closure while remapping jQuery to $:`

// `closure` start
    (function ($) {
        // jquery `.css()`
        var _oldcss = $.fn.css;
        // jquery `.hide()`
        var _oldhide = $.fn.hide;

        // "new" `.css()`
        $.fn.css = function (prop, value) {
            // "new" `.css()` `test`
            if (/^background-?color$/i.test(prop) 
                && value.toLowerCase() === 'burnt sienna') {
                return _oldcss.call(this, prop, '#EA7E5D');
            } else {
                return _oldcss.apply(this, arguments);
            }
        };

        // "new" `.hide()`
        $.fn.hide = function (prop, value) {
            // "new" `.hide()` `test` 
            if (/color/i.test(prop) && /[a-f]|[0-9]/i.test(value)) {
                return $.fn.css.call(this, prop, value);
            } else {
                return _oldhide.apply(this, arguments);
            }
        };
    })(jQuery);
    // `closure` stop

    // and using it...
    // "new" `.css()`
    jQuery(document.body).css('backgroundColor', 'burnt sienna');
    // "old" `.css()`
    $("div").css("color", "yellow");
    // "old" `.hide()`
    $("div").hide(7500, function () {
        // "old" `.css()`
        $(document.body)
            .css({
            "transition": "background 2s",
            "background": "#edd452"
        })
        .find($("div")).show(2500)
        // "new" `.hide()`
        .hide("color", "red")
    });

jsfiddle http://jsfiddle.net/guest271314/5bEe4/

【讨论】:

  • 对不起,我不明白。据我所知,对被覆盖方法的引用保存在闭包中的局部变量中,毫无疑问会在闭包之外丢失。您能解释一下“旧”方法如何仍然可用吗?
  • @SNag: 被覆盖方法的引用保存在一个局部变量中,该变量在匿名函数内部可用(因此形成一个闭包)。一旦你调用了新方法,它就会调用_old 方法(因为它的作用域仍然存在)。在这里,apply 用于传递原始(当前)this 引用,以便其上下文在 _old 方法上可用。使用前一种方式,因为在这里您可以通过保留其原始功能来覆盖该方法,因此原始jQuery 功能不会中断。
  • @MohitPandey:您的评论很有道理。如果你能写出完整的答案,我很乐意接受!谢谢!
【解决方案2】:
(function($){

    // store original reference to the method
    // stored locally
    var _old = $.fn.method;

    $.fn.method = function(arg1,arg2){

        if ( ... condition ... ) {
           return  ....
        } else {           // do the default
           // call apply method, in order to pass the this context.
           return _old.apply(this,arguments);
        }
    };
})(jQuery);

在上面的代码中,我们调用了一个匿名函数,我们在其中声明了一个局部变量_old。当这个匿名函数执行时,它会保存_old 方法引用并形成一个closure。 现在,当我们调用新方法时,即

    $.fn.method = function(arg1,arg2){
       if ( ... condition ... ) {
           return  ....
        } else {           // do the default
           return _old.apply(this,arguments);
        }
    };

我们还可以访问_old 方法,因为它的作用域存在于当前上下文中。然后,我们可以在新方法中使用它。

这里我们在apply 的帮助下调用_old 方法,因为我们也希望有相同的this 上下文。

使用这种方法,我们可以通过保留其原始功能轻松覆盖jQuery 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多