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

readyState

В заключение
занятия отметим свойство

document.readyState

которое в момент
загрузки HTML-документа принимает
следующие значения:

  • «loading»
    – документ в процессе загрузки;

  • «interactive»
    – документ был полностью прочитан (парсинг документа завершен);

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

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

removeImage();
function removeImage() {
     if(document.readyState == "loading") {
          console.log("документ грузится, вешаем обработчик");
          document.addEventListener("DOMContentLoaded", removeImage);
     }
     else {
          console.log("удаляем изображение");
          document.body.remove(image);
     }
}

По аналогии
могут быть обработаны и остальные свойства.

Для полноты картины
пару слов о событии readystatechange, которое появилось до событий

DOMContentLoaded, load, unload, beforeunload

и в старых версиях
JavaScript процесс
загрузки документа контролировался через него. Например, так:

document.addEventListener('readystatechange', function() {
         console.log(document.readyState);
});

Теперь при
обновлении страницы мы можем увидеть изменение состояний свойства document.readyState в процессе
загрузки. Однако такой механизм отслеживания ушел в прошлое и сейчас уже нет смысла
о нем подробно говорить.

Итак, на этом
занятии мы с вами рассмотрели события

DOMContentLoaded,
load, unload, beforeunload

и поговорили о свойстве

document.readyState

которое
дополняет работу с этими событиями.

Видео по теме

JavaScipt (DOM) #1: объектная модель документа DOM и BOM

JavaScipt (DOM) #2: навигация по DOM — parentNode, nextSibling, previousSibling, chidNodes

JavaScipt (DOM) #3: методы поиска элементов в DOM: querySelector, querySelectorAll, getElementById

JavaScipt (DOM) #4: свойства DOM-узлов: nodeName, innerHTML, outerHTML, data, textContent, hidden

JavaScipt (DOM) #5: работа с нестандартными свойствами DOM-элементов: getAttribute, setAttribute, dataset

JavaScipt (DOM) #6: создание и добавление элементов DOM createElement, append, remove, insertAdjacentHTML

JavaScipt (DOM) #7: управление стилями — className, style, classList, getComputedStyle

JavaScipt (DOM) #8: метрики — clientWidth, scrollTop, scrollHeight, offsetLeft, offsetTop, clientLeft

JavaScipt (DOM) #9: HTML-документ: размеры (clientWidth, innerWidth), положение (pageYOffset, scrollBy)

JavaScipt (DOM) #10: расположение элементов — fixed, absolute, getBoundingClientRect, elementFromPoint

JavaScipt (DOM) #11: обработчики событий: onclick, addEventListener, removeEventListener, event

JavaScipt (DOM) #12: погружение и всплытие событий: stopPropagation, stopImmediatePropagation, eventPhase

JavaScipt (DOM) #13: делегирование событий, отмена действия браузера по умолчанию — preventDefault

JavaScipt (DOM) #14: события мыши mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter

JavaScipt (DOM) #15: события клавиатуры keydown, keyup, событие скроллинга scroll

JavaScipt (DOM) #16: навигация и обработка элементов форм (form) — document.forms, form.elements

JavaScipt (DOM) #17: фокусировка — focus, blur, focusin, focusout, tabindex, activeElement

JavaScipt (DOM) #18: события change, input, cut, copy, paste, submit элементов input и select

JavaScipt (DOM) #19: события при загрузке — DOMContentLoaded, load, unload, beforeunload, readyState

JavaScipt (DOM) #20: события load, error; атрибуты async, defer тега script

JavaScipt (DOM) #21: пример предзагрузки изображений с помощью javascript

JavaScipt (DOM) #22: пример создания начала игры арканоид

Summary

Page load events:

  • event triggers on when DOM is ready. We can apply JavaScript to elements at this stage.

    • Script such as or block DOMContentLoaded, the browser waits for them to execute.
    • Images and other resources may also still continue loading.
  • event on triggers when the page and all resources are loaded. We rarely use it, because there’s usually no need to wait for so long.
  • event on triggers when the user wants to leave the page. If we cancel the event, browser asks whether the user really wants to leave (e.g we have unsaved changes).
  • event on triggers when the user is finally leaving, in the handler we can only do simple things that do not involve delays or asking a user. Because of that limitation, it’s rarely used. We can send out a network request with .
  • is the current state of the document, changes can be tracked in the event:

    • – the document is loading.
    • – the document is parsed, happens at about the same time as , but before it.
    • – the document and resources are loaded, happens at about the same time as , but before it.

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.

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()
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
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

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()

window.onbeforeunload

Если посетитель покидает страницу или пытается закрыть окно, обработчик beforeunload может запросить дополнительное подтверждение. Этот обработчик возвращает строку с вопросом. Браузер отобразит ее.

Например:

window.onbeforeunload = function() {
  return "Некоторые изменения не были сохранены. Вы все равно желаете покинуть страницу?";
};

Некоторые браузеры, такие как Chrome и Firefox, игнорируют заданное значение и отображают собственное сообщение. Делается это из соображений безопасности, чтобы защитить пользователя от мошеннических и хакерских сообщений при наступлении события JavaScript onload.

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

Window.onbeforeunload¶

If a user has initiated navigation away from the page or intends to close the window, the beforeunload will ask for additional confirmation. In case of discarding the event, the browser will ask the user whether they are sure. See how to do it by running the following code and reloading the page, as shown below:

An interesting thing to note: returning a non-empty string also counts as aborting the event. Previously, the browsers used to show it as a message, but the modern specification doesn’t allow that.

Let’s take a look at an example:

The reason for changing the behaviour was that some webmasters abused the event handler by showing annoying messages. Still, old browsers may show messages, but there is no way of customizing the message.

ReadyState¶

The document.readyState property informs about the current loading state.

Three possible values can be distinguished:

  • "loading": the state of loading the document.
  • «interactive»"interactive": the document is completely read.
  • "complete": the document is completely read, and all the resources are loaded.

So, you can check document.readyState and set up a handler, executing the code immediately when it’s ready.

Here is an example of using document.readyState:

You can also use the readystatechange event, which gets activated when the state changes. So, all the state can be printed as follows:

Try it Yourself »

So, this event is an alternative way of tracking the document loading state. But, nowadays, it’s not used often.

The complete events flow will look like this:

Try it Yourself »

The example above includes <iframe>, <img>, as well as handlers for logging events.

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.

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>

readyState

What happens if we set the handler after the document is loaded?

Naturally, it never runs.

There are cases when we are not sure whether the document is ready or not. We’d like our function to execute when the DOM is loaded, be it now or later.

The property tells us about the current loading state.

There are 3 possible values:

  • – the document is loading.
  • – the document was fully read.
  • – the document was fully read and all resources (like images) are loaded too.

So we can check and setup a handler or execute the code immediately if it’s ready.

Like this:

There’s also event that triggers when the state changes, so we can print all these states like this:

The event is an alternative mechanics of tracking the document loading state, it appeared long ago. Nowadays, it is rarely used.

Let’s see the full events flow for the completeness.

Here’s a document with , and handlers that log events:

The working example is in the sandbox.

The typical output:

  1. initial readyState:loading
  2. readyState:interactive
  3. DOMContentLoaded
  4. iframe onload
  5. img onload
  6. readyState:complete
  7. window onload

The numbers in square brackets denote the approximate time of when it happens. Events labeled with the same digit happen approximately at the same time (± a few ms).

  • becomes right before . These two things actually mean the same.
  • becomes when all resources ( and ) are loaded. Here we can see that it happens in about the same time as ( is the last resource) and . Switching to state means the same as . The difference is that always works after all other handlers.

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()
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
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

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()

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 – .

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.

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

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

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

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

Подставка первого скрипта

Несколько комментаторов правильно указали, что эту технику можно дополнительно оптимизировать, переместив исходную функцию в строку вместо сохранения ее во внешнем файле. Как правило, мне нравится хранить JavaScript вне кода страницы для удобства сопровождения. Я также ожидал, что исходный код JavaScript на странице будет больше, чем просто эта функция по той или иной причине. Если у вас может быть какая-то автоматизация для внедрения этого на вашу страницу в виде встроенного сценария, я полностью за это! Ключевой момент – убедидесь, что первый встроенный скрипт достаточно мал, чтобы производительность во время выполнения не влияла на загрузку страниц.

Несколько слов об async и defer

Атрибуты async и defer в window onload JavaScript используются только для внешних скриптов. Они игнорируются, если нет подключения через src.

Оба атрибута указывают браузеру, что он может продолжать обрабатывать страницу и загружать скрипты «в фоновом режиме». А затем запускать скрипт после его полной загрузки. Таким образом, скрипт не блокирует создание DOM и отображение страниц.

Между этими атрибутами есть два отличия.

async Defer
Порядок Скрипты с атрибутом async выполняются в том порядке, в котором они загружаются. Порядок, в котором они указаны в документе, не имеет значения — скрипт, загруженный первым, выполняется первым. Скрипты с атрибутом defer всегда выполняются в соответствии с порядком, в котором они расположены в документе.
DOMContentLoaded Скрипты с атрибутом async могут загружаться и выполняться, пока документ еще не загружен полностью. Это происходит, когда скрипты являются небольшими или кэшируются, а документ достаточно объемен. Скрипты с атрибутом defer выполняются после того, как документ будет полностью загружен и обработан (если необходимо они ожидают завершения процесса), сразу после события DOMContentLoaded.

Атрибут async используется для полностью независимых скриптов.

Размещение скрипта

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

Добавить комментарий

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

Adblock
detector