Как встроить виджет JavaScript, который зависит от jQuery в неизвестную среду

Я разрабатываю виджет JavaScript, который зависит от jQuery. Виджет может или не может быть загружен на страницу, которой уже загрузили jQuery. Существует много проблем, которые подходят в этом случае...

  1. Если веб-страница не имеет jQuery, я должен загрузить свой собственный jQuery. Кажется, существует тонкая проблема синхронизации при выполнении этого, как бы то ни было. Например, если мой виджет загружается и выполняется, прежде чем jQuery закончен, загрузившись и выполнившись, я получаю a jQuery is not defined ошибка.

  2. Если веб-страница действительно имеет jQuery, я могу обычно работать с ним. Если бы версия jQuery стара, однако, я хотел бы загрузить свое собственное. Если я действительно загружаю свое собственное, однако, я должен сделать это таким способом как относительно не, топают на их $ переменная. Если я установил jQuery.noConflict() и любой из их сценариев зависит от $, тогда я только что повредил их страницу.

  3. Если веб-страница пользуется другой библиотекой JavaScript (например, прототип), я должен был быть чувствительным из прототипа $ переменная также.

Из-за всего вышеупомянутого кажется легче не зависеть от jQuery. Но прежде чем я иду по той дороге, которая включит главным образом перезапись моего кода виджета, я хотел попросить совет сначала.

Основной скелет моего кода, включая ошибку синхронизации и иногда $ ошибки, следует:

<script type="text/javascript" charset="utf-8">
// <![CDATA
 if (typeof jQuery === 'undefined') {
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '{{ URL }}/jquery.js';
  head.appendChild(script);
 }
// ]]>
</script>
<script type="text/javascript" src="{{ URL }}/widget.js"></script>

Мой виджет имеет следующую структуру:

(function($) {
 var mywidget = {
  init: function() {
   ...
  }
 };
 $(document).ready(function() {
   mywidget.init();
 });
})(jQuery);

Если существуют какие-либо указатели или ресурсы для достижения виджета, который может работать во всех упомянутых средах, они значительно ценились бы.

61
задан robhudson 31 January 2010 в 03:22
поделиться

4 ответа

После просмотра некоторых ответов и указателей, а также нахождения некоторых полезных хакеров jQuery, я обнаружил что-то вроде следующего:

(function(window, document, version, callback) {
    var j, d;
    var loaded = false;
    if (!(j = window.jQuery) || version > j.fn.jquery || callback(j, loaded)) {
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "/media/jquery.js";
        script.onload = script.onreadystatechange = function() {
            if (!loaded && (!(d = this.readyState) || d == "loaded" || d == "complete")) {
                callback((j = window.jQuery).noConflict(1), loaded = true);
                j(script).remove();
            }
        };
        (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script);
    }
})(window, document, "1.3", function($, jquery_loaded) {
    // Widget code here
});

Это загрузит jQuery, если он еще не загружен, и инкапсулирует его в обратный вызов, чтобы он не конфликтовал с уже существующим jQuery на странице. Также проверяется наличие минимальной версии или загружается известная версия -- в данном случае, v1.3. Она посылает булевое значение обратному вызову (моему виджету) о том, был ли загружен jQuery, в случае, если необходимо сделать какие-либо триггеры. И только после загрузки jQuery вызывает мой виджет, передавая в него jQuery.

97
ответ дан 24 November 2019 в 17:18
поделиться

Я бы загрузил источник jQuery и изменил объект jQuery на другой (jQueryCustom).

А затем найду экземпляр, который устанавливает символ $ в качестве объекта jQuery, и прокомментирую эту рутину.

Не знаю, насколько это может быть просто или трудно, но я бы обязательно попробовал.

(Также, проверьте второй вариант, так как он неплохой, сайт, на котором будет выполняться виджет, может иметь версию jQuery старше той, которая вам нужна).

EDIT: Я только что проверил источник. Вам просто нужно заменить jQuery на другую строку (jQcustom например). Затем попробуйте прокомментировать эту строку:

_$ = window.$

И вы сделаете ссылку на пользовательский jQuery следующим образом:

jQcustom("#id").attr(...)
-1
ответ дан 24 November 2019 в 17:18
поделиться

Можете ли вы использовать document.write (), чтобы необязательно добавить сценарий jQuery на страницу? Это должно заставить jQuery загружать синхронно. Попробуйте это:

<script type="text/javascript" charset="utf-8">
// <![CDATA
 if (typeof jQuery === 'undefined') {
  document.write('<script src="{{ URL }}/jquery.js"><' + '/script>');
 }
// ]]>
</script>
<script type="text/javascript" src="{{ URL }}/widget.js"></script>

Если вы хотите сделать проверку jQuery внутри вашего списка виджета, я полагаю, что следующие работы поперечины браузер:

(function() {
 function your_call($) {
  // your widget code goes here
 }
 if (typeof jQuery !== 'undefined') your_call(jQuery);
 else {
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '{{ URL }}/jquery.js';
  var onload = function() {
   if (!script.readyState || script.readyState === "complete") your_call(jQuery);
  }
  if ("onreadystatechange" in script) script.onreadystatechange = onload;
  else script.onload = onload;
  head.appendChild(script);
 }
})()
1
ответ дан 24 November 2019 в 17:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: