выполнить функцию после полной загрузки страницы


121

Я использую следующий код для выполнения некоторых операторов после загрузки страницы.

 <script type="text/javascript">
    window.onload = function () { 

        newInvite();
        document.ag.src="b.jpg";
    }
</script>

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


1
Не могли бы вы добавить демонстрацию на JSFiddle.net ?
Some Guy

2
Не могли бы вы использовать jQuery? Если так, попробуйте$(window).load()
Мэтт Хинцке

Да, не могли бы вы объяснить, что именно не работает? Вы получаете сообщение об ошибке или, возможно, вызываете alertфункцию до перерисовки окна (чтобы оно выглядело так, как будто оно вызывается перед загрузкой)? Код выглядит нормально, и принуждение пользователей к загрузке больших библиотек, вероятно, не решит эту проблему и не упростит диагностику.
Джеффри Суини,


Когда я говорю, что это не работает, я имею в виду, что функция запускается, даже если загружаются некоторые изображения.
Нирадж Кумар,

Ответы:


166

это может сработать для вас:

document.addEventListener('DOMContentLoaded', function() {
   // your code here
}, false);

или если вам удобно с jquery,

$(document).ready(function(){
// your code
});

$(document).ready()запускается в DOMContentLoaded, но это событие не запускается последовательно среди браузеров. Вот почему в jQuery, скорее всего, будут реализованы сложные обходные пути для поддержки всех браузеров. И это очень затруднит «точное» моделирование поведения с использованием простого Javascript (но, конечно, не невозможно).

как предложили Джеффри Суини и Дж. Торрес, я думаю, что лучше иметь setTimeoutфункцию, прежде чем запускать функцию, как показано ниже:

setTimeout(function(){
 //your code here
}, 3000);

12
jQuery не readyбудет делать то, что запросил OP. readyсрабатывает при загрузке DOM, а не после загрузки элементов. loadсработает после завершения загрузки / рендеринга элементов.
Хайме Торрес,

Похоже, OP хочет, чтобы все элементы были загружены полностью, а не только HTML.
Джеффри Суини,

3
@shreedhar, или он мог бы использовать подходящий инструмент для работы ( load).
Хайме Торрес,

14
setTimeoutплохая идея. Он полагается на загрузку страницы менее 3 секунд (или n секунд в зависимости от того, какое значение вы выберете). Если загрузка занимает больше времени, она не будет работать, а если страница загружается быстрее, ей придется ждать без причины.
JJJ

1
@ChristianMatthew its useCapture Если true, useCapture указывает, что пользователь желает инициировать захват. После запуска захвата все события указанного типа будут отправлены зарегистрированному прослушивателю перед отправкой любому объекту EventTargets под ним в дереве DOM. События, которые поднимаются вверх по дереву, не запускают прослушиватель, назначенный для использования захвата. См. Подробное объяснение в DOM Level 3 Events .
Шридхар

52

JavaScript

document.addEventListener('readystatechange', event => { 

    // When HTML/DOM elements are ready:
    if (event.target.readyState === "interactive") {   //does same as:  ..addEventListener("DOMContentLoaded"..
        alert("hi 1");
    }

    // When window loaded ( external resources are loaded too- `css`,`src`, etc...) 
    if (event.target.readyState === "complete") {
        alert("hi 2");
    }
});

то же самое для jQuery:

$(document).ready(function() {   //same as: $(function() { 
     alert("hi 1");
});

$(window).load(function() {
     alert("hi 2");
});





ПРИМЕЧАНИЕ. - Не используйте приведенную ниже разметку (потому что она перезаписывает другие объявления того же типа):

document.onreadystatechange = ...

1
поддерживается
ли

Этот ответ намного лучше других. +1
Xydez

Очень хорошо! Спасибо.
Фарзин Kanzi

34

Если вы можете использовать jQuery, посмотрите на load . Затем вы можете настроить свою функцию на запуск после того, как ваш элемент завершит загрузку.

Например, рассмотрим страницу с простым изображением:

<img src="book.png" alt="Book" id="book" />

Обработчик событий можно привязать к изображению:

$('#book').load(function() {
  // Handler for .load() called.
});

Если вам нужно загрузить все элементы в текущем окне, вы можете использовать

$(window).load(function () {
  // run code
});

1
Разве loadметод jQuery не привязывает функцию к событию загрузки с помощью Javascript? Чем это будет отличаться от того, что OP уже делает?
Alex Kalicki

@AlexKalicki AFAIK, это не будет иначе, за исключением того, что jQuery может использовать, addEventListenerа не связывать onloadсвойство DOM0 .
Alnitak

@AlexKalicki Я не могу сказать, что он использует ту же функциональность, но, согласно документации, jQuery гарантирует, что все элементы, включая изображения, загружаются до того, как это сработает. Я склонен полагать, что в этом случае будет дополнительная логика, и у меня нет причин не доверять документации, хотя я никогда не сталкивался с той же проблемой, о которой сообщает OP.
Хайме Торрес,

4
Начиная с JQuery v1.8, .load устарел. источник
Адонис К. Какулидис

1
Лучшее решение на этот вопрос.
Роберто Сепульведа Браво

29

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

  1. Загрузка DOM: что обеспечивает загрузку всего дерева DOM от начала до конца. Но не гарантируйте загрузку справочного контента. Предположим, вы добавили изображения с помощью imgтегов, поэтому это событие гарантирует, что все imgзагруженные, но не изображения правильно загружены или нет. Чтобы получить это событие, вы должны написать так:

    document.addEventListener('DOMContentLoaded', function() {
       // your code here
    }, false);

    Или используя jQuery:

    $(document).ready(function(){
    // your code
    });
  2. После загрузки DOM и контента: что также указывает на загрузку DOM и контента. Это гарантирует, что не только imgтег, но и все изображения или другой относительный контент будут загружены. Чтобы получить это событие, вы должны написать так:

    window.addEventListener('load', function() {...})

    Или используя jQuery:

    $(window).on('load', function() {
     console.log('All assets are loaded')
    })

2
Это единственный ответ, который дает решение для OP,
отличное от

Обработчик DOMContentLoadedсобытий @Hanif , похоже, ничего не делает для меня, но loadделает.
Брэндон Бенефилд

1
Разве в последних двух примерах не нужны точки с запятой в конце строк?
Р. Навега

11

Если вы хотите вызвать js-функцию на своей html-странице, используйте событие onload. Событие onload происходит, когда пользовательский агент завершает загрузку окна или всех фреймов в FRAMESET. Этот атрибут можно использовать с элементами BODY и FRAMESET.

<body onload="callFunction();">
....
</body>

7

Таким образом, вы можете справиться с обоими случаями - если страница уже загружена или нет:

document.onreadystatechange = function(){
    if (document.readyState === "complete") {
       myFunction();
    }
    else {
       window.onload = function () {
          myFunction();
       };
    };
}

3

В качестве альтернативы вы можете попробовать ниже.

$(window).bind("load", function() { 
// code here });

Это работает во всех случаях. Это сработает только при загрузке всей страницы.


3

Насколько я знаю, лучше всего использовать

window.addEventListener('load', function() {
    console.log('All assets loaded')
});

Ответ №1 использования DOMContentLoadedсобытия - это шаг назад, поскольку DOM загрузится до загрузки всех ресурсов.

Другие ответы рекомендуют, setTimeoutчто я категорически против, поскольку это полностью субъективно для производительности клиентского устройства и скорости сетевого подключения. Если кто-то находится в медленной сети и / или у него медленный процессор, загрузка страницы может занять от нескольких до десятков секунд, поэтому вы не можете предсказать, сколько времениsetTimeout потребуется.

Что касается readystatechange, он срабатывает всякий раз, когда readyStateизменения, которые, согласно MDN, все еще будут происходить до loadсобытия.

полный

Состояние указывает, что событие загрузки вот-вот сработает.


2
window.onload = () => {
  // run in onload
  setTimeout(() => {
    // onload finished.
    // and execute some code here like stat performance.
  }, 10)
}

2
Хотя этот фрагмент кода может быть решением, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причины вашего предложения кода.
yivi

@yivi, если это не автоматическое сообщение: для всех совершенно очевидно, что означает этот код, тем более что в коде есть комментарии ..
bluejayke


1

Если вы уже используете jQuery, вы можете попробовать следующее:

$(window).bind("load", function() {
   // code here
});

4
Бесполезно без объяснения причин.
Daniel W.

1

Я могу вам сказать, что лучший ответ, который я нашел, - это поставить сценарий «драйвера» сразу после </body>команды. Это самый простой и, наверное, более универсальный вариант, чем некоторые из вышеперечисленных решений.

План: На ​​моей странице есть таблица. Я записываю страницу с таблицей в браузер, затем сортирую ее с помощью JS. Пользователь может изменить это, щелкнув заголовки столбцов.

После того, как таблица завершена </tbody>командой, и тело завершено, я использую следующую строку для вызова JS сортировки для сортировки таблицы по столбцу 3. Я получил сценарий сортировки из Интернета, поэтому он не воспроизводится здесь. По крайней мере, в следующем году вы можете увидеть это в действии, включая JS, по адресу static29.ILikeTheInternet.com. Щелкните «здесь» внизу страницы. Откроется еще одна страница с таблицей и скриптами. Вы можете увидеть, как он помещает данные, а затем быстро их сортирует. Мне нужно немного ускорить это, но основы уже есть.

</tbody></body><script type='text/javascript'>sortNum(3);</script></html>

MakerMikey


0

Попробуйте этот jQuery :

$(function() {
 // Handler for .ready() called.
});

1
jQuery не readyбудет делать то, что запросил OP. readyсрабатывает при загрузке DOM, а не после загрузки элементов. loadсработает после завершения загрузки / рендеринга элементов.
Хайме Торрес,

0

вызвать функцию по истечении установленного времени ожидания полной загрузки страницы

setTimeout(function() {
   var val = $('.GridStyle tr:nth-child(2) td:nth-child(4)').text();
	for(var i, j = 0; i = ddl2.options[j]; j++) {
		if(i.text == val) {      
			ddl2.selectedIndex = i.index;
			break;
		}
	} 
}, 1000);


0

Я обычно использую следующий шаблон, чтобы проверить, завершилась ли загрузка документа. Функция возвращает обещание (если вам нужно поддерживать IE, включите полифил ), которое разрешается после завершения загрузки документа. Он используется setIntervalснизу, потому что аналогичная реализация setTimeoutможет привести к очень глубокому стеку.

function getDocReadyPromise()
{
  function promiseDocReady(resolve)
  {
    function checkDocReady()
    {
      if (document.readyState === "complete")
      {
        clearInterval(intervalDocReady);
        resolve();
      }
    }
    var intervalDocReady = setInterval(checkDocReady, 10);
  }
  return new Promise(promiseDocReady);
}

Конечно, если вам не нужно поддерживать IE:

const getDocReadyPromise = () =>
{
  const promiseDocReady = (resolve) =>
  {
    const checkDocReady = () =>
      ((document.readyState === "complete") && (clearInterval(intervalDocReady) || resolve()));
    let intervalDocReady = setInterval(checkDocReady, 10);
  }
  return new Promise(promiseDocReady);
}

С помощью этой функции вы можете делать следующее:

getDocReadyPromise().then(whatIveBeenWaitingToDo);

-1

Я использую веб-компоненты, поэтому мне это подходит:

document.addEventListener('WebComponentsReady', function() {
       document.querySelector('your-element').show();
});

-3

Ставьте свой скрипт после завершения тега body ... работает ...

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.