17

假设我们需要在第三方页面中嵌入一个小部件。例如,此小部件可能使用 jquery,因此小部件本身带有一个 jquery 库。假设第三方页面也使用 jquery,但版本不同。嵌入小部件时如何防止它们之间的冲突?jquery.noConflict 不是一个选项,因为它需要为页面中加载的第一个 jquery 库调用此方法,这意味着第三方网站应该调用它。这个想法是第三方网站不应该修改或做任何事情,除了将带有 src 的标签放到小部件中以便使用它。

这也不是 jquery 的问题——谷歌闭包库(甚至已编译)可以作为一个例子。

除了明显的 iframe 之外,还有哪些解决方案可以隔离不同的 javascript 库?也许将javascript作为字符串加载,然后在匿名函数中进行eval(通过使用函数('code to eval'),而不是eval('code to eval'))可能会成功?

4

5 回答 5

9

实际上,我认为jQuery.noConflict正是您想要使用的。如果我正确理解了它的实现,您的代码应该如下所示:

(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$对象恢复到它们以前的值。

于 2010-11-12T15:17:03.577 回答
4

Function(...)在你的函数中进行 eval ,它并没有更好。

为什么不使用iframe它们为第三方内容提供默认沙盒。

对于友好的人,您可以在他们和您的页面之间共享文本数据,parent.postMessage用于现代浏览器或老年人的window.name黑客。

于 2010-11-12T15:17:14.660 回答
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());
});

example/ambiguitytest.js 使用了两个库,它们都导出函数再见,但它可以显式导入正确的库并将它们分配给本地别名以消除它们之间的歧义。

以这种方式使用 jQuery 意味着通过将其代码包装在对 Package 的调用中并导出它现在暴露给全局范围的对象来“打包”jQuery。这意味着稍微改变一下库,这可能不是您想要的,但是很遗憾,如果不求助于 iframe,我就无法解决这个问题。

我计划在下载中包含流行库的“打包”版本,jQuery 肯定在列表中,但目前我只有 jQuery 的选择器引擎 Sizzle 的打包版本。

于 2011-02-22T14:16:16.877 回答
0

与其寻找没有冲突的方法,您可以很好地在 jQuery 上调用 Google API 的完整 URL,以便它可以在应用程序中工作。

于 2010-11-12T13:31:38.040 回答
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>

最重要的几点:

  1. 在您自己的 jquery 和相关插件标签之后立即调用 jQuery.noConflict() 方法

  2. 将结果 jquery 存储到全局变量中,名称几乎不会发生冲突或混淆

  3. 使用旧版本的 jquery 加载您的小部件;

  4. 跟进的是你的逻辑代码。为方便起见,使用闭包获取私有 $。私有 $ 不会与其他 jquery 冲突。

  5. 您最好不要忘记删除全局临时变量。
于 2015-03-18T03:35:19.820 回答