загрузка в мой плагин внешних библиотек JavaScript - PullRequest
1 голос
/ 19 марта 2012

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

<script type="text/javascript" src="path/to/plugin.js"></script>
<script type="text/javascript">
PLUGIN.init({
    "param1": "foo",
    "parma2": 33, 
    "include": {"jquery": 0, "googlemaps": 0}
});
</script>

В моем плагине скрипт

var PLUGIN = {
    "init": function(obj) {
        if (obj.include.googlemaps !== 0) {
            document.write('<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&v=3.6">\x3C/script>');
        }

        if (obj.include.jquery !== 0) {
            document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js">\x3C/script>');
        }

        .. do more things ..
}

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

document.write('<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true&v=3.6">\x3C/script>');
document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js">\x3C/script>');

var PLUGIN = {
    "init": function(obj) {         
        .. do more things ..
}

но теперь пользователь не может контролировать загрузку библиотек или не загружать их. Предложения? Обходные?

Обновление: Спасибо за предложения, вы все, но пока радости нет. Вот что я делаю и что происходит. Поскольку я потенциально загружаю 0 или более сценариев (пользователь может по своему усмотрению решить, какие сценарии не нужно загружать), я сделал свой код следующим образом:

"importLib": function(libPath, callback) {
    var newLib = document.createElement("script");

    if (callback !== null) {
        newLib.onload = callback;
    }
    newLib.src = libPath;

    document.head.appendChild(newLib);
},

"init": function(obj) {
    var scripts = [];
    if (obj.include.googlemaps !== 0) {
        scripts.push("http://maps.google.com/maps/api/js?sensor=true&v=3.6");
    }

    if (obj.include.jquery !== 0) {
        scripts.push("http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js");
    }

    if (obj.include.anotherlib !== 0) {
        scripts.push("http://path/to/another/lib.js");
    }

    var len_scripts = scripts.length,
        callback = null;

    if (len_scripts > 0) {
        for (var i = 0; i < len_scripts; i++) {

            // add callback only on the last lib to be loaded
            if (i == len_scripts - 1) {
                callback = function() { startApp(obj) };
            }

            importLib(scripts[i], callback);
        }
    }

    // Start the app rightaway if no scripts need to be loaded
    else {
        startApp(obj);
    }
},

"startApp": function(obj) {
}

В результате Firefox выдает ошибку attempt to run compile-and-go script on a cleared scope, и Safari не получает эту ошибку, но ничего не загружает. Как ни странно, консоль ошибок Safari не показывает никаких ошибок вообще. Похоже, ошибка Firefox вызвана строкой document.head.appendChild(newLib);, которая, если я прокомментирую, ошибка исчезнет, ​​но, конечно, веб-страница не загружается правильно.

Ответы [ 3 ]

1 голос
/ 19 марта 2012

Вы должны добавить каждый скрипт в качестве узла DOM и использовать атрибут onload, чтобы выполнить действие после завершения загрузки.

function importLib(libPath, callback) {
    var newLib = document.createElement("script");
    newLib.onload = callback;
    newLib.src = libPath;
    document.head.appendChild(newLib);
}

Выше аргумент libPath - это URL-адрес библиотеки, а аргумент callback - это функция, вызываемая по завершении загрузки. Вы можете использовать его следующим образом:

importLib("http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js", function() {
   alert("jquery loaded!");
   nowDoSomething(aboutIt); 
});

Кстати: в целом, document.write не является хорошим решением для большинства проблем (но я не скажу, никогда правильное решение - есть исключения из каждого правила).

0 голосов
/ 13 ноября 2013

Я столкнулся с той же проблемой.Одним из обходных путей, если вы пишете свой сайт в .NET, является условное написание ссылки на скрипт перед загрузкой страницы из кода.Моя проблема в том, что когда удаленные пользователи получают доступ к моему приложению через VPN, оно блокирует доступ к Интернету, поэтому на карты Google нельзя ссылаться.Это предотвращает загрузку остальной части страницы в разумные сроки.Я пытался управлять ссылкой на скрипт библиотеки Google Maps с помощью команды jQuery getScript (), но, как вы узнали, последующий код конфигурации карт Google запускается до обращения к внешней библиотеке.Google Maps из кода позади вместо:

VB (код сзади):

'if VPN mode is not enable, add the external google maps script reference (this speeds up the interface when using VPN significantly)
    If Session("VPNMode") = False Then
        Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder()
        sb.AppendLine("")
        sb.AppendLine("<script type='text/javascript'")
        sb.Append(" src='http://maps.google.com/maps/api/js?v=3&sensor=false'>")
        sb.Append("</script>")

        Dim header As LiteralControl = New LiteralControl
        header.Text = sb.ToString()
        Me.Page.Header.Controls.Add(header)
    End If

Сценарий на стороне клиента (JavaScript):

<script type='text/javascript'>
    $(function () {

        if ($("input[name*='VPN']").is(":checked"))
        { }

        else {
            loadGoogleMap()
        }
    });
    function loadGoogleMap() {

        hazsite = new google.maps.LatLng(hazLat, hazLong);
        map = new google.maps.Map(document.getElementById('map_canvas'), { zoom: 18, center: hazsite, mapTypeId: google.maps.MapTypeId.SATELLITE });
        var marker = new google.maps.Marker({
            position: hazsite,
            map: map,
            title: "Site Location"
        });
    }
</script>
0 голосов
/ 20 марта 2012

вышеприведенное решение будет работать в современных браузерах, но для IE 7/8 вы можете добавить немного дополнительного кода, что-то вроде этого:

function importLib(libPath, callback) {
    var newLib = document.createElement("script");
    if (navigator.userAgent.indexOf('MSIE') !== -1) {
        newLib.onreadystatechange = function () {// this piece is for IE 7 and 8
           if (this.readyState == 'complete') {
              callback();
           }
        };
    } else {
        newLib.onload = callback;
    }
    newLib.src = libPath;
    document.head.appendChild(newLib);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...