2016-05-18 6 views
0

Я пытаюсь написать анонимную функцию javascript, которая динамически загружает jquery и угловую. Однако, когда я запускаю функцию, я продолжаю получать «jQuery не функция». Может кто-нибудь помочь? Вот мой код:jQuery не является функцией анонимной функции

(function() { 

    var jQuery; 
    var jquery_tag = document.createElement('script'); 
    var angular_tag = document.createElement('script'); 

    jquery_tag.setAttribute("type", "text/javascript"); 
    jquery_tag.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"); 

    angular_tag.setAttribute("type", "text/javascript"); 
    angular_tag.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"); 

    jquery_tag.onload = scriptLoadHandler; 
    angular_tag.onload = scriptLoadHandler; 

    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(jquery_tag); 
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(angular_tag); 


    function scriptLoadHandler() { 
    jQuery = window.jQuery 
    main(); 
    } 

    function main() { 
    jQuery(document).ready(function($) { 
     alert('yo'); //this runs 
    }); 
    } 

})(); 

Вот моя скрипка:

https://jsfiddle.net/p7jcofx1/4/

Заранее спасибо!

+1

Можете ли вы обновить свой jsfiddle, чтобы отразить недавние изменения кода? – Matt

+0

Кроме того, где именно вы получаете ошибку '' jQuery - это не функция''? – nem035

+0

Что произойдет, если угловые нагрузки перед jQuery? – apokryfos

ответ

3

scriptLoadHandler() будет работать два раза на основе этого кода:

jquery_tag.onload = scriptLoadHandler; 
angular_tag.onload = scriptLoadHandler; 

Даже если Угловой код указан после кода JQuery, он может загрузить первую, что делает window.jQuery неопределенных в scriptLoadHandler, и вызывая jQuery(document) потерпеть неудачу в main().

Вы можете предотвратить это путем обновления scriptLoadHandler следующим образом:

function scriptLoadHandler() { 
    if(window.jQuery) { 
    jQuery = window.jQuery 
    main(); 
    } 
} 
+0

это решило! также, если вы не возражаете, не могли бы вы подтвердить, что я загружаю jquery и правильно углы/с помощью лучших практик? –

+0

Я честно не знаю, какие лучшие практики для загрузки сценариев динамически, но я не вижу ничего плохого в вашем коде, кроме риска, который может загрузить Angular. –

1

Из угловой документации here

Чтобы использовать jQuery, просто убедитесь, что он загружен до файла angular.js. Вы также можете использовать директиву ngJq, чтобы указать, что jqlite следует использовать через jQuery или использовать определенную версию jQuery, если на странице существует несколько версий.

Вы можете достичь этого, используя следующие:

var jquery_tag = document.createElement('script');   

    jquery_tag.setAttribute("type", "text/javascript"); 
    jquery_tag.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js");   

    jquery_tag.onload = jQueryLoadedHandler;  

    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(jquery_tag);  


    function jQueryLoadedHandler() { 
    //Load angular after jQuery 
    var angular_tag = document.createElement('script'); 
    angular_tag.setAttribute("type", "text/javascript"); 
    angular_tag.setAttribute("src", "https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"); 
    angular_tag.onload = angularLoadedHandler; 
    (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(angular_tag); 
    } 

    function angularLoadedHandler() {   
     main(); //Both jQuery and angular should be loaded 
    } 

    function main() { 
    jQuery(document).ready(function($) { 
     alert('yo'); //this runs 
    }); 
    } 

Updated fiddle

Примечание: Это предложение в случае, если вы хотите angular.js использовать JQuery. Если вы не возражаете против использования jqLite, тогда это не обязательно, и принятый ответ должен работать нормально.