Как заставить JavaScript работать после загрузки страницы?

739

Я выполняю внешний скрипт, используя <script>внутренний <head>.

Теперь, когда скрипт выполняется до загрузки страницы, я не могу получить доступ <body>, среди прочего. Я хочу выполнить JavaScript после того, как документ был «загружен» (HTML полностью загружен и находится в оперативной памяти). Есть ли какие-либо события, которые я могу подключить при выполнении моего скрипта, которые сработают при загрузке страницы?

Вспышка
источник

Ответы:

839

Эти решения будут работать:

<body onload="script();">

или

document.onload = function ...

или даже

window.onload = function ...

Обратите внимание, что последний вариант - лучший способ, так как он ненавязчив и считается более стандартным .

marcgg
источник
5
В чем разница между <body onload = "script ();"> и document.onload = function ...?
Ментолипт
11
@mentoliptus: document.onload=не навязчиво en.wikipedia.org/wiki/Unobtrusive_JavaScript
marcgg,
3
скрипт в html ... нет нет нет $ (function () {code here}); <- javascript.js может быть помещен в голову и будет загружаться после DOM
21
@gerdi OP ничего не сказал о jQuery. Я также дал ненавязчивый вариант в своем ответе.
Marcgg
1
document.onload не работает для меня. Я нашел этот пост с той же проблемой stackoverflow.com/questions/5135638/… . Не похоже на то, что document.onload является опцией.
spottedmahn
197

Разумно переносимый, неструктурированный способ заставить ваш скрипт установить функцию для запуска во время загрузки:

if(window.attachEvent) {
    window.attachEvent('onload', yourFunctionName);
} else {
    if(window.onload) {
        var curronload = window.onload;
        var newonload = function(evt) {
            curronload(evt);
            yourFunctionName(evt);
        };
        window.onload = newonload;
    } else {
        window.onload = yourFunctionName;
    }
}
хаос
источник
10
+1 за публикацию почти точно, что я должен был придумать 6 месяцев назад. Подобный код может быть необходим, если другие платформы и код, который вы не можете контролировать, добавляют события onload, и вы тоже хотите это делать, не уничтожая другие события onload. Я включил мою реализацию как функцию, и она потребовала var newonload = function (evt) {curronload (evt); newOnload (EVT); } потому что по какой-то причине используемая мной среда требует передачи события onload.
Грант Вагнер
6
Я только что обнаружил в тестировании, что код, как написано, приводит к тому, что обработчики запускаются в неопределенном порядке при присоединении с attachEvent (). Если порядок выполнения обработчика важен, вы можете не использовать ветку window.attachEvent.
Грант Вагнер
Так что это добавит эту функцию в качестве ДОПОЛНИТЕЛЬНОЙ функции для запуска OnLoad, правильно? (вместо того, чтобы заменить существующее событие
Клэй Николс
@ClayNichols: правильно.
хаос
2
Хорошее решение, но уже устаревшее: developer.mozilla.org/en-US/docs/Web/API/EventTarget/…
Ренан
192

Имейте в виду, что загрузка страницы имеет более одного этапа. Кстати, это чистый JavaScript

"DOMContentLoaded"

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

Выполняется после загрузки DOM (до img и css):

document.addEventListener("DOMContentLoaded", function(){
    //....
});

Примечание. Синхронный JavaScript приостанавливает анализ DOM. Если вы хотите, чтобы DOM обрабатывался как можно быстрее после того, как пользователь запросил страницу, вы можете включить JavaScript в асинхронном режиме и оптимизировать загрузку таблиц стилей.

«Нагрузка»

Совершенно другое событие, load , следует использовать только для обнаружения полностью загруженной страницы . Это невероятно популярная ошибка - использовать load, когда DOMContentLoaded будет гораздо более уместным, поэтому будьте осторожны.

Ожидает после того, как все загружено и проанализировано:

window.addEventListener("load", function(){
    // ....
});

Ресурсы MDN:

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded https://developer.mozilla.org/en-US/docs/Web/Events/load

MDN список всех событий:

https://developer.mozilla.org/en-US/docs/Web/Events

DevWL
источник
1
@Peter почти уверен, что он стоит один, вероятно, лучше всего, если он находится внизу ваших файлов javascript, поэтому он выполняется в последний раз
arodebaugh
Javascript приостанавливает рендеринг DOM там, чтобы лучше всего было разместить его внизу страницы или загрузить асинхронный javascript в заголовок.
DevWL
Это самый законченный ответ. перегрузка идет после, но люди сначала не осознают этого.
tfont
1
Re асинхронный JavaScript : чтобы уточнить, есть два варианта для сценариев, которые не запускаются сразу. Из них defer обычно предпочтительнее асинхронного - потому что defer не прерывает синтаксический анализ / рендеринг html - и при запуске DOM гарантированно будет готов. Эффективно загружать JavaScript с отсрочкой и асинхронностью .
ToolmakerSteve
+1 Я пытался window.onload = ...подумать, что мой сценарий будет ждать, пока все не будет полностью загружено, прежде чем запускаться, но, похоже, он window.onloadдействительно ведет себя как document.addEventListener("DOMContentLoaded", ..., тогда как на window.addEventListener("load", ...самом деле все ждет полной загрузки. Я бы подумал, что window.onloadдолжно быть эквивалентно, window.addEventListener("load", ...а не document.addEventListener("DOMContentLoaded", ...?? Я получил тот же результат в Chrome и FF.
wkille
121

Вы можете поместить атрибут "onload" внутри тела

...<body onload="myFunction()">...

Или, если вы используете JQuery, вы можете сделать

$(document).ready(function(){ /*code here*/ }) 

or 

$(window).load(function(){ /*code here*/ })

Я надеюсь, что это ответит на ваш вопрос.

Обратите внимание, что $ (window) .load будет выполняться после отображения документа на вашей странице.

Nordés
источник
65

Если сценарии загружены в пределах <head>документа, то возможно использовать deferатрибут в теге сценария.

Пример:

<script src="demo_defer.js" defer></script>

С https://developer.mozilla.org :

Перенести

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

Этот атрибут не должен использоваться, если атрибут src отсутствует (то есть для встроенных сценариев), в этом случае он не будет иметь никакого эффекта.

Чтобы добиться аналогичного эффекта для динамически вставляемых сценариев, используйте вместо этого async = false. Скрипты с атрибутом defer будут выполняться в том порядке, в котором они появляются в документе.

Дэниэл Прайс
источник
Мне нравится это решение, потому что не нужно никакого кода JavaScript, а нужен только один атрибут html <3
sarkiroka
27

Вот скрипт, основанный на отложенной загрузке js после загрузки страницы,

<script type="text/javascript">
  function downloadJSAtOnload() {
      var element = document.createElement("script");
      element.src = "deferredfunctions.js";
      document.body.appendChild(element);
  }

  if (window.addEventListener)
      window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
      window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

Где я могу разместить это?

Вставьте код в HTML непосредственно перед </body>тегом (в нижней части HTML-файла).

Что оно делает?

Этот код говорит, что дождитесь загрузки всего документа, а затем загрузите внешний файл deferredfunctions.js.

Вот пример кода выше - отложенный рендеринг JS

Я написал это на основе отложенной загрузки концепции gavascript pagespeed google, а также из этой статьи Отложить загрузку javascript

Счастливчик
источник
21

Посмотрите на перехват document.onloadили в jQuery $(document).load(...).

Даниэль А. Уайт
источник
Это событие надежно? (Кросс-браузер .. IE6 + FF2 + и т. Д.)
TheFlash
1
Да, это кросс-браузерный стандарт DOM.
Дэниел А. Уайт
16
На самом деле это более стандартная версия window.onload, а не document.onload. AFAIK
Питер Бейли
11

Рабочая Fiddle на<body onload="myFunction()">

<!DOCTYPE html>
<html>
 <head>
  <script type="text/javascript">
   function myFunction(){
    alert("Page is loaded");
   }
  </script>
 </head>

 <body onload="myFunction()">
  <h1>Hello World!</h1>
 </body>    
</html>
Аамир Шахзад
источник
10
<script type="text/javascript">
  function downloadJSAtOnload() {
   var element = document.createElement("script");
   element.src = "defer.js";
   document.body.appendChild(element);
  }
  if (window.addEventListener)
   window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
   window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

http://www.feedthebot.com/pagespeed/defer-loading-javascript.html

Frankey
источник
7

Иногда на более сложных страницах я обнаруживаю, что не все элементы загружены к временному окну. Запущена загрузка. Если это так, добавьте setTimeout до того, как ваша функция задержится на мгновение. Это не элегантно, но это простой взлом, который хорошо рендерится.

window.onload = function(){ doSomethingCool(); };

становится ...

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };
Чарльз Хаймет
источник
5

Просто определите, <body onload="aFunction()">что будет вызвано после загрузки страницы. Ваш код в скрипте , чем приложен aFunction() { }.

Норберт Хартл
источник
4
<body onload="myFunction()">

Этот код работает хорошо.

Но window.onloadметод имеет различные зависимости. Так что это может не работать все время.

Акарш Сатия
источник
3

Использование библиотеки YUI (мне это нравится):

YAHOO.util.Event.onDOMReady(function(){
    //your code
});

Портативный и красивый! Однако, если вы не используете YUI для других вещей (см. Документацию), я бы сказал, что его не стоит использовать.

NB: чтобы использовать этот код, вам нужно импортировать 2 скрипта

<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>
Валентин Жакмин
источник
3

Существует очень хорошая документация о том, как определить, загружен ли документ с использованием Javascript или Jquery.

Используя нативный Javascript, этого можно достичь

if (document.readyState === "complete") {
 init();
 }

Это также можно сделать внутри интервала

var interval = setInterval(function() {
    if(document.readyState === 'complete') {
        clearInterval(interval);
        init();
    }    
}, 100);

Например, Мозилла

switch (document.readyState) {
  case "loading":
    // The document is still loading.
    break;
  case "interactive":
    // The document has finished loading. We can now access the DOM elements.
    var span = document.createElement("span");
    span.textContent = "A <span> element.";
    document.body.appendChild(span);
    break;
  case "complete":
    // The page is fully loaded.
    console.log("Page is loaded completely");
    break;
}

Использование Jquery Чтобы проверить только готов DOM

// A $( document ).ready() block.
$( document ).ready(function() {
    console.log( "ready!" );
});

Чтобы проверить, все ли ресурсы загружены, используйте window.load

 $( window ).load(function() {
        console.log( "window loaded" );
    });

источник
3

Используйте этот код с библиотекой jQuery, это будет прекрасно работать.

$(window).bind("load", function() { 

  // your javascript event

});
Хариш Кумар
источник
Добавьте описание здесь
Mathews Sunny
3
$(window).on("load", function(){ ... });

.ready () работает лучше всего для меня.

$(document).ready(function(){ ... });

.load () будет работать, но не будет ждать загрузки страницы.

jQuery(window).load(function () { ... });

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

Чтобы скрыть загрузку моих сайтов, я использую следующее:

<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>
Зак Рейнольдс
источник
3

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 = ...
T.Todua
источник
1

Как говорит Даниэль, вы можете использовать document.onload.

Различные фреймворки javascript, однако (jQuery, Mootools и т. Д.) Используют пользовательское событие 'domready', которое, я думаю, должно быть более эффективным. Если вы разрабатываете с использованием javascript, я настоятельно рекомендую использовать фреймворк, он значительно увеличит вашу производительность.

Iain
источник
1

<script type="text/javascript">
$(window).bind("load", function() { 

// your javascript event here

});
</script>

Vô Vị
источник
4
Этот ответ зависит от JQuery
Chiptus
0

Мой совет использовать asnycатрибут для тега script, который поможет вам загрузить внешние скрипты после загрузки страницы

<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>
Kalidass
источник
7
Согласно w3schools , если присутствует асинхронный: сценарий выполняется асинхронно с остальной частью страницы (сценарий будет выполняться, пока страница продолжает анализ) . Возможно, вы имели в виду deferвместо этого, как упомянутое @Daniel Price?
jk7
0

использовать функцию самостоятельного выполнения onload

window.onload = function (){
    /* statements */
}();   
user7087840
источник
2
Вы можете переопределить другие onloadобработчики, используя этот подход. Вместо этого вы должны добавить слушателя.
Леонид Дашко