浏览器的核心是两部分:渲染引擎和 JavaScript 解释器(又称 JavaScript 引擎)。
文章目录
浏览器
渲染引擎
渲染引擎的主要作用是,将网页代码渲染为用户视觉可以感知的平面文档。
不同的浏览器有不同的渲染引擎。
- Firefox:Gecko 引擎
- Safari:WebKit 引擎
- Chrome:Blink 引擎
- IE: Trident 引擎
- Edge: EdgeHTML 引擎
渲染引擎处理网页,通常分成四个阶段。
- 解析代码:HTML 代码解析为 DOM,CSS 代码解析为 CSSOM(CSS Object Model)。
- 对象合成:将 DOM 和 CSSOM 合成一棵渲染树(render tree)。
- 布局:计算出渲染树的布局(layout)。
- 绘制:将渲染树绘制到屏幕。
以上四步并非严格按顺序执行
重流和重绘
渲染树转换为网页布局,称为“布局流”(flow);
布局显示到页面的这个过程,称为“绘制”(paint)。
它们都具有阻塞效应,并且会耗费很多时间和计算资源。
页面生成以后,脚本操作和样式表操作,都会触发“重流”(reflow)和“重绘”(repaint)。用户的互动也会触发重流和重绘
重流必然导致重绘,重绘不一定需要重流
比如改变元素颜色,只会导致重绘,而不会导致重流;改变元素的布局,则会导致重绘和重流。
作为开发者,应该尽量设法降低重绘的次数和成本。比如,尽量不要变动高层的 DOM 元素,而以底层 DOM 元素的变动代替;再比如,重绘table布局和flex布局,开销都会比较大。
JavaScript 引擎
JavaScript 引擎的主要作用是,读取网页中的 JavaScript 代码,对其处理后运行。
JavaScript 是一种解释型语言,也就是说,它不需要编译,由解释器实时运行。这样的好处是运行和修改都比较方便,刷新页面就可以重新解释;缺点是每次运行都要调用解释器,系统开销较大,运行速度慢于编译型语言。
为了提高运行速度,目前的浏览器都将 JavaScript 进行一定程度的编译,生成类似字节码(bytecode)的中间代码,以提高运行速度
字节码不能直接运行,而是运行在一个虚拟机(Virtual Machine)之上,一般也把虚拟机称为 JavaScript 引擎。
有的 JavaScript 虚拟机基于源码,通过 JIT(just in time)编译器直接把源码编译成机器码运行省略字节码步骤。
最常见的一些 JavaScript 虚拟机:
- Chakra (Microsoft Internet Explorer)
- Nitro/JavaScript Core (Safari)
- Carakan (Opera)
- SpiderMonkey (Firefox)
- V8 (Chrome, Chromium)
开发者
- Preserve log
https://zhuanlan.zhihu.com/p/439206293
window 对象
浏览器里面,window对象(w为小写)指当前的浏览器窗口。它也是当前页面的顶层对象
一个变量如果未声明,那么默认就是顶层对象的属性。
window 对象的属性
-
window.name
表示当前浏览器窗口的名字。窗口不一定需要名字,这个属性主要配合超链接和表单的target属性使用。浏览器窗口不关闭,这个属性是不会消失 -
window.closed
检查当前窗口是否关闭, 一般用来检查,使用脚本打开的新窗口是否关闭。 -
window.opener
打开当前窗口的父窗口 -
window.self,window.window
都指向窗口本身。属性只读。 -
window.frames,window.length
window.frames属性返回一个类似数组的对象,成员为页面内所有框架窗口,包括frame元素和iframe元素。
window.length属性返回当前网页包含的框架总数。
//frames属性实际上是window对象的别名。
frames === window // true
-
window.frameElement
用于当前窗口嵌在另一个网页的情况(嵌入、或元素),返回当前窗口所在的那个元素节点。 -
window.isSecureContext
如果是 HTTPS 协议,就是true,否则就是false。 -
位置属性
- window.screenX,window.screenY
浏览器窗口左上角相对于当前屏幕左上角的水平距离和垂直距离(单位像素)。属性只读。 - window.innerHeight,window.innerWidth
网页在当前窗口中可见部分的高度和宽度,即“视口”(viewport)的大小(单位像素)。属性只读。
用户放大网页的时候(比如将网页从100%的大小放大为200%),这两个属性会变小。因为可见部分(视口)变小了。这两个属性值包括滚动条的高度和宽度。 - window.outerHeight,window.outerWidth
浏览器窗口的高度和宽度,包括浏览器菜单和边框(单位像素)。属性只读。 - window.scrollX,window.scrollY
页面的水平滚动距离,垂直滚动距离, 双精度浮点数(单位像素)。属性只读。 - window.pageXOffset,window.pageYOffset
是window.scrollX和window.scrollY别名
- window.screenX,window.screenY
-
组件属性
组件属性返回浏览器的组件对象。属性只读- window.locationbar:地址栏对象
- window.menubar:菜单栏对象
- window.scrollbars:窗口的滚动条对象
- window.toolbar:工具栏对象
- window.statusbar:状态栏对象
- window.personalbar:用户安装的个人工具栏对象
-
全局对象属性
全局对象属性指向一些浏览器原生的全局对象。- window.document:指向document对象,这个属性有同源限制。只有来自同源的脚本才能读取这个属性。
- window.location:指向Location对象,用于获取当前窗口的 URL 信息。它等同于document.location属性。
- window.navigator:指向Navigator对象,用于获取环境信息。
- window.history:指向History对象,表示浏览器的浏览历史。
- window.localStorage:指向本地储存的 localStorage 数据。
- window.sessionStorage:指向本地储存的 sessionStorage 数据。
- window.console:指向console对象,用于操作控制台。
- window.screen:指向Screen对象,表示屏幕信息。
window 对象的方法
- 对话框
- window.alert()
弹出的对话框,只有一个“确定”按钮, 用户只有点击“确定”按钮,对话框才会消失。对话框弹出期间,具有堵塞效应,一旦弹出对话框,整个页面就是暂停执行,等待用户做出反应。 - window.prompt()
弹出的对话框,提示文字的下方,还有一个输入框,要求用户输入信息,并有“确定”和“取消”两个按钮。它往往用来获取用户输入的数据。具有堵塞效应 - window.confirm()
弹出的对话框,除了提示信息之外,只有“确定”和“取消”两个按钮,往往用来征询用户是否同意。具有堵塞效应
- window.alert()
- 窗口操作
- window.open()
新建另一个浏览器窗口,类似于浏览器菜单的新建窗口选项。它会返回新窗口的引用 - window.open()
关闭当前窗口,一般只用来关闭window.open方法新建的窗口 - window.stop()
等同于单击浏览器的停止按钮,会停止加载图像、视频等正在或等待加载的对象。
- window.open()
window.open(url, windowName, [windowFeatures])
//例
var popup = window.open(
'somepage.html',
'DefinitionsWindows',
'height=200,width=200,location=no,status=yes,resizable=yes,scrollbars=yes'
);
- window.moveTo(),window.moveBy()
window.moveTo()方法用于移动浏览器窗口到指定位置。它接受两个参数,分别是窗口左上角距离屏幕左上角的水平距离和垂直距离,单位为像素。
window.moveBy()方法将窗口移动到一个相对位置。它接受两个参数,分别是窗口左上角向右移动的水平距离和向下移动的垂直距离,单位为像素。
window.moveTo(100, 200)
window.moveBy(25, 50)
-
window.resizeTo(),window.resizeBy()
window.resizeTo()方法用于缩放窗口到指定大小。
它接受两个参数,第一个是缩放后的窗口宽度(outerWidth属性,包含滚动条、标题栏等等),第二个是缩放后的窗口高度(outerHeight属性)。window.resizeBy()方法用于缩放窗口。它与window.resizeTo()的区别是,它按照相对的量缩放,window.resizeTo()需要给出缩放后的绝对大小。
//缩放一半
window.resizeTo(
window.screen.availWidth / 2,
window.screen.availHeight / 2
)
//缩小200像素
window.resizeBy(-200, -200)
- window.print()
跳出打印对话框,与用户点击菜单里面的“打印”命令效果相同。 - window.focus(),window.blur()
window.focus()方法会激活窗口,使其获得焦点,出现在其他窗口的前面。
window.blur()方法将焦点从窗口移除。 - window.getSelection()
返回一个Selection对象,表示用户现在选中的文本 - window.requestAnimationFrame()
跟setTimeout类似,都是推迟某个函数的执行。
推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。 - window.requestIdleCallback()
也是将某个函数推迟执行,但是它保证将回调函数推迟到系统资源空闲时执行。
多窗口操作
由于网页可以使用iframe元素,嵌入其他网页,因此一个网页之中会形成多个窗口。如果子窗口之中又嵌入别的网页,就会形成多级窗口。
窗口的引用
各个窗口之中的脚本,可以引用其他窗口。浏览器提供了一些特殊变量,用来返回其他窗口。
- top:顶层窗口,即最上层的那个窗口
- parent:父窗口
- self:当前窗口,即自身
iframe 元素
对于iframe嵌入的窗口,document.getElementById方法可以拿到该窗口的 DOM 节点,然后使用contentWindow属性获得iframe节点包含的window对象。
//该窗口的 DOM 节点
var frame = document.getElementById('theFrame');
//子窗口的window对象
var frameWindow = frame.contentWindow;
// 获取子窗口的标题
frameWindow.title
//<iframe>元素的contentDocument属性,可以拿到子窗口的document对象。
var frameDoc = frame.contentDocument;
// 等同于
var frameDoc = frame.contentWindow.document;
window.frames 属性
可以使用这个属性,实现窗口之间的互相引用。比如,
frames[0]返回第一个子窗口,
frames[1].frames[2]返回第二个子窗口内部的第三个子窗口,
parent.frames[1]返回父窗口的第二个子窗口。
window.frames每个成员的值,是框架内的窗口(即框架的window对象),而不是iframe标签在父窗口的 DOM 节点。如果要获取每个框架内部的 DOM 树,需要使用window.frames[0].document的写法。