JS 学习笔记 | BOM 篇

1.什么是 BOM

BOM(Browser Object Model)即浏览器对象模型。

关于 BOM 的说明:

  • BOM 提供了独立于內容,而与浏览器窗口进行交互的对象。
  • 由于 BOM 主要用于管理窗口和窗口之间的通讯,因此其核心对象是 window 对象
  • BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。
  • BOM 缺乏一个统一的标准:
    • JavaScript 语法的标准组织是 ECMA
    • DOM 的标准组织是 W3C(所有浏览器公共遵守的标准)。
    • BOM 是各个浏览器厂商根据 DOM 在各自浏览器上的表现(表现为不同浏览器定义有差别,实现方式不同)。

注意:通常情况下如果提到 BOM,一般指的都是 window 对象。

2.BOM 和 DOM 之间的关系

在这里插入图片描述

可以认为 BOM 是浏览器窗口,DOM 则是浏览器窗口中的页面。

总结

  • DOM 通过 document 对象来访问、控制、修改 html 和 xhtml 等文档中的内容。
  • BOM 通过 window 对象来访问、控制、修改浏览器中的內容。
  • 联系:
    • BOM 包含 DOM,浏览器提供用来访问的是 BOM 对象,从 BOM 对象可以访问到 DOM 对象,从而使 JavaScript 可以操作浏览器,并通过操作浏览器读取到文档的內容。
  • 区别:
    • DOM 描述了处理网页內容的方法和接口,即操作页面内部。BOM 描述了与浏览器进行交互的方法和接口,即操作页面之间

3.window 对象

window 对象是 BOM 的具体表现形式。window 和 BOM 之间的关系就像 document 和 DOM 之间的关系一样,BOM 相当于 DOM,window 相当于 document。

注意:因为 window 对象是 JS 中的顶级对象,因此所有定义在全局作用域中的变量、函数都会变成 window对象的属性和方法,在调用的时候可以省略 window
例如:

// 打开窗口
window.open(url);  // 等价于 open(url);
// 关闭窗口
window.close(); // 等价于 close();
// 获取事件
window.event;   // 等价于 event
// 获取文档
window.document;    // 等价于 document

3.1 window 对象中常用的属性和方法

3.1.1 window.name

属性:
window.namewindow 对象的一个属性,默认值为空。
特性:
window.name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB左右)。
应用:
正是由于 window.name 属性拥有在不同页面依旧存在的特性,因此出现了一门叫做 跨域传输 的技巧。而这个技巧的内部实现原理就是 window.name 的持久性的特征。

3.1.2 window 尺寸属性

  • window.outerHeightwindow.outerWidth,这两个属性返回的是整个浏览器的高度,和页面窗口的大小没有任何关系
    console.log("outerHeight " + window.outerHeight);
    console.log("outerWidth " + window.outerWidth);
    
  • window.innerHeightwindow.innerWidth,返回视口的高度和宽度(计算滚动条),页面变化它就变。
    console.log("innerHeight " + window.innerHeight);
    console.log("innerWidth " + window.innerWidth);
    
  • document.documentElement.clientHeightdocument.documentElement.clientWidth,返回视口的高度和宽度(不计算滚动条)。
    console.log("clientHeight " + document.documentElement.clientHeight);
    console.log("clientWidth " + document.documentElement.clientWidth);
    
  • window.pageXOffsetwindow.pageYOffset 返回页面滚动的距离(通用),这两个属性指的是页面发生滚动的距离
    console.log("pageYOffset: " + window.pageYOffset);
    console.log("pageXOffset: " + window.pageXOffset);
    
  • window.screenYwindow.screenX 返回浏览器距离屏幕左上角的距离
    console.log("screenY: " + window.screenY);
    console.log("screenX: " + window.screenX);
    

3.1.3 window.navigator 对象属性

window.navigator 对象包含大量有关 Web 浏览器的信息,在检测浏览器及操作系统上非常有用。(这个对象和 event一样,是全局并且唯一的。)

navigator.appCodeName   // 浏览器代码名的字符串表示
navigator.appName   // 官方浏览器名的字符串表示
navigator.appVersion    // 浏览器版本信息的字符串表示
navigator.cookieEnable  // 如果启用 cookie 返回 true,否则返回 false
navigator.javaEnable    // 如果启用 java 则返回 true,否则返回 false
navigator.platform  // 浏览器所在计算机平台的字符串表示
navigator.plugins   // 安装在浏览器中的插件数组
navigator.userAgent // 返回和浏览器内核相关的信息(加粗)

注意:如果 window.navigator.userAgent 出现了 Mobile,则可以确定用户使用的是移动设备。

3.2 window 对象中涉及的其它方法

在这里插入图片描述

在这里插入图片描述

3.2.1 alert

alert 是一个警示框,作用是提示用户信息,该方法执行后无返回值
语法:

window.alert("Hello World!");
// 或
alert("Hello World!");

注意:警示框弹出后将阻断程序执行,必须关闭警示框程序才会继续执行。

3.2.2 prompt

prompt 也表示警示框,作用是提示用户信息,该方法执行后根据情况不同返回值略有不同。

  • 点击取消:返回 null
  • 没有默认值:
    如果用户没有输入內容,返回一个空字符串。
    如果用户输入了內容,返回值为用户输入的內容。
  • 有默认值
    如果用户没有输入內容,返回默认值
    如果用户输入了內容,返回值为用户输入的內容。

语法:

// 默认值不是必须的
var res = prompt(msg, defaultMsg);

3.2.3 confirm

confirm 表示警示框,作用是提示用户信息,点击确认返回 true,点击取消返回 false
语法:

var msg = window.confirm("我是 confirm");
console.log(msg);

注意:以上三种对话框都是模式对话框,即在用户点击确定按钮或者取消按钮把对话框关闭之前,它将阻止用户对浏览器的所有输入,并暂停对 JavaScript 代码的执行,在用户做出响应之前,不会执行下一条语句。

3.2.4 间隔调用和延迟调用

  • 使用间隔调用
    setInterval方法用于实现间隔调用,又被称为定时器。是一种能够每隔一定时间自动执行一次的函数。
    语法:

    var timer = null;
    timer = setInterval(function() {
        console.log("hello");
    }, 1000);
    

    以上代码会每隔 1s 打印一次 hello,所以 function 代表的是要被回调的函数,1000 代表的是函数调用的时间间隔。

    如果间隔调用的函数需要传入参数,则间隔调用需要使用如下的声明方式。
    语法:

    var timer = null;
    timer = setInterval(字符串, 执行事件的时间间隔 ms);
    

    例如:

    var timer = null;
    function show(words) {
        console.log(words);
    }
    var timer = setInterval('show("hello")', 1000);
    

    注意

    • 间隔调用不是立即执行,而是在 任务队列中的任务完成后 才执行间隔调用。
    • 因为间隔调用函数的实际执行者是 window,因此间隔调用内部的 this 指向 window
  • 移除间隔调用
    clearInterval 方法用于移除间隔调用
    语法:

    clearInterval(timer);
    

    上述代码能够将刚才创建的定时器移除掉。
    注意:间隔调用的返回值是一个数字队列,因此通过访问数字队列来清除间隔调用也是被允许的。
    例如:

    setInterval(function() {
        console.log("hello");
    }, 1000);
    
    setTimeout(function() {
        clearInterval(1);
    }, 5000);
    
  • 延迟调用
    延迟调用又叫延迟调用函数。是一种能够等待一定事件后再去执行的函数。
    语法:

    var timer = null;
    timer = setTimeout(需要执行的函数, 等待的时间);
    

    例如:

    var timer = setTimeout(function() {
        clearInterval(1);
    }, 5000);
    

    上面代码的功能是在页面加载 5s 后清除定时器。

4.数据解析

数据解析是指将 不能被直接打开的数据 通过某种方法转变为 能够被直接使用的数据
对于开发者来说最常见的数据解析就是将 字符串数据 解析为 对象数据

例如:

function parseData() {
    var obj = {};
    var infoStr = document.location.search;
    var realInfo = infoStr.slice(1);
    var infoArr = realInfo.split("&");
    for (var i = 0; i < infoArr.length; i++) {
        var tempArr = infoArr[i].split("=");
        obj[tempArr[0]] = decodeURIComponent(tempArr[1]);
    }
    return obj;
}

5.页面加载优化和 JS 文件解析顺序

在阅读下面的内容之前,先了解一下 JavaScript 引擎这个概念。
JS 引擎是由渲染引擎解释器构成。

  • 渲染引擎

    • 解析代码:HTML 代码解析为 DOM 树
    • 对象的合成:CSS 和 DOM 合成一棵渲染树
    • 布局:计算出渲染树的布局
    • 绘制:将渲染树绘制到屏幕

    注意:这四步不一定严格按照顺序来执行。

  • JS 解释器
    能够将 JS 代码解释成可以在网页中实现的工具。

5.1 加载优化

5.1.1 defer

该属性可以等待 DOM 加载完毕后再去加载脚本,可以避免因外部文件过大或网络卡顿导致文件阻塞。
例子:

// 从外部引入一个死循环的 js 代码
<script src="js/01.js" defer></script>

<script>
    console.log("哈哈哈");
</script>

如果不使用 defer 属性,则会出现死循环导致 哈哈哈 无法被打印出来,使用 defer 后可以先输出內容,再加载外部脚本。

5.1.2 async(推荐使用)

  • 作用:该属性可以使 DOM 加载和 JS 脚本加载异步执行,从而同时进行。
  • 优点:避免因 DOM 文件过大导致的 文件加载阻塞
  • 缺点:无法确定 JS 脚本到底何时执行,并仅对外部 JS 脚本有效

例如:

<script src="js/01.js" async></script>
<script src="js/02.js" async></script>

console.log("页面内部的脚本");

按照我们的说法,引入的两个 JS 脚本和本地的 DOM 是异步执行的,也就是说究竟先输出那句是不一定的,但是事实却不是这样

注意:由于 HTML5 规范要求,脚本执行应该按照脚本出现的先后顺序执行,所以应该是先输出页面内部的脚本,然后是01.js 中的内容,然后是 02.js 里的内容。

5.2 性能优化

5.2.1 重绘(repaint)与回流(reflow)

重绘:当页面的可见性发生变化时,我们说页面发生了重绘。
回流:当页面中的部分(全部)元素改变宽度和高度,或者位置发生变化,删除或增加某个(某些元素)、某个元素隐藏或显示时,这时页面的重新加载被称为回流。

总结:回流必将引起重绘,但是重绘不一定会引起回流。

注意

  • 重绘的代价是高昂的,因为浏览器必须验证 DOM 树上其它元素节点的可见性。
  • 回流更是浏览器性能的关键,因为其变化设计到页面的布局。一个元素的回流导致了其所有子元素以及 DOM 中紧随其后的祖先元素的随后的回流。

5.2.2 重绘和回流的原因

  • 调整窗口大小
  • 改变字体
  • 增加或者移除样式表
  • 用户在 input 框中输入文字
  • 激活 CSS 伪类
  • 操作 class 属性
  • 脚本操作 DOM
  • 计算 offsetWidthoffsetHeight
  • 设置 style 属性的值

5.2.3 如何从重绘和回流方面提高浏览器性能

  • 不要打断修改样式的过程,例如在修改样式时创建新元素
  • 读写 DOM 尽量放在一起,避免一会读一会写
  • 将创建的内容添加到文档碎片 var fragment = document.createDocumentFragment(); 中,然后统一进行添加
  • 使用 fixedabsolute 可减少回流和重绘
  • 使用如下方式把发生重绘的代码推迟到下一次重绘发生时一起执行
    window.requestAnimationFrame(function() {
    for (var i = 0; i < div.length; i++) {
            div[i].style.backgroundColor = "red";
        }
    })
    

6.window.history

window.history 对象表示整个浏览器的页面栈对象。在对象中提供了一些属性和方法更好的控制整个浏览器中页面的访问。

6.1 back()

跳转到栈中的上一个页面

6.2 forward()

跳转到栈中的下一个页面

6.3 go(num)

指定跳转的页面个数

6.4 length

栈中页面的数量

注意:使用 window.history 对象中提供的方法进行的页面跳转并不会向栈中添加新的页面,而通过 window.location.href 或者通过 a 标签进行跳转,则会向栈中添加新的页面。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353