javascript - 如何包装 jQuery 函数

标签 javascript jquery

问题

我想知道在保留所有功能的同时包装 jQuery 函数的最佳方法。本质上我想调用 $('#someId') 但通过包装函数、修改参数,并将其传递给原始 jQuery 函数。

动机

我有一个 JS 部分,它将重用相同的变量 winId ,该变量被连接并传递给 jQuery。而不是写

$('#' + winId + 'someId').html();
$('#' + winId + 'someOtherId').css();
...
$('#' + winId + 'someThirdId').text();

在整个文件中,我想包装 jQuery 函数,这样我就可以调用

$('#someId').html();
$('#someOtherId').css();
...
$('#someThirdId').text();

并且在传递到 $ 之前添加了 winId


我的尝试

这是我作为包装器的想法:

(function() {
    var fn = $;

    return $ = function() {
       for ( var i = 0; i < arguments.length; i++ ) {
          if ( typeof arguments[i] == 'string') {
             arguments[i] = /* code to add in winId, omitted */
          }
       }
       return fn.apply( this, arguments );
    }
})();

这非常有效,除了显然没有像 $.ajax 这样的方法可用:

Uncaught TypeError: Object function () {
    for ( var i = 0; i < arguments.length; i++ ) {
       if ( typeof arguments[i] == 'string' ) {
          arguments[i] = /* code to add in winId, omitted */
       }
    }
    return fn.apply( this, arguments );
} has no method 'ajax' 

注意:我知道我可以使用 jQuery.extend($, jQuery) 复制对象,但如果可能的话,我对比这更优雅的解决方案感兴趣。

最佳答案

这是一个不同的实现:

DEMO

(jQuery.fn.init = (function (init) {

    return function (selector) {
        if (typeof selector === 'string' && selector[0] === '#') {
            arguments[0] = selector.replace('#', '#prefix_');
        }

        return init.apply(this, arguments);
    };

})(jQuery.fn.init)).prototype = jQuery.fn;


$(function () {
    console.log($('#test').length);
    console.log($.ajax);
});

编辑:后续问题:我如何才能仅在闭包中应用此功能?例如,在一个对象内。

也许可以使用允许添加命名装饰器和删除它们的函数,例如:

HTML

<div id="prefix_test"></div>

JS

var decJQ = (function (decJQ, $) {
    var decorators = {},
        init = $.fn.init;

    ($.fn.init = function () {

        for (var k in decorators) {
            if (decorators.hasOwnProperty(k)) {
                arguments = decorators[k].apply(this, arguments);
            }
        }

        return init.apply(this, arguments);
    }).prototype = $.fn;

    return $.extend(decJQ, {
        decorate: function (name, fn) {
            decorators[name] = fn;
        },
        undecorate: function (name) {
            delete decorators[name];
        }
    });

})(window.decJQ || {}, jQuery);

decJQ.decorate('idPrefix', function (selector) {
    if (typeof selector === 'string' && selector[0] === '#') {
        arguments[0] = selector.replace('#', '#prefix_');
    }

    return arguments;
});

$(function () {
    console.log($('#test').length); //1

    decJQ.undecorate('idPrefix');

    console.log($('#test').length); //0
});

编辑2: 您也可以选择非常简单的东西,例如:

(function ($) {
    //use $ which has been wrapped
})(function () {
    //do some manipulations
    return jQuery.apply(this, arguments);
});

关于javascript - 如何包装 jQuery 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18907888/

相关文章:

javascript - 验证提交按钮上的值 jQuery

javascript - 如何让元素在某个点后停止滚动?

javascript - 如何等待 promise resolve rxjs 过滤器

javascript - jQuery 任务,获取选择的 html 元素的值

javascript - 如何检查 contenteditable 插入符号是否在 { } 内

javascript - Jquery 分离并重新附加到另一个

Javascript/jquery - 添加一个类以在可变位置列出

javascript - 使用 javascript 将自动生成的 HTML 中的字体大小从 px 更改为 em

javascript - 动态添加时 Facebook 社交插件不显示

javascript - fadeIn( ) 不使用我的 css 定位