一次性分清DOMContentLoaded、window.onload、style

简单来说

  1. onload事件触发时,页面上所有的DOM,样式表,图片,js等都完全加载完成;
  2. DOMContentLoaded事件触发时,仅仅是DOM加载完成,但不包括样式表,图片等;
  3. 先触发DOMContentLoaded事件,后触发load事件;

看个栗子:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script type="text/javascript" src="script.js"></script>

    <script language="javascript">
        window.onload = haha;
        function haha(){console.log(document.getElementById("div1"));}

        if(document.addEventListener){
            function DOMContentLoaded(){
                console.log("DOMContentLoaded");
            }
            document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
        }
    </script>

</head>
<body>
    <div id="div1">a</div>
</body>
</html>

如上代码,我们分别绑定了onload和DOMContentLoaded两个事件,执行结果是先打印出DOMContentLoaded,再输出div1这个节点内容,佐证了以上三点。

为什么会有两种事件?

我们需要给一些元素的事件绑定事件处理函数,但潜在的问题是,如果那个元素还没有加载到页面上,但是绑定事件已经执行完了,是没有效果的;

上述这两个事件就是用来避免这种情况的发生,将绑定函数放在两个事件中,保证能在页面的某些元素加载完毕之后再执行事件处理函数。

当然DOMContentLoaded机制更加合理,因为我们可以容忍图片,flash延迟加载,却不可以容忍看见内容后页面不可交互。

Jquery中的ready

jq中,我们常常看到以下两种等价的写法

$(document).ready(function(){
  // 在这里写你的代码...
});

$(function($) {    // 简化写法
  // 你可以在这里继续使用$作为别名...
});

在没有出现DOMContentLoaded事件出现以前,jq中的上述写法就是模拟这个事件的方法;

window.onload

window.onload无法注册多个事件处理函数,如下代码无法执行,会出现报错

window.onload = function(){
  alert("test1");
};

window.onload = function(){
  alert("test2");
};

但是jq的$(document).ready()能同时编写多个,并且都会输出

$(document).ready(function(){
   alert("Hello World");
});
$(document).ready(function(){
   alert("Hello again");
}); 

样式阻塞

根据文档,该事件仅当在DOM加载完成之后触发,实际上有时并非如此!

一般来说,外部样式文件并不会响到DOMCotentLoaded事件,它并不会等待外部样式文件加载完成。

但是!!!在某些版本的Gecko和Webkit引擎的浏览器中,有些情况会使等待样式表加载完成后才触发DOMContentLoaded事件。最普遍的情况便是将脚本写在样式表后面:

html

<!DOCTYPE html>
<head>
    <linkrel="stylesheet"href="stylesheet.css">
    <scriptsrc="script.js"></script>
</head>
<body>
    <divid="element">The element</div><
/body>

css

#element { color: red; }

js

document.addEventListener(‘DOMContentLoaded‘,function(){
     alert(getComputedStyle(document.getElementById(‘element‘),null).color);},
false);

如上,脚本是可以读出color属性值的,也就是说触发DOMContentLoaded事件时,样式表也加载完成了,样式表阻塞了DOM的构建!!!

原因是浏览器猜测脚本可能会读取一些样式信息,如位置、颜色,显然脚本就需要等到样式的加载完成了。

这也是为什么我们最好把脚本文件放到HTML文档的最后再加载,而不要把脚本放在head标签里,除非你清楚放在head标签里是必要的。

异步脚本

load与DOMContentLoaded标志着页面上两个重要的时刻:

  • DOMContentLoaded:DOM已经完成加载,此时可以为这些DOM元素绑定事件,初始化接口等
  • Load:其他外部资源均已加载完成,可以正确读出这些资源的信息,如图片的宽高等

异步的script

当解析器遇到内联标签的脚本<script>...</script>时,会阻塞DOM的构建,读取后会立即执行脚本。原因是可能这些脚本会影响DOM,因此需要等到这些脚本都执行完成了,才会触发DOMContentLoaded事件。

阻塞同样对外联脚本有效(<script src="...">...</script>),浏览器需要等到加载后再执行完成才可以继续执行。

对于外联的脚本,我们有方法让其延后执行,asyncdefer属性登场,他们可以让外部脚本延后执行,而不阻塞浏览器解析文档,但他们对内联脚本无效。

async & defer 均可以让浏览器继续完成dom的加载,而不用等待脚本加载完成,他们的区别如下:

区别 async defer
执行顺序 谁先完成下载谁先执行 执行顺序始终遵循加载的顺序,即使先下载完成了
DOMContentLoaded 如果页面加载时间较长,脚本可能会先执行;绝大多数会在DOMContentLoaded之后执行,但一定是在Load事件之前执行 脚本会在DOMContentLoaded之前执行,但不阻塞浏览器加载和解析文档,即defer脚本与浏览器加载顺序无关先后

参考列表

  1. 从onload和DOMContentLoaded谈起
  2. https://juejin.im/post/5a36499551882529c70f34b5

原文地址:https://www.cnblogs.com/CharmanderS5/p/9057468.html

时间: 2024-08-02 11:07:22

一次性分清DOMContentLoaded、window.onload、style的相关文章

window.onload、DOMContentLoaded和$(document).ready()

window.onload.DOMContentLoaded和$(document).ready() <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <scr

DOMContentLoaded和window.onload

相信写js的,都知道window.onload吧,但是并不是每个人都知道DOMContentLoaded,其实即使你不知道,很有可能你也经常使用了这个东西. 一般情况下,DOMContentLoaded事件要在window.onload之前执行,当DOM树构建完成的时候就会执行DOMContentLoaded事件,而window.onload是在页面载入完成的时候,才执行,这其中包括图片等元素.大多数时候我们只是想在DOM树构建完成后,绑定事件到元素,我们并不需要图片元素,加上有时候加载外域图片

jQuery Ready 与 Window onload 的区别(转)

“我们都知道,很多时候,在页面加载完后都需要做一些相应的初始化动作.例如,运行某些js特效,设置表单等等.怎么知道页面加载完了呢?一 般情况下都是设置body标签的onload监听window的load事件.但load事件是要在页面的元素全部加载完了才触发的,如果页面上图片较多 或图片太大,就会导致初始化的代码未被执行的时候用户就做了其它操作了. Jquery库提供了一个非常方便好用的函数( $(selector).ready()),让我们可以在页面的dom加载完后就可以做相应的操作(当然,这还

jQuery Ready 与 Window onload 的区别

在网上看到一篇文章与大家分享一下: “我们都知道,很多时候,在页面加载完后都需要做一些相应的初始化动作.例如,运行某些js特效,设置表单等等.怎么知道页面加载完了呢?一般情况下都是设置body标签的onload监听window的load事件.但load事件是要在页面的元素全部加载完了才触发的,如果页面上图片较多或图片太大,就会导致初始化的代码未被执行的时候用户就做了其它操作了. Jquery库提供了一个非常方便好用的函数( $(selector).ready()),让我们可以在页面的dom加载完

js 完全分离 window.onload=

js 完全分离  window.onload= <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>TAB菜单</title> <script type="text/javascript"

window.onload用法详解

window.onload用法详解: 网页中的javascript脚本代码往往需要在文档加载完成后才能够去执行,否则可能导致无法获取对象的情况,为了避免这种情况的发生,可以使用以下两种方式: 一.将脚本代码放在网页的低端,这样在运行脚本代码的时候,可以确保要操作的对象已经加载完成. 二.通过window.onload来执行脚本代码. 第一种方式感觉比较凌乱(其实推荐使用),往往我们需要将脚本代码放在一个更为合适的地方,那么window.onload方式就是一个更好的选择.window.onloa

谈谈document.ready和window.onload的区别

在Jquery里面,我们可以看到两种写法:$(function(){}) 和$(document).ready(function(){}) 这两个方法的效果都是一样的,都是在dom文档树加载完之后执行一个函数(注意,这里面的文档树加载完不代表全部文件加载完). 而window.onload是在dom文档树加载完和所有文件加载完之后执行一个函数.也就是说$(document).ready要比window.onload先执行. 那么Jquery里面$(document).ready函数的内部是怎么实

window.onload和window.document.readystate的探究

在编写前端页面的时候,我们时常需要对页面加载的状态进行判断,以便进行相应的操作. 比如在移动端,时常需要在页面完全加载完成之前,先显示一个loading的图标,等待页面完成加载完成后,才显示出真正要展现的页面元素.见代码1: <html> <head> <script src="http://code.jquery.com/jquery-1.8.0.min.js"></script> <script> function isL

js中window.onload与jquery中$(document.ready())的区别

$(document).ready()是在DOM结构载入完后执行的,而window.onload是得在所有文件都加载完后执行的,注意区别,一个是DOM加载完,一个是所有文件加载完 耳听为虚,眼见为实.通过下面的实例可查看两者的异同(注意:aa.jpg最好是一张大容量图片) <html> <head> <script type='text/javascript' src='jquery-1.3.2.min.js'></script> <script ty