假设我们需要在第三方页面中嵌入小部件。例如,这个小部件可能使用jquery,因此widget携带一个jquery库。 假设第三方页面也使用jquery但使用不同的版本。 嵌入小部件时如何防止它们之间发生冲突? jquery.noConflict不是一个选项,因为它需要为页面中加载的第一个jquery库调用此方法,这意味着第三方网站应该调用它。这个想法是第三方网站不应该修改或做任何事情,除了将带有src的标记放到小部件中以便使用它。
此外,这不是jquery的问题 - 谷歌闭包库(甚至已编译)可能会作为一个例子。
除了明显的iframe之外,还有哪些解决方案来隔离不同的javascript库? 也许加载javascript为字符串然后eval(通过使用函数('代码到eval'),而不是eval('代码到eval'))它在匿名函数中可能会做到这一点?
答案 0 :(得分:9)
实际上,我认为jQuery.noConflict正是您想要使用的。如果我正确理解了implementation,那么您的代码应如下所示:
(function () {
var my$;
// your copy of the minified jQuery source
my$ = jQuery.noConflict(true);
// your widget code, which should use my$ instead of $
}());
对noConflict
的调用会将全局jQuery
和$
个对象恢复为以前的值。
答案 1 :(得分:4)
Function(...)
在你的函数中创建一个eval,它没有任何好处。
为什么不使用iframe
为第三方内容提供默认沙盒。
对于友好的用户,您可以在他们与您的网页之间共享文字数据,使用parent.postMessage
代替现代浏览器,或者window.name
hack for the olders。
答案 2 :(得分:2)
我建立了一个库来解决这个问题。我不确定它是否会对您有所帮助,因为代码仍然必须知道问题并首先使用库,所以只有在您能够更改代码以使用库时它才有用。
有问题的图书馆名为Packages JS,可以免费下载和使用,因为它是知识共享许可下的开源版。
它基本上是通过在函数内部打包代码来实现的。从这些函数中,您可以将要公开的对象导出到其他包。在使用者包中,您将这些对象导入本地命名空间。如果其他人或甚至您自己多次使用相同的名称并不重要,因为您可以解决歧义。
以下是一个例子:
(文件示例/ greeting.js)
Package("example.greeting", function() {
// Create a function hello...
function hello() {
return "Hello world!";
};
// ...then export it for use by other packages
Export(hello);
// You need to supply a name for anonymous functions...
Export("goodbye", function() {
return "Goodbye cruel world!";
});
});
(文件示例/ ambiguity.js)
Package("example.ambiguity", function() {
// functions hello and goodbye are also in example.greeting, making it ambiguous which
// one is intended when using the unqualified name.
function hello() {
return "Hello ambiguity!";
};
function goodbye() {
return "Goodbye ambiguity!";
};
// export for use by other packages
Export(hello);
Export(goodbye);
});
(文件示例/ ambiguitytest.js)
Package("example.ambiguitytest", ["example.ambiguity", "example.greeting"], function(hello, log) {
// Which hello did we get? The one from example.ambiguity or from example.greeting?
log().info(hello());
// We will get the first one found, so the one from example.ambiguity in this case.
// Use fully qualified names to resolve any ambiguities.
var goodbye1 = Import("example.greeting.goodbye");
var goodbye2 = Import("example.ambiguity.goodbye");
log().info(goodbye1());
log().info(goodbye2());
});
示例/ ambiguitytest.js使用两个库来导出函数再见,但它可以显式导入正确的函数并将它们分配给本地别名以消除歧义。
以这种方式使用jQuery意味着通过在调用Package和Exporting它现在公开给全局范围的对象中包装它的代码来“打包”jQuery。这意味着改变图书馆有点可能不是你想要的,但是如果没有诉诸iframe,我就无法看到。
我计划在下载中包含流行库的'打包'版本,jQuery肯定在列表中,但目前我只有一个打包版本的Sizzle,jQuery的选择器引擎。
答案 3 :(得分:0)
您可以在jQuery上调用Google API的完整网址,而不是寻找没有冲突的方法,以便它可以在应用程序中运行。
答案 4 :(得分:0)
<script src="myjquery.min.js"></script>
<script>window.myjQuery = window.jQuery.noConflict();</script>
...
<script src='...'></script> //another widget using an old versioned jquery
<script>
(function($){
//...
//now you can access your own jquery here, without conflict
})(window.myjQuery);
delete window.myjQuery;
</script>
最重要的一点:
在您自己的jquery和相关插件标签之后立即调用jQuery.noConflict()方法
将结果jquery存储到全局变量中,其名称几乎没有冲突或混淆的可能性
使用旧的版本化jquery加载小部件;
后续是您的逻辑代码。使用一个闭包来获得一个私人的$ for convience。私人$不会与其他jquerys冲突。