Загрузите jQuery с помощью Javascript и используйте jQuery

85

Я добавляю библиотеку jQuery в дом, используя:

 var script = document.createElement('script');
 script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
 script.type = 'text/javascript';
 document.getElementsByTagName('head')[0].appendChild(script);

Однако когда я бегу:

jQuery(document).ready(function(){...

Консоль сообщает об ошибке:

Uncaught ReferenceError: jQuery is not defined

Как мне динамически загружать jQuery, а также использовать его, когда он находится в dom?

ThomasReggi
источник
2
Есть ли причина, по которой вы хотите сделать это по сравнению с более оптимизированным способом?
Code Maverick
Некоторые ответы на этот вопрос могут вам помочь - stackoverflow.com/questions/7474354/…
mrtsherman
@ Скотт Да. У меня есть приложение, в котором при установке загружаются как jquery, так и скрипт. Мне нужно загрузить jquery в скрипт, чтобы jquery не нарушал темы пользователей. Мне нужно условно загрузить javascript на определенную веб-страницу в их теме. Пожалуйста, просто поверьте мне в этом.
ThomasReggi
Почему jQuery нарушает темы пользователей? Если загрузка jQuery (которая не влияет на css) может сломать темы, вы делаете что-то очень неправильно.
Андерс Торнблад
Хороший вопрос, но что, если они используют старую версию jQuery или другую библиотеку?
ThomasReggi

Ответы:

140

Здесь есть рабочий JSFiddle с небольшим примером, который демонстрирует именно то, что вы ищете (если я не неправильно понял ваш запрос) : http://jsfiddle.net/9N7Z2/188/

Есть несколько проблем с этим методом динамической загрузки javascript. Когда дело доходит до самых базовых фреймворков, таких как jQuery, вы, вероятно, действительно хотите загружать их статически, потому что в противном случае вам пришлось бы написать целую структуру загрузки JavaScript ...

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

// Immediately-invoked function expression
(function() {
    // Load the script
    var script = document.createElement("SCRIPT");
    script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
    script.type = 'text/javascript';
    script.onload = function() {
        var $ = window.jQuery;
        // Use $ here...
    };
    document.getElementsByTagName("head")[0].appendChild(script);
})();

Просто помните, что если вам нужно поддерживать действительно старые браузеры, такие как IE8, loadобработчики событий не выполняются. В этом случае вам нужно будет опросить о существовании window.jQueryповторного использования window.setTimeout. Здесь есть рабочий JSFiddle с этим методом: http://jsfiddle.net/9N7Z2/3/

Есть много людей, которые уже сделали то, что вам нужно. Ознакомьтесь с некоторыми из существующих фреймворков загрузчика JavaScript, например:

Андерс Торнблад
источник
Это решение работает, кроме WordPress. В любом случае это можно изменить, чтобы загрузить jQuery в другой объект?
Kraang Prime
@SanuelJackson В Wordpress вы должны использовать wp_enqueue_script()функцию для правильного включения jQuery. Документация: codex.wordpress.org/Function_Reference/wp_enqueue_script Дополнительная информация здесь: digwp.com/2009/06/including-jquery-in-wordpress-the-right-way или здесь: digwp.com/2011/09/using- вместо jquery-in-wordpress
Андерс Торнблад
Да, я говорил, что приведенный выше код не работает в Wordpress, потому что он также загружает jQuery асинхронно. Даже если этот скрипт загружается в самом низу страницы (непосредственно перед закрытием html), jQuery не полностью «инициализирован», поэтому он не видит загруженного jQuery и продолжает загружаться и выполнять обратный вызов. После загрузки он сбивает другие вещи, которые были загружены асинхронно, которые зависели от загрузки jQuery другим способом (например, $, jQuery и т. Д.) Или от другой версии jQuery.
Kraang Prime
В других случаях, которые я пробовал, это здорово. Просто отмечал единственную вопиющую проблему с этим. Если бы это можно было как-то настроить, но я не думаю, что это возможно, поскольку это зависит от обнаружения jQuery, который, конечно, не загружен и, следовательно, может действовать только по логике - если нет jquery ... тогда ..
Kraang Prime
1
Вам не нужно проводить опрос, вы можете использовать только одну строку, чтобы дождаться загрузки jquery, используя событие .onload, например stackoverflow.com/a/42013269/3577695
aljgom 02
7

Есть другой способ динамической загрузки jQuery ( исходный код ). Вы также можете использовать

document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>');

Это считается плохой практикой document.write, но для полноты картины полезно упомянуть об этом.

См. Почему document.write считается «плохой практикой»? по причинам. Про то , что document.writeдействительно блокирует страницы от загрузки других assests, поэтому нет необходимости создавать функцию обратного вызова.

Якоб ван Линген
источник
1
Я прочитал документ, с которым вы связались, и для моего варианта использования загрузки более старой библиотеки jQuery для IE8 использование document.write кажется нормальным. У меня пока все работает хорошо.
Алан
Это самый простой способ сделать это. Будет ли проблема делать это в начале довольно большого скрипта, который представляет собой отдельный файл JS? Это слишком хорошо, чтобы отказываться от этого.
Агустин Ладо,
6

Сайт Encosia рекомендует:

<script type="text/javascript" 
        src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
  // You may specify partial version numbers, such as "1" or "1.3",
  //  with the same result. Doing so will automatically load the 
  //  latest version matching that partial revision pattern 
  //  (e.g. 1.3 would load 1.3.2 today and 1 would load 1.7.2).
  google.load("jquery", "1.7.2");

  google.setOnLoadCallback(function() {
    // Place init code here instead of $(document).ready()
  });
</script>

Но даже он признает, что когда речь заходит об оптимальной производительности, это не сравнится со следующим:

    <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script type="text/javascript"> window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js">\x3C/script>')</script>
    <script type="text/javascript" src="scripts.js"></scripts>
</body>
</html>
Code Maverick
источник
Я могу загрузить только один javascript. Это означало бы, что мне пришлось бы динамически загружать google jsapi с помощью этого загрузочного jquery? Кажется излишним для моего варианта использования.
ThomasReggi
1
Это то, что делает загрузчик jQuery. Вы ссылаетесь на загрузчик, и загрузчик вставляет jQuery в документ за вас.
Code Maverick
3

Вам нужно запустить свой код ПОСЛЕ завершения загрузки jQuery

var script = document.createElement('script'); 
document.head.appendChild(script);    
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
script.onload = function(){
    // your jQuery code here
} 

или если вы используете его в асинхронной функции, вы можете использовать awaitв приведенном выше коде

var script = document.createElement('script'); 
document.head.appendChild(script);    
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
await script.onload
// your jQuery code here

Если вы хотите сначала проверить, существует ли уже jQuery на странице, попробуйте это

Aljgom
источник
0

Причина, по которой вы получаете эту ошибку, заключается в том, что JavaScript не ждет загрузки скрипта, поэтому при запуске

jQuery(document).ready(function(){...

нет гарантии, что сценарий готов (и никогда не будет).

Это не самое элегантное решение, но оно работает. По сути, вы можете каждую секунду проверять, есть ли объект jQuery и запускать функцию, когда она загружена с вашим кодом. Я бы добавил тайм-аут (скажем, clearTimeout после того, как он был запущен 20 раз), чтобы остановить выполнение проверки на неопределенный срок.

var jQueryIsReady = function(){
    //Your JQuery code here
}

var checkJquery = function(){
    if(typeof jQuery === "undefined"){
        return false;
    }else{
        clearTimeout(interval);
        jQueryIsReady();
    }
}
var interval = setInterval(checkJquery,1000);
Marteljn
источник
0

Используя require.js, вы можете сделать то же самое более безопасным способом. Вы можете просто определить свою зависимость от jquery, а затем выполнить нужный код, используя зависимость, когда она загружена, не загрязняя пространство имен:

Я обычно рекомендую эту библиотеку для управления всеми зависимостями от Javascript. Это просто и позволяет эффективно оптимизировать загрузку ресурсов. Однако есть некоторые меры предосторожности, которые вам могут потребоваться при использовании его с JQuery. Мой любимый способ борьбы с ними объясняется в этом репозитории на github и отражается в следующем примере кода:

<title>jQuery+RequireJS Sample Page</title>
   <script src="scripts/require.js"></script>
   <script>
   require({
       baseUrl: 'scripts',
       paths: {
           jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min'
       },
       priority: ['jquery']
    }, ['main']);
    </script>
txominpelu
источник
0

HTML:

<html>
  <head>

  </head>
  <body>

    <div id='status'>jQuery is not loaded yet.</div>
    <input type='button' value='Click here to load it.' onclick='load()' />

  </body>
</html>   

Сценарий:

   <script>

        load = function() {
          load.getScript("jquery-1.7.2.js");
          load.tryReady(0); // We will write this function later. It's responsible for waiting until jQuery loads before using it.
        }

        // dynamically load any javascript file.
        load.getScript = function(filename) {
          var script = document.createElement('script')
          script.setAttribute("type","text/javascript")
          script.setAttribute("src", filename)
          if (typeof script!="undefined")
          document.getElementsByTagName("head")[0].appendChild(script)
        }

        </script>
кодировщик
источник
Сложная часть - запустить скрипт после того, как скрипт загружен ... И почему скрипт может быть неопределенным! ??
Андерс Торнблад