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

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

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


person Robin Rodricks    schedule 30.04.2009    source источник


Ответы (25)


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

<body onload="script();">

or

document.onload = function ...

или даже

window.onload = function ...

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

person marcgg    schedule 30.04.2009
comment
В чем разница между ‹body onload = script ();› и document.onload = function ...? - person Mentoliptus; 16.08.2011
comment
@mentoliptus: document.onload= не навязчивый en.wikipedia.org/wiki/Unobtrusive_JavaScript - person marcgg; 05.09.2011
comment
скрипт в html ... нет нет нет $ (function () {здесь код}); ‹- javascript.js может быть помещен в заголовок и загрузится после DOM - person ; 17.01.2014
comment
@gerdi OP ничего не упоминал о jQuery. Еще я в своем ответе дал ненавязчивый вариант. - person marcgg; 29.01.2014
comment
@gerdi Нет проблем, я отредактировал свой ответ, чтобы более четко показать разницу - person marcgg; 29.01.2014
comment
По какой-то причине в моем случае $ (window) .load (function () {/ * здесь код * /}) работал - person Kremena Lalova; 16.04.2014
comment
window.onload = function работал в моем случае. Я видел людей, отвечающих $(document).ready(function() на тот же вопрос на некоторых других форумах, но у меня это не работает! - person sohaiby; 02.07.2015
comment
Не могли бы вы добавить синтаксис jQuery для загрузки документа для полноты? - person IAbstract; 10.10.2016
comment
document.onload у меня не работал. Я нашел этот пост с той же проблемой stackoverflow.com/questions/5135638/. Не похоже, что document.onload - это вариант. - person spottedmahn; 28.07.2017
comment
Я предпочитаю первый подход, который мне кажется более понятным - особенно. при использовании aspx только с ограниченным javascript на странице. - person Zeek2; 17.10.2017
comment
document.onload не работает в Google Chrome при использовании в отдельном index.js файле сценария. window.onload работает. (Chrome 71.0.3578.98 (официальная сборка) (64-разрядная версия)) - person The Red Pea; 21.01.2019
comment
ВСЕ из этих параметров гораздо позже, чем необходимо, учитывая цель запуска javascript, когда DOM будет готов к манипуляциям. Два лучших варианта для этой цели: 1) Используйте атрибут defer в ссылке javascript в заголовке. 2) переместите любой javascript, который обращается к DOM, в конец страницы, непосредственно перед </body>. - person ToolmakerSteve; 01.05.2019
comment
На мой взгляд, использование функций onload - плохой стиль, потому что они относятся только к последней назначенной функции. Посмотрите ответ DevWL stackoverflow.com/a/36096571/11323907. - person MrXeth; 09.02.2020

Помните, что загрузка страницы состоит из нескольких этапов. Кстати, это чистый 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

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

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

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;
    }
}
person chaos    schedule 30.04.2009
comment
+1 за публикацию почти в точности то, что мне пришлось придумать 6 месяцев назад. Такой код может быть необходим, если другие фреймворки и код, которые вы не контролируете, добавляют события onload, и вы также хотите, не уничтожая другие события onload. Я включил свою реализацию как функцию, и для этого потребовалось var newonload = function (evt) {curronload (evt); newOnload (evt); } потому что по какой-то причине используемый мной фреймворк требует, чтобы событие передавалось событию onload. - person Grant Wagner; 01.05.2009
comment
Я только что обнаружил при тестировании, что написанный код приводит к тому, что обработчики запускаются в неопределенном порядке при присоединении с помощью attachEvent (). Если важен порядок выполнения обработчика, вы можете не указывать ветку window.attachEvent. - person Grant Wagner; 05.05.2009
comment
Итак, это добавит эту функцию как ДОПОЛНИТЕЛЬНУЮ функцию для запуска OnLoad, верно? (вместо замены существующего события onload) - person Clay Nichols; 09.06.2017
comment
@ClayNichols: Верно. - person chaos; 10.06.2017
comment
Хорошее решение, но теперь устаревшее: developer.mozilla.org/en -US / docs / Web / API / EventTarget / - person Renan; 26.11.2017
comment
Напоминание: не изменяйте объекты, которые вам не принадлежат, особенно глобальные объекты ... см. Ссылку Ренана - person Ray Foss; 10.04.2020

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

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

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

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

or 

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

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

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

person Nordes    schedule 30.04.2009

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

Пример:

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

Из https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script:

отложить

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

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

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

person Daniel Price    schedule 10.01.2014
comment
Мне нравится это решение, потому что не нужен код javascript, нужен только один атрибут html ‹3 - person sarkiroka; 10.05.2020
comment
Это в корне неверно. Отсрочка не предотвращает загрузку страницы сообщения о выполнении. Оба сценария defer и async загружаются перед загрузкой страницы, вместо этого сокращается время domInteraction. - person Akansh; 20.10.2020
comment
@Akansh OP просто хотел обеспечить загрузку DOM до выполнения их скрипта. Defer делает это, это буквально написано во фрагменте документации, которым я поделился в своем ответе. - person Daniel Price; 01.02.2021

Вот сценарий, основанный на отложенной загрузке 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

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

person Lucky    schedule 05.02.2013

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

person Daniel A. White    schedule 30.04.2009
comment
Насколько надежно это событие? (Кросс-браузер .. IE6 + FF2 + и т. Д.) - person Robin Rodricks; 30.04.2009
comment
Да, это кроссбраузерный, стандартный DOM. - person Daniel A. White; 30.04.2009
comment
На самом деле более стандартным является window.onload, а не document.onload. Насколько мне известно - person Peter Bailey; 30.04.2009

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 = ...
person T.Todua    schedule 06.04.2020

Рабочий скрипт на <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>
person Aamir Shahzad    schedule 26.03.2013

<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

person Frankey    schedule 11.09.2014

Если вы используете jQuery,

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

эквивалентно

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

или другая короткая рука:

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

См. Какое событие запускает JQuery $ function ()? и https://api.jquery.com/ready/

person Benjamin Crouzier    schedule 06.03.2013

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

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

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

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };
person Charles Jaimet    schedule 20.07.2013

document.onreadystatechange = function(){
     if(document.readyState === 'complete'){
         /*code here*/
     }
}

посмотрите здесь: http://msdn.microsoft.com/en-us/library/ie/ms536957(v=vs.85).aspx

person Arthur Tsidkilov    schedule 11.09.2014
comment
однострочный: document.onload = function () {...} - person colm.anseo; 26.03.2015

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

person Norbert Hartl    schedule 30.04.2009

<body onload="myFunction()">

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

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

person Akarsh Satija    schedule 29.04.2013

Сравнение

В приведенном ниже фрагменте я собираю выбранные методы и показываю их последовательность. Замечания

  • document.onload (X) не поддерживается ни одним современным браузером (событие никогда не запускается)
  • если вы используете <body onload="bodyOnLoad()"> (F) и одновременно window.onload (E), то будет выполнен только первый (потому что он перекрывает второй)
  • обработчик событий, указанный в <body onload="..."> (F), заключен в дополнительную функцию onload
  • document.onreadystatechange (D) не переопределять document .addEventListener('readystatechange'...) (C) вероятно, методы cecasue onXYZevent-like независимы, чем addEventListener очереди (что позволяет добавлять несколько слушателей). Вероятно, между выполнением этих двух обработчиков ничего не происходит.
  • все сценарии записывают свою временную метку в консоли, но сценарии, которые также имеют доступ к div, записывают свои временные метки также в теле (щелкните ссылку «Полная страница» после выполнения сценария, чтобы увидеть ее).
  • solutions readystatechange (C,D) are executed multiple times by browser but for different document states:
    • loading - the document is loading (no fired in snippet)
    • интерактивный - документ анализируется, запускается до DOMContentLoaded
    • завершено - документ и ресурсы загружены, запускаются до body/window onload

<html>

<head>
  <script>
    // solution A
    console.log(`[timestamp: ${Date.now()}] A: Head script`);
    
    // solution B
    document.addEventListener("DOMContentLoaded", () => {
      print(`[timestamp: ${Date.now()}] B: DOMContentLoaded`);
    });

    // solution C
    document.addEventListener('readystatechange', () => {
      print(`[timestamp: ${Date.now()}] C: ReadyState: ${document.readyState}`);
    });
   
    // solution D
    document.onreadystatechange = s=> {print(`[timestamp: ${Date.now()}] D: document.onreadystatechange ReadyState: ${document.readyState}`)};
    
    // solution E (never executed)
    window.onload = () => {
      print(`E: <body onload="..."> override this handler`);
    };

    // solution F
    function bodyOnLoad() {
      print(`[timestamp: ${Date.now()}] F: <body onload='...'>`);      
      infoAboutOnLoad(); // additional info
    }
    
    // solution X
    document.onload = () => {print(`document.onload is never fired`)};



    // HELPERS

    function print(txt) { 
      console.log(txt);
      if(mydiv) mydiv.innerHTML += txt.replace('<','&lt;').replace('>','&gt;') + '<br>';
    }
    
    function infoAboutOnLoad() {
      console.log("window.onload (after  override):", (''+document.body.onload).replace(/\s+/g,' '));
      console.log(`body.onload==window.onload --> ${document.body.onload==window.onload}`);
    }
            
    console.log("window.onload (before override):", (''+document.body.onload).replace(/\s+/g,' '));

  </script>
</head>

<body onload="bodyOnLoad()">
  <div id="mydiv"></div>

  <!-- this script must te at the bottom of <body> -->
  <script>
    // solution G
    print(`[timestamp: ${Date.now()}] G: <body> bottom script`);
  </script>
</body>

</html>

person Kamil Kiełczewski    schedule 17.06.2020

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

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

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

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

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

Например, Mozilla

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" );
    });
person Community    schedule 12.12.2015

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

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

  // your javascript event

});
person Harish Kumar    schedule 21.12.2017
comment
Добавьте сюда описание - person Mathews Sunny; 21.12.2017

$(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>
person Zach Reynolds    schedule 08.03.2018

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

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

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

N.B. : чтобы использовать этот код, вам нужно импортировать 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>
person Valentin Jacquemin    schedule 30.04.2009

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

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

person Iain    schedule 30.04.2009

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

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

Вы можете написать функцию в конкретном файле сценария и вызвать ее в свой элемент тела с помощью атрибута onload.

Пример:

<script>
  afterPageLoad() {
   //your code here
}
</script>

Теперь вызовите свой скрипт на свою html-страницу, используя тег скрипта:

<script src="afterload.js"></script>

в элемент вашего тела; добавьте атрибут onload следующим образом:

<body onload="afterPageLoad();">
person Camel Djoulako    schedule 02.04.2021
comment
Пожалуйста, пересмотрите свой откат, который отменил полезную правку. Улучшение читабельности ваших сообщений другими пользователями должно считаться хорошим делом. - person Yunnosch; 17.06.2021

я могу поймать загрузку страницы по этому коду

<script>
console.log("logger saber");

window.onload = (event) => {
  console.log('page is fully loaded');
document.getElementById("tafahomNameId_78ec7c44-beab-40de-9326-095f474519f4_$LookupField").value = 1;;
};

</script>
person saber tabatabaee yazdi    schedule 30.03.2021

person    schedule
comment
Этот ответ зависит от jquery - person Chiptus; 05.09.2018