Запуск функции JavaScript после загрузки окна, включая любые асинхронные загрузки.

В моем приложении есть функция initialise, которую я хочу активировать при выполнении двух условий: 1) загрузилось окно: $(window).load() и 2) загрузился Typekit.

$(window).load(function() {
    try {
        Typekit.load({ active: initialise });
    } catch (e) {}
});

На данный момент этот код ожидает, пока загрузится окно (включая все ресурсы, например изображения), прежде чем он начнет загружать веб-шрифты Typekit, а затем, когда они тоже загрузятся, он инициализируется.

Однако я хочу, чтобы Typekit загружался до загрузки окна. Они должны загружаться асинхронно. Так:

$(window).load(initialise);

try {
    Typekit.load({ active: initialise });
} catch (e) {}

Теперь веб-шрифты загружаются асинхронно, но проблема в том, что мне нужно, чтобы функция initialise запускалась только тогда, когда 1) загрузилось окно: $(window).load() и 2) загрузился Typekit. Иногда окно загружается раньше, чем загрузится Typekit, а иногда наоборот.

Итак, мой вопрос: как я могу вызвать initialise, как только оба моих критерия будут выполнены?


person Community    schedule 28.01.2012    source источник


Ответы (4)


Увеличивайте и проверяйте каждое событие. Как только ready станет положительным, initialize сработает:

   {
        var ready = -1;
        $(window).load(function() {
            if (++ready) initialize();
        });

        try {
            Typekit.load({
                active: function() {
                    if (++ready) initialize();
                }
            });
        } catch (e) {}

        function initialize() {
            //do work
        }
    }
person Brent Anderson    schedule 28.01.2012
comment
Это отличное решение. Не уверен, использовать ли это или пример/ответ, который я только что опубликовал, который использует jQuery $.holdReady. С точки зрения производительности, я бы предположил, что это лучше. - person ; 28.01.2012
comment
Почему странная конструкция ++? Это JavaScript, а не C;) В остальном это решение прекрасно. $.holdReady так же хорош. Производительность в данном случае не имеет значения. Это, вероятно, имеет значение в несколько микросекунд. - person user123444555621; 28.01.2012
comment
@ Pumbaa80, я не понимаю твоего вопроса. ++ — стандартный оператор, а ++ready — допустимое приращение. - person Brent Anderson; 28.01.2012

load() это неправильный метод запуска при загрузке окна. Это ready().

Typekit.load({
    active: function () {
        $(document).ready(initialize);
    }
});

Метод ready() немедленно запустит обратный вызов, если окно уже загружено. Метод load() привязывает обработчик события к событию load DOM, которое в этот момент уже сработало. Таким образом, обработчик никогда не вызывается.

person user123444555621    schedule 28.01.2012
comment
Я считаю, что мне нужно использовать load(), потому что это включает в себя загрузку изображений, которые мне необходимо загрузить перед выполнением моей функции initialise. - person ; 28.01.2012
comment
Итак, я попробовал то, что вы сказали, но изменил его на $(window).load(initialise). К сожалению, кажется, что метод не запускает обратный вызов немедленно, если окно уже загружено, в отличие от ready(). - person ; 28.01.2012

Я нашел решение, использующее jQuery $.holdReady:

$.holdReady(true);

Typekit.load({
    active: function () {
        $.holdReady(false);
    }
});

$window.load(function () {
    $document.ready(initialize);
});
person Community    schedule 28.01.2012

Вы можете использовать setInterval и проверить две переменные, которые будут установлены

var windowLoaded = false, typeKitLoaded = false, myLoadedInterval = null;
$(window).load(function() { windowLoaded = true; if ( myLoadedInterval == null ) beginInterval(); });
try {
    Typekit.load({ active: function() { typeKitLoaded = true; if ( myLoadedInterval == null ) beginInterval(); } });
} catch (e) {}

function beginInterval()
{
    myLoadedInterval = setInterval(function() {
        if ( typeKitLoaded && windowLoaded ) 
        {
            clearInterval(myLoadedInterval);
            initialise();
        } 
    }, 25);
}
person dievardump    schedule 28.01.2012