2

问题

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

动机

我有一段 JS 将重用winId连接并传递给 jQuery 的相同变量。而不是写

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

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

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

并且winId在通过 to 之前添加了$


我的尝试

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

(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' 

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

4

5 回答 5

4

这是一个不同的实现:

演示

(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);
});
于 2013-09-20T03:56:42.453 回答
2

根据 Bergi 的建议和他链接到的帖子这是一种方法:

$.fn.extend({
    initCore: $.fn.init,
    init: function (selector, context, rootjQuery) {
        if (typeof selector === 'string' && selector[0] === '#') {
            selector = selector.replace('#', '#' + winId);
        }
        return $.fn.initCore(selector, context, rootjQuery);
    }
});

$.fn.init.prototype = $.fn;

我已经测试过$('#foo')会找到一个以值为winId前缀的 div id,例如 this <div id="1foo"></div>

例如:http: //jsfiddle.net/MfdJS/1/

于 2013-09-20T03:23:27.920 回答
1

将 class="winID" 添加到您的元素中。

使用 $(".winID").find('#someId").css(...) 访问特定元素的 CSS 属性。

使用 $(".winID").css(...) 访问所有 winID 标记元素的 CSS 属性。

于 2013-09-20T04:09:20.783 回答
-1

好的,我刚刚测试过

$('.con'+'tainer')

$('d'+'iv');

var s = 't';
$('.con'+s+'ainer');

并且控制台正在返回正确的值

我相信你正在调用一个带有字符串参数的函数 jQuery(),所以只要你使用正常的语法来构建/附加/构造带有加号的字符串,我认为你是黄金。我很高兴你问了这个问题,因为现在我也知道了

于 2013-09-20T04:14:55.560 回答
-2

这是一件很奇怪的事情。为什么不为 winId 创建一个 CSS 选择器字符串并将其保存为变量?

var foo = '#' + winId;

现在你可以这样做:

$(foo + ', #bar').html("add some content"); 

你打算做的事情会让任何从事这个项目的程序员——包括六个月后的你——在他们使用 $('#bar') 并且它实际上选择 #foo 和 #bar 时完全困惑。

于 2013-09-20T03:58:22.860 回答