JavaScript学习笔记28

Posted -恰饭第一名-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript学习笔记28相关的知识,希望对你有一定的参考价值。

一、json

  1. JSON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,json是用来传输的)
  2. JSON.parse(); string---->json
  3. JSON.stringify(); json---->string

例:json的属性名必须加双引号(传的是二进制文本)

在这里插入图片描述


<script>
        var obj = {
            "name": "abc",
            "age": 123
        }
        var str = JSON.stringify(obj);
    </script>

在这里插入图片描述


在这里插入图片描述

在这里插入图片描述

思路:绘制dom树,符合深度优先(纵向)原则,比如先看head—>title—>meta—>body—>div—>strong—>span


dom树是节点解析,dom树解析完毕代表dom树所有的节点解析完毕,不代表加载(下载完毕)完毕。如看到img标签就放到dom树上,然后同时下载


dom树形成完了以后,就等css树形成【cssTree也是深度优先原则】


domTree+cssTree=randerTree,randerTree形成以后。渲染引擎才会绘制页面


domTree改变,randerTree也会改变,会重排,影响效率,要尽量避免重排。


randerTree触发重排(reflow)的情况:dom节点的删除,添加,dom节点的宽高变化,位置变化,display none==>block,offsetWidth,offsetLeft


repaint 重绘:效率也比较低,效率影响较小。触发情况:改颜色,图片

二、异步加载js

js是单线程的,会阻断html,css加载(因为js会修改html和css,一起加载会乱)
所以是同步加载js,先下载js,再下载HTML和css。常规来说js是同步加载的,所以我们讲讲js异步加载的情况

1、 js加载的缺点:加载工具方法没必要阻塞文档,过度加载js会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作

2、有些工具方法需要按需加载,用到再加载,不用时不加载

3、 javascript异步加载的三种方案

  1. defer异步加载,但要等到dom文档全部解析完(dom树生成完)才会被执行,只有IE能用,可以把js写在script标签里。
    (dom文档全部解析完,不代表整个页面加载完)
  2. async 异步加载,加载完就执行,async只能加载外部脚本,不能把js写在script标签里。ie9以上也可以用,w3c标准
    (1和2执行时也不阻塞页面)
  3. 创建script,插入到DOM中,加载完毕后callBack(按需加载,方便)—》常用

js异步加载,属性名和属性值相同可以只写一个defer=“defer”

在这里插入图片描述
下面这样也可以实现异步加载
在这里插入图片描述


async异步加载

在这里插入图片描述

创建script,插入到dom中,加载完毕后callBack

<script>
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "tools.js";

        document.head.appendChild(script);
        //如果不写这一段,就是只加载,不执行,像这样写了执行以后才执行
    </script>

预加载机制:img的灯塔模式

在这里插入图片描述


在这里插入图片描述
demo.js
在这里插入图片描述

在这里插入图片描述

上面这种方式不能执行,会报错



在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

思考:为什么上一个例子当前执行,执行不了,但是设置定时器以后就能执行了?


答案:因为还没有下载完。因为程序执行是非常快的,当程序读到document.head读到test()时上面的script.type和script.src还没又下载完,所以执行不了
所以,能不能有一个方法提示我们,他下载完了,等他下载完了我们在用?


方法一:非ie方法script.οnlοad=function(){},触发script.onload事件就代表他下载完了,当他们下载完了再执行test()

<script>
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "demo.js";
        script.onload = function() {
            test();
        }
        document.head.appendChild(script);
    </script>
function test() {
    console.log("a");
}

方法二:ie上有一个状态码,script.readyState,功能与script.onload相似
script.readyState=“loading”;最开始的值
script.readyState=“complete”;或者"leaded"表示加载完成

在这里插入图片描述


监听这个方法的事件

在这里插入图片描述

    <script>
        var script = document.createElement("script");
        script.type = "text/javascript";
        script.src = "demo.js";
        if (script.readyState) {
            script.onreadystatechange = function() {
                if (script.readyState == "complete" || script.readyState == "loaded") {
                    test();
                }
            }
        } else {
            script.onload = function() {
                //Safari chrome firefox opera
                test();
            }
        }
        document.head.appendChild(script);
    </script>

例:我们把以上两种异步加载js方法封装成函数:(左下是方法三的封装库)

 <script>
        function loadScript(url, callback) {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "demo.js";
            if (script.readyState) {
                script.onreadystatechange = function() {
                    if (script.readyState == "complete" || script.readyState == "loaded") {
                        callback();
                    }
                }
            } else {
                script.onload = function() {
                    //Safari chrome firefox opera
                    callback();
                }
            }
            script.src = url;
            document.head.appendChild(script);
        }
    </script>

事件里面有一个绑定的事件处理函数,当满足一定执行条件才执行的函数叫做回调函数。回调函数叫callback


把上面那个函数折叠,加上下面

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

执行顺序 :先function loadScript(){}
【不会看里面的代码是什么】,再loadScript()【这一步的时候不知道test是什么】,然后执行function里面的内容


为了解决上面的问题,如下例:

在这里插入图片描述
在这里插入图片描述


利用callback变成字符串形式,(不让用eval,只做扩展)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

下面是更好的方法,需要配合库实现

在这里插入图片描述

在这里插入图片描述



三、js 加载时间线(可以理解成浏览器加载时间线)

js 加载时间线:依据 js 出生的那一刻起,记录了一系列浏览器按照顺序做的事(就是一个执行顺序)

js 时间线步骤(创建 document 对象==>文档解析完==>文档解析完加载完执行完)

  1. 创建 Document 对象,开始解析 web 页面。解析 HTML 元素和他们的文本内容后添加 Element 对象和 Text 节点到文档中。这个阶段 document.readyState = ‘loading’。
  2. 遇到 link 外部 css,创建线程,进行异步加载,并继续解析文档。
  3. 遇到 script 外部 js,并且没有设置 async、defer,浏览器同步加载,并阻塞,等待 js 加载完成并执行该脚本,然后继续解析文档。
  4. 遇到 script 外部 js,并且设置有 async、defer,浏览器创建线程异步加载,并继续解析文档。

对于 async 属性的脚本,脚本加载完成后立即执行。(异步禁止使用 document.write(),因为当你整个文档解析到差不多,再调用 document.write(),会把之前所有的文档流都清空,用它里面的文档代替)

  1. 遇到 img 等(带有 src),先正常解析 dom 结构,然后浏览器异步加载 src,并继续解析文档。 看到标签直接生产 dom 树,不用等着 img 加载完 scr。
  2. 当文档解析完成(domTree 建立完毕,不是加载完毕),document.readyState = ‘interactive’。
  3. 文档解析完成后,所有设置有 defer 的脚本会按照顺序执行。(注意与 async 的不同,但同样禁止使用 document.write());
  4. document 对象触发 DOMContentLoaded 事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。
  5. 当所有 async 的脚本加载完成并执行后、img 等加载完成后(页面所有的都执行加载完之后),document.readyState = ‘complete’,window 对象触发 load 事件。
  6. 从此,以异步响应方式处理用户输入、网络事件等。


异步禁止使用document.write()

在这里插入图片描述

在这里插入图片描述


用window.onload会等整个页面加载完才执行,消除文档流(把自己script删了)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


执行到document.readyState时,整个dom树还没有解析完,所以不会是interactive

在这里插入图片描述
在这里插入图片描述


我们就利用window.onload事件,看到的是complete,代表执行加载完

在这里插入图片描述

在这里插入图片描述


如果想看到 interactive,所有事件都是用的小写

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述

这个事件只在 addEventListener 上面能用

在这里插入图片描述
在这里插入图片描述


通用写法是把 JS 的 script 写在最下面,为什么我们要把他写在最下面?写在最下面意味着上面的 dom 已经处理完毕了。window.onload 是整个页面加载完才执行,慢 , dom 解析完毕就执行完就执行,比较快。

在这里插入图片描述

只要有一个图片没加载完,window.onload 就不能用,所以效率非常低下


script 标签这样写在上面。又能操作 div,又能 dom 解析完就处理,效率很高。但是最好还是写在最下面

在这里插入图片描述


四、BOM(权限过大,不让用)

定义:Browser Object Model,定义了操作浏览器的接口
BOM 对象: Window, History,Navigator,Screen, Location 等
由于浏览器厂商的不同,Bom 对象的兼容性极低。一般情况下,只用其中的部分功能。
Window
History 对象
Navigator 对象
http://www.w3school.com.cn/jsref/dom_obj_navigator.asp
Screen 对象
Location 对象
location.hash
“#”后是对浏览器操作的,对服务器无效,实际发出的请求也不包含”#”后面的
部分
“#”被算作历史记录

以上是关于JavaScript学习笔记28的主要内容,如果未能解决你的问题,请参考以下文章

学习笔记:python3,代码片段(2017)

ReactJs学习笔记01

Javascript MVC 学习笔记 视图和模板

ArcGIS API for JavaScript 4.2学习笔记[28] 可视域分析使用Geoprocessor类

译文:18个实用的JavaScript代码片段,助你快速处理日常编程任务

[原创]java WEB学习笔记61:Struts2学习之路--通用标签 property,uri,param,set,push,if-else,itertor,sort,date,a标签等(代码片段