4

我不认为这是可以做到的,虽然我知道 requirejs 可以做类似的事情,我想知道这是否可能在 require 之外。

我正在编写一段SaaS JavaScript 代码,很可能需要 jQuery 才能跨浏览器运行。有些网站有,有些没有,但如果他们不使用它,我不想将 jQuery 粘贴在窗口对象上。虽然我可以为我使用 jQuery 的所有东西单独创建替代品......我想知道是否有一种方法可以加载 jQuery 仅在我的闭包内使用。这可能吗?

4

3 回答 3

5

当您加载 jQuery 的标准版本时,默认情况下 jQuery 将自己分配给全局名称 jQuery 和 $。如果您在页面中的闭包文件之前加载您的 jQuery 版本,那么在您的闭包中执行

var $ = jQuery.noConflict(true);

它将撤消您的 jQuery 版本对全局对象所做的任何修改。

然而,值得注意的是,这会产生竞争条件。如果在 jQuery 文件加载和闭包调用之间发生任何事件或超时,jQuery.noConflict(true)它们将意外使用您加载的 jQuery 版本。

另一种方法是编辑您正在使用的 jQuery 文件,以jQuery.noConflict(true)在 jQuery 文件的底部包含对的调用。您可以将结果分配给其他人不会想到使用的任意名称,例如“abcRandomNumberHere”。然后,您可以从闭包中的全局名称中检索您的 jQuery 实例,并将其分配给名为 jQuery 和/或 $ 的局部变量,并在那时删除全局引用。

// Your jQuery file on your server
// ...
// End of file:
someRandomGlobalName = jQuery.noConflict(true);

// The file that contains your closure:
(function() {
    var $, jQuery;
    $ = jQuery = someRandomGlobalName;
    delete window.someRandomGlobalName;

    // Your code that uses jQuery here
} ());

这是 RequireJS 将 jQuery 排除在全局命名空间之外所做的粗略近似。最新版本的 jQuery 具有内置代码,可以检测脚本加载器(如 RequireJS)的存在,而不是分配给全局名称 jQuery 将对自身的引用传递给 RequireJS 并保持全局对象不变。这样 RequireJS 在内部包含了对 jQuery 的引用,但是 global.requirejs 变量被修改了。

为您的 jQuery 版本创建自己的非冲突全局名称并关闭“会合”类似于 RequireJS 的功能。RequireJS 使用的名称是“全局名称”:requirejs.s.contexts._.jQuery(不完全是,但类似这样)。

于 2013-10-08T19:31:44.093 回答
3

调用jQuery.noConflict(true),它将重新分配$jQuery它所在的位置。

然后,您可以将上述表达式返回的引用传递到您的闭包中。

(function(jQuery) {

})(jQuery.noConflict(true));
于 2013-10-08T19:23:36.807 回答
2

是的,调用jQuery.noConflict(true)将完全删除 jquery 从全局命名空间中添加的任何内容,将其恢复为以前允许冲突库和/或多个版本的 jQuery 的内容。

<script src="jquery.min.js"></script>
<script>
(function($){
    $("el").doSomething();
})(jQuery.noConflict(true));
</script>
于 2013-10-08T19:25:58.043 回答