Букмарклет дождаться загрузки Javascript

У меня есть букмарклет, который загружает jQuery и некоторые другие библиотеки js.

Как я:

  • Подождите, пока библиотека javascript, которую я использую, не будет доступна/загружена. Если я попытаюсь использовать скрипт до того, как он завершит загрузку, например, используя функцию $ с jQuery до его загрузки, возникнет неопределенное исключение.
  • Убедитесь, что загружаемый мной букмарклет не будет кэширован (без использования заголовка сервера или, очевидно, из-за того, что это файл javascript: метатег)

Кто-нибудь знает, работает ли onload для динамически добавляемого javascript в IE? (чтобы опровергнуть это сообщение)

Какое самое простое решение, самое чистое решение этих проблем?


person cgp    schedule 16.04.2009    source источник
comment
Подождите, пока библиотека javascript не будет доступна, пожалуйста, уточните это. Чего же ты ждешь?   -  person Josh Stodola    schedule 16.04.2009


Ответы (4)


Это зависит от того, как вы на самом деле загружаете jQuery. Если вы добавляете элемент скрипта на страницу, вы можете использовать тот же метод, который jQuery использует для динамической загрузки скрипта.

РЕДАКТИРОВАНИЕ: я выполнил домашнее задание и фактически извлек функцию loadScript из кода jQuery для использования в вашем букмарклете. Это может быть полезно для многих (в том числе и для меня).

function loadScript(url, callback)
{
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");
    script.src = url;

    // Attach handlers for all browsers
    var done = false;
    script.onload = script.onreadystatechange = function()
    {
        if( !done && ( !this.readyState 
                    || this.readyState == "loaded" 
                    || this.readyState == "complete") )
        {
            done = true;

            // Continue your code
            callback();

            // Handle memory leak in IE
            script.onload = script.onreadystatechange = null;
            head.removeChild( script );
        }
    };

    head.appendChild(script);
}


// Usage: 
// This code loads jQuery and executes some code when jQuery is loaded
loadScript("https://code.jquery.com/jquery-latest.js", function()
{
    $('my_element').hide();
});
person Vincent Robert    schedule 16.04.2009
comment
вам не нужно указывать type=text/javascript? - person vsync; 14.09.2009
comment
уже нет. В настоящее время браузеры предполагают, что нетипизированные скрипты являются javascript. - person joeytwiddle; 20.12.2010
comment
Они предполагают это, но считается ли это правильной формой? - person devios1; 19.03.2012
comment
как мы можем обернуть это, чтобы проверить, загружена ли страница jquery (и определенная версия) - person Adi; 15.03.2013
comment
Подробнее: nczonline. сеть/блог/2009/07/28/ - person Bryan Downing; 22.10.2014
comment
Это хорошо работает, спасибо. Стоит отметить, что моя страница была на https и не загружала jquery из домена http. - person Carlton; 18.08.2016
comment
Перешел на HTTPS, не вижу смысла сейчас использовать HTTP. - person Vincent Robert; 19.08.2016

Чтобы ответить на ваш первый вопрос: Javascript интерпретируется последовательно, поэтому любой следующий код букмарклета не будет выполняться до тех пор, пока библиотека не будет загружена (при условии, что библиотека была успешно интерпретирована - никаких синтаксических ошибок).

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

url = 'jquery.js?x=' + new Date().getTime();
person Josh Stodola    schedule 16.04.2009
comment
Судя по всему, динамически добавляемый javascript работает не так, как вы описываете. Элемент добавляется DOM-функцией addElement и немедленно возвращается. onLoad помогает, но меня беспокоит этот пост: answers.google.com/answers/ просмотр потока?id=595949 - person cgp; 16.04.2009
comment
Ваш комментарий не точен, особенно когда дело доходит до этого вопроса. altCognito описал проблему, позвольте мне сделать это немного яснее. Если ваш сценарий динамически добавляет тег сценария, содержимое динамического тега не будет анализироваться до тех пор, пока вы не выйдете из текущего тега сценария. - person Juan Mendes; 03.12.2010

Я обратил внимание, что в Chrome порядок загрузки скриптов не определен при использовании техники @Vincent Robert. В этом случае поможет небольшая модификация:


(function() {
    var callback = function() {
        // Do you work
    };
        // check for our library existence
    if (typeof (MyLib) == 'undefined') {
        var sources = [
                'http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js',
            'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js',
            'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js',
            'http://myhost.com/javascripts/mylib.min.js'];

        var loadNextScript = function() {
            if (sources.length > 0) {
                var script = document.createElement('script');
                script.src = sources.shift();
                document.body.appendChild(script);

                var done = false;
                script.onload = script.onreadystatechange = function() {
                    if (!done
                            && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) {
                        done = true;

                        // Handle memory leak in IE
                        script.onload = script.onreadystatechange = null;

                        loadNextScript();
                    }
                }
            } else {
                callback();
            }
        }
        loadNextScript();

    } else {
        callback();
    }
})();
person Michael Spector    schedule 04.06.2011

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

person cgp    schedule 16.04.2009