目录
1. BOM 概述
1.1 BOM 简介
BOM(Browser Object Model)即浏览器对象模型,它提供了独立于网页内容、专门用于与浏览器窗口交互的对象集合,其中核心对象为 window。BOM 由一系列功能各异的对象构成,每个对象都附带众多实用的方法与属性,极大地拓展了 JavaScript 在浏览器环境中的操作能力。不过,BOM 与严格标准化的 JS 语法(由 ECMA 组织规范)和 DOM(由 W3C 组织规范)不同,它最初源于 Netscape 浏览器的标准,在标准化方面存在一定缺失,这也导致了不同浏览器对 BOM 的支持和实现存在差异。
1.2 DOM 与 BOM 的区别
类别 | DOM | BOM |
定义 | 文档对象模型 | 浏览器对象模型 |
看待对象 | 将文档视为一个整体对象进行操作 | 把浏览器本身作为一个对象来交互 |
顶级对象 | document | window |
主要学习内容 | 聚焦于页面元素的访问、修改与创建等操作 | 侧重于浏览器窗口相关的交互功能,如窗口控制、地址栏操作等 |
标准规范 | 遵循 W3C 制定的统一标准,具有良好的兼容性和一致性 | 由各浏览器厂商自行定义标准,导致兼容性问题较为突出 |
1.3 BOM 的构成 (对象)
BOM 是一个比 DOM 更宽泛的概念,它涵盖了 DOM,为开发者提供了全方位控制浏览器的能力。BOM 主要由以下核心对象构成:
- window:代表整个浏览器窗口,是网页运行的全局环境。它具有双重角色,既是 JavaScript 与浏览器窗口沟通的桥梁,允许开发者操作浏览器窗口的各种属性和行为;同时也是一个全局对象,在全局作用域中定义的变量和函数,都会自动成为 window 对象的属性和方法,调用时可以省略 window 前缀。例如常见的 alert () 和 prompt () 函数,实际上都是 window 对象的方法。需要注意的是,window 对象有一个名为 name 的特殊属性,为避免命名冲突,在定义变量时应尽量避免使用 name 作为变量名。
- document:作为 DOM 的核心对象,代表当前加载的网页文档。通过 document 对象,开发者可以访问、修改和操作网页中的所有元素,包括 HTML 标签、文本内容、样式等,是实现网页动态交互的关键。
- location:包含了浏览器地址栏的信息,通过它可以获取当前页面的完整 URL,也能对 URL 的各个部分进行解析和修改,从而实现页面的跳转和导航功能。比如在开发中,需要引导用户跳转到特定页面时,就可以借助 location 对象轻松实现。
- navigator:主要用于识别当前浏览器的相关信息,虽然由于历史原因,其大部分属性已不再适用于精确识别浏览器,但 userAgent 属性依然被广泛应用。userAgent 是一个包含浏览器详细信息的字符串,不同浏览器的 userAgent 具有独特的特征,通过分析这个字符串,开发者可以判断用户使用的浏览器类型、版本等信息。
- screen:代表用户屏幕的相关信息,通过该对象,开发者可以获取用户显示器的参数,如屏幕分辨率、颜色深度、屏幕尺寸等,这些信息在进行响应式设计、适配不同屏幕设备时非常重要。
- history:用于与浏览器的历史记录进行交互,开发者可以通过它实现页面的前进、后退等操作,类似于浏览器的前进和后退按钮功能。但出于隐私保护考虑,history 对象无法获取具体的历史记录内容,且相关操作仅在当前访问会话中有效。
这些 BOM 对象在浏览器中均作为 window 对象的属性存在,这意味着开发者既可以通过 window 对象来调用它们,也可以直接使用,为 Web 开发提供了极大的灵活性和便利性。
2. window 对象的常见事件
2.1 onload 窗口加载事件
- 传统注册方式:使用window.onload = function() {},这种方式简单直接,但存在局限性,一个页面中只能定义一次window.onload事件处理函数,如果定义多次,后面的会覆盖前面的,最终只会执行最后一个定义的函数。
- addEventListener 方式:window.addEventListener("load", function() {}),这种方式更加灵活,允许为同一个事件添加多个不同的处理函数,它们会按照添加的顺序依次执行。
当页面的所有内容,包括 HTML 文档、图像、脚本文件、CSS 文件等全部加载完成后,就会触发load事件,并执行相应的处理函数。这通常用于在页面完全准备好后执行一些初始化操作,比如获取页面元素并绑定事件监听器等。
2.2 DOMContentLoaded 窗口加载事件
使用window.addEventListener("DOMContentLoaded", function() {}),当 DOM 树加载完成,即 HTML 文档被解析完毕,无需等待样式表、图片、Flash 等资源加载完成时,就会触发该事件。此事件在 IE9 及以上版本浏览器中得到支持,它为开发者提供了一种在页面 DOM 可用时尽早执行代码的方式,有助于提升页面的交互响应速度。
2.3 调整窗口大小事件
- 方式一:window.onresize = function() {},通过这种方式定义的事件处理函数,当浏览器窗口大小发生改变时,会立即执行该函数。
- 方式二:window.addEventListener("resize", function() {}),同样在窗口大小改变时触发,这种方式相较于前者更加灵活,可添加多个不同的处理函数。
该事件常被用于实现响应式设计,根据窗口大小动态调整页面布局和元素样式,以提供更好的用户体验。例如,当窗口宽度小于某个阈值时,隐藏某些元素或调整元素的排列方式。
3. 定时器
3.1 setInterval () 定时调用
JavaScript 程序执行速度极快,在某些场景下,我们希望一段代码能够每隔一段时间重复执行,这时就可以使用setInterval()函数。setInterval(回调函数, 间隔时间),它会按照指定的时间间隔(单位为毫秒)周期性地调用传入的回调函数。
- 参数说明:
- 第一个参数为回调函数,即每次时间间隔到达时要执行的函数。
- 第二个参数是每次调用之间的时间间隔,以毫秒为单位,例如setInterval(myFunction, 1000)表示每隔 1 秒调用一次myFunction函数。
- 返回值:返回一个唯一的数字标识符,该标识符可用于标识这个定时器。通过clearInterval()函数,并传入这个标识符,就可以停止对应的定时器。例如:
// 设置一个定时器,每2秒调用一次函数 var timerId = setInterval(function() { console.log('定时器执行中...'); }, 2000); // 5秒后停止定时器 setTimeout(function() { clearInterval(timerId); }, 5000); |
3.2 setTimeout () 延时调用
setTimeout()函数用于实现延时调用,即让一个函数在指定的延迟时间(单位为毫秒)后执行,并且只执行一次。使用方式为window.setTimeout(回调函数, 延迟毫秒数)。
- 参数说明:
- 第一个参数为回调函数,可以直接传入函数表达式,也可以传入函数名。
- 第二个参数为延迟执行的时间,若省略该参数,默认延迟时间为 0 毫秒。
- 返回值:同样返回一个数字标识符,用于标识这个延时调用任务,可通过clearTimeout()函数传入该标识符来取消延时任务。
setInterval()和setTimeout()的主要区别在于,setInterval()会周期性地重复执行回调函数,而setTimeout()只执行一次。在实际开发中,可根据具体需求选择合适的定时器函数。例如,实现一个倒计时功能时,通常使用setInterval();而在延迟执行某个一次性任务时,如页面加载后延迟显示提示信息,则适合使用setTimeout()。
4. JS 执行机制
4.1 JS 是单线程
JavaScript 语言的一个重要特性是单线程执行,这意味着在同一时刻,JavaScript 引擎只能执行一个任务。这种设计源于 JavaScript 的最初设计目标 —— 主要用于处理网页中的用户交互和操作 DOM。单线程执行模式使得所有任务必须按照顺序排队执行,前一个任务完成后,下一个任务才能开始执行。
然而,这种机制也带来了一些问题。如果某个 JavaScript 任务执行时间过长,就会阻塞页面的渲染和用户交互,导致页面出现卡顿、无响应的情况。例如,在一个循环中执行大量复杂计算的代码,就可能会使页面在计算过程中无法响应用户的点击、滚动等操作。
4.2 同步和异步
为了解决单线程带来的阻塞问题,HTML5 引入了 Web Worker 标准,允许 JavaScript 创建多个线程来执行一些耗时的任务,从而实现了同步和异步操作。
- 同步任务:指在主线程上按照顺序依次执行的任务,前一个任务执行完毕后,才会执行下一个任务,任务的执行顺序与代码的书写顺序一致。例如,简单的数学计算、变量赋值等操作都是同步任务。
- 异步任务:不会立即进入主线程执行,而是被放入 “任务队列”(也称为消息队列)中。当主线程上的所有同步任务执行完毕后,系统会从任务队列中取出异步任务,将其放入主线程中执行。常见的异步任务包括:
- setTimeout和setInterval:用于实现定时和延时执行的任务。
- DOM 事件:如用户的点击、鼠标移动、窗口大小改变等事件触发的回调函数。
- ES6 中的 Promise:用于处理异步操作的结果,提供了一种更优雅的异步编程方式。
- Ajax 异步请求:用于在不刷新页面的情况下与服务器进行数据交互。
4.3 JS 执行机制
- 同步任务执行:JavaScript 引擎首先会在主线程上顺序执行同步任务,将这些任务依次放入执行栈中执行。
- 异步任务处理:当遇到异步任务时,不会立即执行其回调函数,而是将其放入任务队列中等待。
- 任务队列处理:当执行栈中的所有同步任务执行完毕后,JavaScript 引擎会检查任务队列中是否有等待执行的异步任务。如果有,就会按照任务队列的顺序,将异步任务的回调函数取出并放入执行栈中执行。这个过程会不断重复,直到任务队列中没有待处理的异步任务为止。
4.4 事件循环
事件循环(Event Loop)是 JavaScript 实现异步操作的核心机制。其基本流程如下:
- 执行栈开始顺序执行同步任务。
- 当遇到异步任务时,将其交给对应的异步线程处理(如定时器线程处理setTimeout和setInterval,事件触发线程处理 DOM 事件等)。
- 异步线程在任务完成后,将对应的事件回调放入事件触发线程的任务队列中等待执行。
- 执行栈中的同步任务执行完毕后,询问任务队列中是否有事件回调。
- 如果任务队列中有事件回调,则将其加入执行栈末尾,继续从第一步开始执行;如果任务队列中没有事件回调,则继续不断询问,直到有新的异步任务回调进入任务队列。
通过事件循环机制,JavaScript 能够在单线程环境下高效地处理同步和异步任务,实现复杂的交互功能和非阻塞的 I/O 操作,确保页面的流畅性和响应性。
5. location 对象
5.1 location 对象初识
window 对象提供了一个location属性,通过它可以获取或设置当前浏览器窗口的 URL,并且能够对 URL 进行详细的解析。由于location返回的是一个包含 URL 各个部分信息的对象,因此被称为location对象。在 Web 开发中,location对象是实现页面导航、参数传递和 URL 解析等功能的重要工具。
5.2 URL
统一资源定位符(Uniform Resource Locator,简称 URL)作为互联网标准资源的唯一标识,精准定义了互联网中各类文件与资源的地址。从本质上讲,URL 不仅承载了资源的物理位置信息,还为浏览器处理资源提供了必要的操作指令。
URL 主要由以下几个核心部分构成:
- 协议(protocol):负责指定访问资源所采用的传输协议。常见的协议类型包括 HTTP(超文本传输协议)、HTTPS(安全超文本传输协议)以及 FTP(文件传输协议)等。其中,HTTP 协议在 WWW 应用领域中最为广泛,其标准格式为HTTP://;HTTPS 协议在 HTTP 的基础上引入了加密与认证机制,极大地提升了数据传输的安全性,格式为HTTPS://;FTP 协议则主要用于文件的上传与下载,格式为FTP://。通常情况下,以 HTTPS 开头的 URL 在数据传输过程中采用加密技术,能够有效保障用户数据的安全传输。
- 主机名(hostname):指的是存放资源的服务器在域名系统(DNS)中的主机名或 IP 地址。在特定场景下,主机名前可包含连接服务器所需的用户名与密码,格式表现为username:password@hostname。
- 端口号(port):用于指定服务器监听的端口号。HTTP 协议默认使用 TCP 协议的 80 端口,因此在访问标准 HTTP 服务时,端口号通常可以省略,直接使用http://开头的 URL 即可;而 HTTPS 协议默认使用 TCP 协议的 443 端口。
- 路径(path):由零个或多个 “/” 符号分隔的字符串组成,用于明确主机上的目录或文件地址。例如,/index.html表示网站根目录下的index.html文件。
- 参数(parameters):作为指定特殊参数的可选项,在 HTTP 协议中使用频率相对较低,更多地出现在特定协议场景中。例如,在ftp://user:password@example.com;type=d/file.txt中,;type=d即为参数,用于指定文件类型为目录。
- 查询(query):作为可选部分,主要用于向动态网页传递参数。可以包含多个参数,参数之间以 “&” 符号分隔,每个参数的名称与值之间用 “=” 符号连接。例如,?name=John&age=25表示传递了两个参数name和age,其对应的值分别为John和25。
- 信息片断(fragment):也称作锚点,是一个字符串,主要用于定位网络资源中的特定位置或片段。例如,在包含多个章节的网页中,可使用#chapter1直接定位到第一章的内容。
URL 的一般语法格式为:protocol://hostname[:port]/path/[;parameters][?query]#fragment。
5.3 location 对象的属性与方法
location 对象属性 | 返回值 |
location.href | 返回当前加载页面的完整 URL,与window.location.href等价,通过修改该属性可以实现页面跳转 |
location.hash | 返回 URL 中的 hash 部分(即 #号后的内容),如果 URL 中不包含 hash,则返回空字符串,常用于实现页面内的锚点定位 |
location.host | 返回服务器名称和端口号,如example.com:8080 |
location.hostname | 返回不带端口号的服务器名称,如example.com |
location.pathname | 返回 URL 中的目录和(或)文件名,如/blog/article1.html |
location.port | 返回 URL 中指定的端口号,如果 URL 中未指定端口号,则返回空字符串 |
location.protocol | 返回页面使用的协议,如http:或https: |
location.search | 返回 URL 的查询字符串,以 “?” 开头,如?name=John&age=25,常用于获取和解析 URL 传递的参数 |
location 对象方法 | 功能 |
location.assign() | 用于跳转到其他页面,作用与直接修改location.href相同,会在浏览器历史记录中生成新的记录,用户可以通过浏览器的后退按钮返回上一页 |
location.replace() | 重新定向 URL,不会在历史记录中生成新纪录,用户无法通过后退按钮回到当前页面,常用于需要强制用户访问新页面且不允许返回的场景 |
location.reload() | 重新加载当前显示的页面,如果在方法中传递true作为参数,如location.reload(true),则会强制刷新缓存,从服务器重新获取最新的页面内容 |
6. navigator 对象
navigator 对象代表当前浏览器的相关信息,通过它可以获取关于浏览器的各种特征和属性,从而实现针对不同浏览器的定制化开发。然而,由于历史原因,navigator 对象中的大部分属性在现代浏览器中已不再可靠,无法准确地识别浏览器类型和版本。目前,最常用的是userAgent属性,它是一个包含浏览器详细信息的字符串,不同浏览器的userAgent具有独特的特征和格式。通过分析userAgent字符串,开发者可以大致判断用户使用的浏览器类型(如 Chrome、Firefox、Safari 等)、版本号以及操作系统信息等。例如,一个典型的 Chrome 浏览器的userAgent字符串可能如下:
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 |
通过解析这个字符串,可以提取出浏览器名称(Chrome)、版本号(91.0.4472.124)以及操作系统(Windows NT 10.0)等信息。
7. history 对象
window对象提供的history对象,主要用于与浏览器的历史记录进行交互。该对象包含了用户在当前浏览器窗口中访问过的 URL 信息,通过对其操作,开发者能够实现页面导航控制。
history 对象属性 | 作用 |
length | 返回当前会话中浏览器历史记录的条目数量,即用户访问过的页面链接数量 |
history 对象方法 | 作用 |
back() | 用于返回上一个浏览页面,功能等同于浏览器的后退按钮 |
forward() | 实现跳转到下一个浏览页面,与浏览器的前进按钮功能一致 |
go() | 接受一个整数参数,用于在浏览器历史记录中进行指定页面的跳转。当参数为正数时,向前跳转 n 个页面;参数为负数时,向后跳转 n 个页面 |