Как изолировать разные библиотеки JavaScript на одной странице? - PullRequest
15 голосов
/ 12 ноября 2010

Предположим, нам нужно встроить виджет в стороннюю страницу. Этот виджет может использовать, например, jquery, поэтому виджет несет с собой библиотеку jquery. Предположим, что сторонняя страница также использует jquery, но другую версию. Как предотвратить конфликт между ними при встраивании виджетов? jquery.noConflict не является опцией, потому что требуется вызывать этот метод для первой библиотеки jquery, которая загружена на странице, и это означает, что сторонний веб-сайт должен вызывать ее. Идея заключается в том, что сторонний сайт не должен вносить поправки или делать что-либо в сторону, добавляя тег с src к виджету, чтобы использовать его.

Кроме того, это не проблема, в частности, с jquery - в качестве примера может быть использована библиотека закрытия Google (даже скомпилированная).

Какие существуют решения для изоляции различных библиотек JavaScript помимо очевидного iframe? Может быть, загрузка javascript в виде строки и затем eval (с использованием Function ('code to eval'), а не eval ('code to eval')), которую он в анонимной функции может решить?

Ответы [ 5 ]

9 голосов
/ 12 ноября 2010

На самом деле, я думаю, 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 и $ до прежнихценности.

4 голосов
/ 12 ноября 2010

Function(...) делает оценку внутри вашей функции, не лучшедля дружественных вы можете обмениваться текстовыми данными между ними и своей страницей, используя parent.postMessage для современного браузера или window.name хак для пожилых людей.

2 голосов
/ 22 февраля 2011

Я построил библиотеку, чтобы решить эту проблему. Конечно, я не уверен, поможет ли это вам, потому что код все еще должен знать о проблеме и, в первую очередь, использовать библиотеку, так что это поможет, только если вы сможете изменить свой код для использования библиотеки.

Данная библиотека называется Packages JS и может быть загружена и использована бесплатно, так как она является Open Source по лицензии Creative Commons.

Это в основном работает путем упаковки кода внутри функций. Из этих функций вы экспортируете те объекты, которые хотите выставить в другие пакеты. В потребительских пакетах вы импортируете эти объекты в локальное пространство имен. Не имеет значения, если кто-то еще или даже вы сами используете одно и то же имя несколько раз, потому что вы можете устранить неоднозначность.

Вот пример:

(пример файла / приветствие.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 таким образом будет означать «упаковку» jQuery путем обертывания его кода в вызов Package и экспорта объектов, которые он теперь предоставляет в глобальную область. Это означает, что нужно немного изменить библиотеку, что, возможно, не то, что вам нужно, но, увы, нет другого пути, который я могу увидеть, не прибегая к iframes.

Я планирую включить в пакет «упакованные» версии популярных библиотек, и jQuery определенно находится в списке, но на данный момент у меня есть только упакованная версия Sizzle, механизма выбора jQuery.

0 голосов
/ 18 марта 2015
<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.noConflict () НЕМЕДЛЕННО ПОСЛЕ ваших собственных тегов jquery и связанных плагинов

  2. сохранить результат jquery в глобальной переменной с именем, которое вряд ли может конфликтовать или сбивать с толку

  3. загрузить ваш виджет, используя старый версионный jquery;

  4. отслеживает ваши логические коды.используя закрытие, чтобы получить частный $ для удобства.Закрытый $ не будет конфликтовать с другими jquerys.

  5. Вам лучше не забыть удалить глобальную временную переменную.
0 голосов
/ 12 ноября 2010

Вместо поиска таких методов, как отсутствие конфликтов, вы можете очень хорошо назвать полный URL-адрес API Google в jQuery, чтобы он мог работать в приложении.

...