DOMContentLoaded, load, beforeunload, unload

2024-04-01 05:32

本文主要是介绍DOMContentLoaded, load, beforeunload, unload,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文连接:https://javascript.info/onload-ondomcontentloaded

The lifecycle of an HTML page has three important events:

  • DOMContentLoaded – the browser fully loaded HTML, and the DOM tree is built, but external resources like pictures <img> and stylesheets may be not yet loaded.
  • load – not only HTML is loaded, but also all the external resources: images, styles etc.
  • beforeunload/unload – the user is leaving the page.

Each event may be useful:

  • DOMContentLoaded event – DOM is ready, so the handler can lookup DOM nodes, initialize the interface.
  • load event – external resources are loaded, so styles are applied, image sizes are known etc.
  • beforeunload event – the user is leaving: we can check if the user saved the changes and ask them whether they really want to leave.
  • unload – the user almost left, but we still can initiate some operations, such as sending out statistics.

Let’s explore the details of these events.

DOMContentLoaded

The DOMContentLoaded event happens on the document object.

We must use addEventListener to catch it:

document.addEventListener("DOMContentLoaded", ready);
// not "document.onDOMContentLoaded = ..."

For instance:


<script>function ready() {alert('DOM is ready');// image is not yet loaded (unless was cached), so the size is 0x0alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`);}document.addEventListener("DOMContentLoaded", ready);
</script><img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">

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

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

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

DOMContentLoaded and scripts

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

So DOMContentLoaded definitely happens after such scripts:

<script>document.addEventListener("DOMContentLoaded", () => {alert("DOM ready!");});
</script><script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js"></script><script>alert("Library loaded, inline script executed");
</script>

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

Scripts with asyncdefer or type="module" don’t block DOMContentLoaded

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

So here we’re talking about “regular” scripts, like <script>...</script>, or <script src="..."></script>.

DOMContentLoaded and styles

External style sheets don’t affect DOM, so DOMContentLoaded 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:

<link type="text/css" rel="stylesheet" href="style.css">
<script>// the script doesn't not execute until the stylesheet is loadedalert(getComputedStyle(document.body).marginTop);
</script>

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 DOMContentLoaded waits for scripts, it now waits for styles before them as well.

Built-in browser autofill

Firefox, Chrome and Opera autofill forms on DOMContentLoaded.

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

So if DOMContentLoaded 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 DOMContentLoaded event.

window.onload

The load event on the window object triggers when the whole page is loaded including styles, images and other resources.

The example below correctly shows image sizes, because window.onload waits for all images:

<script>window.onload = function() {alert('Page loaded');// image is loaded at this timealert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`);};
</script><img id="img" src="https://en.js.cx/clipart/train.gif?speed=1&cache=0">

window.onunload

When a visitor leaves the page, the unload event triggers on window. 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, unload event is when the user leaves us, and we’d like to save the data on our server.

There exists a special navigator.sendBeacon(url, data) 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 sendBeacon.

Here’s how to use it:

let analyticsData = { /* object with gathered data */ };window.addEventListener("unload", function() {navigator.sendBeacon("/analytics", JSON.stringify(analyticsData));
};
  • 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, but usually it’s a stringified object.
  • The data is limited by 64kb.

When the sendBeacon 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 keepalive 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 – onbeforeunload.

window.onbeforeunload

If a visitor initiated navigation away from the page or tries to close the window, the beforeunload handler asks for additional confirmation.

If we cancel the event, the browser may ask the visitor if they are sure.

You can try it by running this code and then reloading the page:

window.onbeforeunload = function() {return false;
};

For historical reasons, returning a non-empty string also counts as canceling the event. Some time ago browsers used show it as a message, but as the modern specification says, they shouldn’t.

Here’s an example:

window.onbeforeunload = function() {return "There are unsaved changes. Leave now?";
};

The behavior was changed, because some webmasters abused this event handler by showing misleading and annoying messages. So right now old browsers still may show it as a message, but aside of that – there’s no way to customize the message shown to the user.

readyState

What happens if we set the DOMContentLoaded 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 document.readyState property tells us about the current loading state.

There are 3 possible values:

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

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

Like this:

function work() { /*...*/ }if (document.readyState == 'loading') {// loading yet, wait for the eventdocument.addEventListener('DOMContentLoaded', work);
} else {// DOM is ready!work();
}

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

// current state
console.log(document.readyState);// print state changes
document.addEventListener('readystatechange', () => console.log(document.readyState));

The readystatechange 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 <iframe><img> and handlers that log events:

<script>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>

The working example is in the sandbox.

The typical output:

  1. [1] initial readyState:loading
  2. [2] readyState:interactive
  3. [2] DOMContentLoaded
  4. [3] iframe onload
  5. [4] img onload
  6. [4] readyState:complete
  7. [4] 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).

  • document.readyState becomes interactive right before DOMContentLoaded. These two things actually mean the same.
  • document.readyState becomes complete when all resources (iframe and img) are loaded. Here we can see that it happens in about the same time as img.onload (img is the last resource) and window.onload. Switching to complete state means the same as window.onload. The difference is that window.onloadalways works after all other load handlers.

Summary

Page load events:

  • DOMContentLoaded event triggers on document when DOM is ready. We can apply JavaScript to elements at this stage.
    • Script such as <script>...</script> or <script src="..."></script> block DOMContentLoaded, the browser waits for them to execute.
    • Images and other resources may also still continue loading.
  • load event on window triggers when the page and all resources are loaded. We rarely use it, because there’s usually no need to wait for so long.
  • beforeunload event on window 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).
  • unload event on window 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 navigator.sendBeacon.
  • document.readyState is the current state of the document, changes can be tracked in the readystatechange event:
    • loading – the document is loading.
    • interactive – the document is parsed, happens at about the same time as DOMContentLoaded, but before it.
    • complete – the document and resources are loaded, happens at about the same time as window.onload, but before it.

Comments

这篇关于DOMContentLoaded, load, beforeunload, unload的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866320

相关文章

解决SpringBoot启动报错:Failed to load property source from location 'classpath:/application.yml'

《解决SpringBoot启动报错:Failedtoloadpropertysourcefromlocationclasspath:/application.yml问题》这篇文章主要介绍... 目录在启动SpringBoot项目时报如下错误原因可能是1.yml中语法错误2.yml文件格式是GBK总结在启动S

类的load方法和initialize方法对比

1. load方法在main()之前被调用,而initialize方法在main()之后调用 load方法实际是在load_images过程中被调用的。load_images会将当前应用依赖的所有镜像(动态库)加载到内存,在在加载中首先是对镜像进行扫描,将所有包含 load 方法的类加入列表 loadable_classes ,然后从这个列表中逐一调用其所包含的 load 方法。 +[XXCl

Unity Adressables 使用说明(六)加载(Load) Addressable Assets

【概述】Load Addressable Assets Addressables类提供了加载 Addressable assets 的方法。你可以一次加载一个资源或批量加载资源。为了识别要加载的资源,你需要向加载方法传递一个键或键列表。键可以是以下对象之一: Address:包含你分配给资源的地址的字符串。Label:包含分配给一个或多个资源的标签的字符串。AssetReference Obj

How can I load the openai api configuration through js in html?

题意:怎样在HTML中通过JavaScript加载OpenAI API配置 问题背景: I am trying to send a request through js in my html so that openai analyzes it and sends a response, but if in the js I put the following: 我正在尝试通过HTM

JavaBug系列- Failed to load driver class com.mysql.cj.jdbc.Driver in either of HikariConfig class load

JavaBug系列之Mysql驱动问题 Java医生一、关于错误信息二、如何解决问题 Java医生 本系列记录常见Bug,以及诊断过程和原因 Java/一对一零基础辅导/企业项目一对一辅导/日常Bug解决/代码讲解/毕业设计等 V:study_51ctofx 一、关于错误信息 APPLICATION FAILED TO START Description: Fai

【Python百日进阶-Web开发-音频】Day705 - 音频加载 librosa.load / librosa.stream

文章目录 一、音频加载1.1 librosa.load1.1.1 语法与参数1.1.2 例子1.1.2.1 下载并加载文件1.1.2.2 加载并重采样1.1.2.3 加载文件,从第15秒开始,加载5秒- 1.2 librosa.stream1.2.1 语法与参数1.2.2 例子1.2.2.1 一次对 256 帧的块应用短期傅里叶变换。1.2.2.2 使用较短的帧和不重叠的窗口计算流上的 m

【异常】java.sql.SQLException: Unable to load authentication plugin ‘caching_sha2_password‘.

异常现象 执行mysql数据库操作的时候,出现以下异常信息: java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:868) ~[mysql-connector-

$(document).ready()与$(window).load()的区别

1.执行时间不同: 从字面的意思上理解,$(document).ready()就是文档准备好了。也就是浏览器已经解析完整个html文档,dom树已经建立起来了,这时就可以通过class属性或者id属性等等对dom进行操作等。而$(window).load()就是整个页面已经加载完毕。与前者的区别是dom树虽然已经建立起来了,但页面不一定加载完毕,如一些大的图片等,加载完成就需要一定的时间;但是页

解决Can‘t load tokenizer for ‘bert-base-chinese‘.问题

报错提示: OSError: Can't load tokenizer for 'bert-base-chinese'. If you were trying to load it from 'https://huggingface.co/models', make sure you don't have a local directory with the same name. Otherwi

POL(Point-of-Load)负载点电源

负载点(POL)电源在靠近负载处单独放置电源调节器(线性稳压器或DC-DC),解决了高性能半导体器件,例如:微控制器、ASIC等,所面临的高峰值电流、低噪声裕量等设计挑战。 一般我们会把负载点电源尽量靠近负载放置, 这么做可以最大限度地确保供电效率和准确性。 图 1 常见POL电源的拓扑结构 Typical设计POL设计