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

DOMContentLoaded¶

This event occurs on the document object.

The addEventListener should be used to catch it, like this:

Here is an extensive example of using addEventListener:

Try it Yourself »

In the example above, the DOMContentLoaded runs once the document is loaded. So, it is capable of seeing all the elements, including <img>.

But, note that it never waits for the image to load. Hence, the alert will show zero sizes.

The DOMContentLoaded event looks very simple at first sight. But, the event comes when the DOM tree is ready.

However, few peculiarities exist that we are going to cover further.

DOMContentLoaded and Scripts

Once the document processes an HTML-document and passes through a <script> tag, it should execute before continuing to set up the DOM. It’s like a precaution because scripts might want to modify the DOM, and, moreover, document.write into it. Therefore, the DOMContentLoaded should wait.

So, the DOMContentLoaded event occurs after scripts like this:

Try it Yourself »

As you can notice from the example above, first comes “Library loaded…” , only then “DOM ready”.

Please, note that there are exceptions to this rule. That is to say, the scripts with async attribute never block DOMContentLoaded. The scripts that are created dynamically using document.createElement('script') and added to the webpage after, don’t block this event, either.

DOMContentLoaded and Styles

The DOM is not affected by external style sheets, so DOMContentLoaded doesn’t wait for them.

But there is a drawback here. If there is a script after the style, then the script shall wait till the stylesheet is loading, like this:

Try it Yourself »

That happens because the script might want to get coordinates or other style-dependant properties. So, it should wait for the style to load. As though DOMContentLoaded waits for the scripts, it will wait for the styles before them, too.

Built-in Browser Autofill

Chrome, Opera and Firefox can autofill forms on DOMContentLoaded. For example, if there is a page form with a login and password, and the browser remembered the values, then it might try to autofill them on DOMContentLoaded (it should be approved by the user).

Moreover, if DOMContentLoaded is suspended by the long-load scripts, the autofill should also wait. In some sites (in case of using browser autofill) the fields of login and password don’t get auto-filled at once. There is a delay until the page is completely loaded. That’s the delay till the DOMContentLoaded event.

window.onunload

When a visitor leaves the page, the event triggers on . We can do something there that doesn’t involve a delay, like closing related popup windows.

The notable exception is sending analytics.

Let’s say we gather data about how the page is used: mouse clicks, scrolls, viewed page areas, and so on.

Naturally, event is when the user leaves us, and we’d like to save the data on our server.

There exists a special method for such needs, described in the specification https://w3c.github.io/beacon/.

It sends the data in background. The transition to another page is not delayed: the browser leaves the page, but still performs .

Here’s how to use it:

  • The request is sent as POST.
  • We can send not only a string, but also forms and other formats, as described in the chapter Fetch: Basics, but usually it’s a stringified object.
  • The data is limited by 64kb.

When the request is finished, the browser probably has already left the document, so there’s no way to get server response (which is usually empty for analytics).

There’s also a flag for doing such “after-page-left” requests in fetch method for generic network requests. You can find more information in the chapter Fetch API.

If we want to cancel the transition to another page, we can’t do it here. But we can use another event – .

Window.onunload¶

The unload event triggers on the window when a visitor leaves the page. You can do there something that doesn’t include a delay (for example, closing related popup window). Sending analytics is considered a notable exception.

Imagine, you want to gather data about how the page is used: scrolls, mouse clicks, and so on. As a rule, the unload event is when the user leaves the page, and you want to save the data on the server. A unique navigator.sendBeacon(url, data) method exists for such needs. It can send the data to the background. Also, there is no delay in the transition to another page still performing sendBeacon.

Here is an example of using sendBeacon:

So, in the example above:

  1. The request is forwarded as POST.
  2. It is possible to send not only a string but also forms and other formats.
  3. There is a data limit: 64kb.

Once the sendBeacon request is over, the browser has probably left the document. Therefore, there is no way of getting server response (for analytics, it’s usually empty).

Also, you can use keepalive to perform “after-page-left” requests in the fetch method for generic network requests.

For canceling the transition to another page, you can use another event: onbeforeunload.

3 ответа

Лучший ответ

Блокировщики всплывающих окон обычно не допускают всплывающие окна (или программный щелчок по динамически создаваемым гиперссылкам и т. Д.), Если не вызывается прямым действием пользователя. Каждый браузер имеет немного другой механизм блокировки всплывающих окон.

В вашем случае 1 сначала весь код запускается в основном потоке в результате нажатия пользователем кнопки экспорта. Это отлично работает.

В случае 2 открытие окна может работать не во всех браузерах, поскольку оно вызывается из другого потока. Обработчик успеха Ajax будет вызываться асинхронно еще долго после завершения события onclick.

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

Реализация приведенных выше предложений может помочь решить вашу проблему, поскольку не запускается, но есть еще одно улучшение, которое можно внести — добавление обработчика перед навигацией:

Или даже лучше добавить его в основной теме, сразу после

Надеюсь, поможет.

Andrew O.
30 Янв 2019 в 04:45

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

Shahar
31 Янв 2019 в 09:18

Попробуй это?

Andrejs Gubars
29 Янв 2019 в 11:29

HTML Tags

<!—><!DOCTYPE><a><abbr><acronym><address><applet><area><article><aside><audio><b><base><basefont><bdi><bdo><big><blockquote><body><br><button><canvas><caption><center><cite><code><col><colgroup><data><datalist><dd><del><details><dfn><dialog><dir><div><dl><dt><em><embed><fieldset><figcaption><figure><font><footer><form><frame><frameset><h1> — <h6><head><header><hr><html><i><iframe><img><input><ins><kbd><label><legend><li><link><main><map><mark><meta><meter><nav><noframes><noscript><object><ol><optgroup><option><output><p><param><picture><pre><progress><q><rp><rt><ruby><s><samp><script><section><select><small><source><span><strike><strong><style><sub><summary><sup><svg><table><tbody><td><template><textarea><tfoot><th><thead><time><title><tr><track><tt><u><ul><var><video>

DOMContentLoaded

The event happens on the object.

We must use to catch it:

For instance:

In the example the handler runs when the document is loaded, so it can see all the elements, including below.

But it doesn’t wait for the image to load. So shows zero sizes.

At the first sight event is very simple. The DOM tree is ready – here’s the event. There are few peculiarities though.

When the browser processes an HTML-document and comes across a tag, it needs to execute before continuing building the DOM. That’s a precaution, as scripts may want to modify DOM, and even into it, so has to wait.

So DOMContentLoaded definitely happens after such scripts:

In the example above, we first see “Library loaded…”, and then “DOM ready!” (all scripts are executed).

Scripts with , or don’t block DOMContentLoaded

Script attributes and , that we’ll cover a bit later, don’t block DOMContentLoaded. JavaScript modules behave like , they don’t block it too.

So here we’re talking about “regular” scripts, like , or .

External style sheets don’t affect DOM, so does not wait for them.

But there’s a pitfall. If we have a script after the style, then that script must wait until the stylesheet loads:

The reason is that the script may want to get coordinates and other style-dependent properties of elements, like in the example above. Naturally, it has to wait for styles to load.

As waits for scripts, it now waits for styles before them as well.

Firefox, Chrome and Opera autofill forms on .

For instance, if the page has a form with login and password, and the browser remembered the values, then on it may try to autofill them (if approved by the user).

So if is postponed by long-loading scripts, then autofill also awaits. You probably saw that on some sites (if you use browser autofill) – the login/password fields don’t get autofilled immediately, but there’s a delay till the page fully loads. That’s actually the delay until the event.

Скрипт асинхронной загрузки множества подключаемых JavaScript файлов

<script type="text/javascript">
(function() {
	function async_load(){
		.forEach(function(src) {
			var s = document.createElement('script');
			s.type = 'text/javascript';
			s.async = true;
			s.src = src;
			document.getElementsByTagName('head').appendChild(script);
		});
	}

	if (window.addEventListener) {
	    window.addEventListener('load', async_load, false);
	} else if (window.attachEvent) {
	    window.attachEvent('onload', async_load);
	}
})();
</script>

Но в такой реализации есть минус — скрипты будут загружаться в произвольном порядке и соответсвенно выполнятся они будут произвольно во времени. Данный скрипт асинхронной загрузки идеально подходит, если выполнение JavaScript файлов не зависят один от другого и не зависит от DOM. В обратном случае его использование может привести к ошибкам на странице или непредвиденному результату выполнения. Для последовательного выполнения, но асинхронной загрузки, нужно указать async=false, тогда файлы будут скачиваться в произвольном порядке, но выполняться по очереди.

readyState

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

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

Свойство document.readyState предоставляет такую информацию. Возможны три значения:

  • «» — документ загружается;
  • «interactive» — документ полностью считан;
  • «complete» — документ полностью считан и все ресурсы (например, изображения) загружены.

Так можно проверить значение document.readyState и настроить обработчик или выполнить код немедленно, как только он будет готов.

Например, следующим образом:

function work() { /*...*/ }
if (document.readyState == 'loading') {
  document.addEventListener('DOMContentLoaded', work);
} else {
  work();
}

Событие readystatechange запускается при изменении состояния. Можно выводить все эти состояния следующим образом:

// текущее состояние
console.log(document.readyState);

// выводим изменение состояния
document.addEventListener('readystatechange', () => console.log(document.readyState));

Событие readystatechange является альтернативным методом отслеживания состояния загрузки документа, оно было введено давно. В настоящее время оно редко используется, но рассмотрим его для полноты картины.

Как размещается readystatechange по отношению к другим событиям? Чтобы продемонстрировать порядок их срабатывания, ниже приводится пример с <iframe>, <img> и обработчиками, которые регистрируют события (JavaScript onload и другие):

<script>
  function log(text) { /* выводим время и сообщение */ }
  log('initial readyState:' + document.readyState);

  document.addEventListener('readystatechange', () => log('readyState:' + document.readyState));
  document.addEventListener('DOMContentLoaded', () => log('DOMContentLoaded'));

  window.onload = () => log('window onload');
</script>

<iframe src="iframe.html" onload="log('iframe onload')"></iframe>

<img src="http://en.js.cx/clipart/train.gif" id="img">
<script>
  img.onload = () => log('img onload');
</script>

Демо-версию можно найти на sandbox.

Стандартная последовательность событий:

  1. инициализация readyState:loading;
  2. readyState:interactive;
  3. DOMContentLoaded;
  4. iframe onload;
  5. readyState:complete;
  6. img onload;
  7. window onload JavaScript.

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

Document.readyState принимает состояние interactive непосредственно перед DOMContentLoaded. Эти два события фактически означают одно и то же.

Document.readyState завершается, когда загружаются все ресурсы (iframe и img). Мы видим, что это происходит примерно в то же время, что и img.onload (img — последний ресурс) и window.onload. Переключение на состояние complete означает то же, что и window.onload. Разница в том, что window.onload всегда запускается после всех других обработчиков load.

HTML Tags

<!—><!DOCTYPE><a><abbr><acronym><address><applet><area><article><aside><audio><b><base><basefont><bdi><bdo><big><blockquote><body><br><button><canvas><caption><center><cite><code><col><colgroup><data><datalist><dd><del><details><dfn><dialog><dir><div><dl><dt><em><embed><fieldset><figcaption><figure><font><footer><form><frame><frameset><h1> — <h6><head><header><hr><html><i><iframe><img><input><ins><kbd><label><legend><li><link><main><map><mark><meta><meter><nav><noframes><noscript><object><ol><optgroup><option><output><p><param><picture><pre><progress><q><rp><rt><ruby><s><samp><script><section><select><small><source><span><strike><strong><style><sub><summary><sup><svg><table><tbody><td><template><textarea><tfoot><th><thead><time><title><tr><track><tt><u><ul><var><video>

More Examples

Example

Using onload on an <img> element. Alert «Image is loaded» immediately after
an image has been loaded:

<img src=»w3html.gif» onload=»loadImage()» width=»100″ height=»132″><script>function loadImage() {    alert(«Image is loaded»);}
</script>

Example

Using the onload event to deal with cookies (using «advanced» javascript):

<body onload=»checkCookies()»><p id=»demo»></p><script>
function checkCookies() {    var text = «»;    if (navigator.cookieEnabled == true) {        text = «Cookies are enabled.»;    } else {        text = «Cookies are not enabled.»;    }
   
document.getElementById(«demo»).innerHTML = text;}</script>

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sinh()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
Modifiers:
g
i
m
Groups:

(x|y)
Metacharacters:
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx
Quantifiers:
+
*
?
{X}
{X,Y}
{X,}
$
^
?=
?!
Properties:
constructor
global
ignoreCase
lastIndex
multiline
source
Methods:
compile()
exec()
test()
toString()

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

Популярные

Хранение паролей в PHP с использованием crypt()
просмотры: 57614

Примеры использования CDbCriteria в Yii
просмотры: 31380

Загрузка JavaScript(без блокировки отрисовки документа, асинхронная загрузка)
просмотры: 16535

Преобразование первых букв в заглавные(верхний регистр) — PHP
просмотры: 14322

Парсинг URL с помощью JavaScript
просмотры: 13369

Tornado. Асинхронное программирование
просмотры: 12981

Composer — менеджер зависимостей для PHP
просмотры: 9615

Установка Django в Ubuntu с использованием локального Python окружения
просмотры: 8390

MySQL и поддержка Unicode
просмотры: 7635

Смена JAVA_HOME в Ubuntu
просмотры: 7621

6 ответов

Лучший ответ

просто запускается, когда браузер доходит до него.

ожидает загрузки окна, прежде чем запускать его.

В общем случае вы должны делать второе, но вы должны прикрепить к нему прослушиватель событий вместо определения функции. Например:

37

Crayon Violent
24 Фев 2019 в 18:45

Вот документация по MDN.

Согласно этому:

Ваш первый фрагмент кода будет запущен, как только браузер достигнет этого места в HTML.

Второй фрагмент вызовет всплывающее окно, когда DOM и все изображения будут полностью загружены (см. Спецификации).

Учитывая функцию , на самом деле не имеет значения, в какой момент она будет работать (она не зависит ни от чего, кроме объекта ). Но если вы хотите манипулировать DOM — вам определенно следует подождать, пока он правильно загрузится ,

6

Slava Fomin II
23 Фев 2017 в 13:32

Причина ожидания загрузки DOM заключается в том, что вы можете настроить таргетинг на любые элементы, которые загружаются после вашего скрипта. Если вы просто создаете , это не имеет значения. Допустим, однако, что вы нацелились на , который был в вашей разметке после вашего скрипта, вы получите ошибку, если не дождетесь загрузки этого фрагмента дерева DOM.

— отличная альтернатива , если вы используете jQuery.

Смотрите здесь: window.onload vs $ (document) .ready ()

1

Community
23 Май 2017 в 12:10

Все остальные ответы кажутся устаревшими

Во-первых, размещение сценариев сверху и использование — это анти-паттерн. Это в лучшем случае осталось от дней IE или неправильного понимания JavaScript и браузера в худшем случае.

Вы можете просто переместить ваши скрипты внизу вашего HTML

Единственная причина, по которой люди использовали , заключается в том, что они ошибочно полагали, что сценарии необходимо добавить в раздел . Поскольку все выполняется по порядку, если ваш сценарий был в разделе head, тогда тело и ваш контент еще не существовали по определению execute in order .

Хакерский обходной путь — использовать для ожидания загрузки остальной части страницы. Перемещение вашего скрипта в конец также решило эту проблему, и теперь нет необходимости использовать , так как ваше тело и контент уже загружены.

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

Преимущество этого заключается в том, что браузер немедленно начнет загружать сценарии и будет выполнять их в указанном порядке, но будет ожидать их выполнения до тех пор, пока страница не загрузится, не нужно или лучше, но все еще не нужно {{Х1}}

21

gman
15 Янв 2018 в 02:28

У вас есть три варианта:

  1. Непосредственно внутри тега script выполняется его, как только он анализируется.

  2. Inside запустит его, как только DOM будет готов.

  3. Внутри запустится, как только будут загружены все ресурсы страницы.

Henrik
24 Ноя 2013 в 20:06

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

Ни один не всегда прав.

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

2

Quentin
24 Ноя 2013 в 20:02

HTML 5. Асинхронная загрузка JavaScript

Стандарт HTML 5 поддерживает асинхронную загрузку JavaScript. Это можно сделать путем добавления ключевого слова async или defer. Например:

<script src="URL_скрипта" type="text/javascript" async></script>
<script src="URL_скрипта" type="text/javascript" defer></script>

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

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

Скрипт, который подключен с атрибутом async выполнится при первой возможности после полной загрузки, но при этом не ожидает окончания парсинга документа и до загрузки объекта window. Браузеры не гарантируют выполнение скриптов в том же порядке в котором они подключены.

More Examples

Example

Using onload on an <img> element. Alert «Image is loaded» immediately after
an image has been loaded:

<img src=»w3javascript.gif» onload=»loadImage()» width=»100″ height=»132″><script>function loadImage() {  alert(«Image is loaded»);}
</script>

Example

Using the onload event to deal with cookies:

<body onload=»checkCookies()»><script>
function checkCookies() {  var text = «»;  if (navigator.cookieEnabled == true) {    text = «Cookies are enabled.»;  } else {     text = «Cookies are not enabled.»;
  }  document.getElementById(«demo»).innerHTML = text;}</script>

❮ DOM Events
❮ Event Object

Автоматическое заполнение браузерами

Firefox, Chrome и Opera автоматически заполняют поля форм для DOMContentLoaded. Например, если страница имеет форму с полями для ввода имени пользователя и пароля, а браузер запомнил их значения, DOMContentLoaded может попытаться автоматически их заполнить (если это одобрено пользователем).

Поэтому, кроме задержки до полной загрузки и выполнения скриптов, DOMContentLoaded может задерживаться и из-за автоматического заполнения полей форм. Вы могли сталкиваться с этим на некоторых сайтах: поля ввода логина / пароля не обновляются автоматически, и возникает задержка до полной загрузки страницы. На самом деле это задержка события DOMContentLoaded.

Одно из незначительных преимуществ использования атрибутов async и defer для внешних скриптов заключается в том, что они не блокируют DOMContentLoaded и позволяют избежать задержки, связанной с автоматическим заполнением форм.

Библиотеки для асинхронной загрузки JavaScript

RequireJS — модуль загрузки JavaScript. Оптимизирован под браузеры, но он может использоваться в других средах, таких как Node, Rhino.

require(, function(script) {
	console.log("start after load script.js");
});

extsrc.js — библиотека, которая запускает скрипты на выполнение после того, как страница загрузится и отобразится пользователю. Работает корректно с document.write.

<script src="http://extsrcjs.googlecode.com/svn/trunk/extsrc.js"></script>
<script extsrc="...."></script>
<script asyncsrc="...."></script>

yepnope.js — позволяет совершать асинхронную загрузку JavaScript и CSS файлов.

yepnope();
Добавить комментарий

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

Adblock
detector