首页 阅读DAY18 JavaScript高级程序设计 12章下 BOM
文章
取消

阅读DAY18 JavaScript高级程序设计 12章下 BOM

开始阅读JavaScript高级程序设计(第5版)学习JS,总共有1000+页,非常全面,短期看完不太现实,找到了一篇博客,花些时间跟着这篇博客过一下红宝书。

JavaScript高级程序设计(第5版)微信读书

红宝书《JavaScript高级程序设计(第5版)》学习大纲 - 大前端全栈开发 - SegmentFault 思否

全文概览:

重要度知识点理由
⭐⭐⭐location 既是 window 也是 document 的属性(window.location === document.location基础概念,面试可能追问”两个location有什么区别”
⭐⭐⭐location URL 解析属性(hash/search/hostname/pathname/port/href 等)开发高频使用,解析/拼接 URL 必备,面试可能问”如何获取 URL 参数”
⭐⭐⭐location.assign() vs location.replace()(是否增加历史记录)路由跳转核心区别,面试常问”assign和replace区别”
⭐⭐⭐location.hash 修改不重载页面,其他属性修改会重载SPA 路由基础,面试可能问”改变hash会刷新页面吗”
⭐⭐⭐history.pushState() / replaceState() / popstate 事件SPA 路由核心原理,Vue Router / React Router 底层依赖,面试必问
⭐⭐⭐pushState() 假 URL 需真实后端对应(否则刷新 404)SPA 部署经典坑,面试可能问”history模式刷新404怎么解决”
⭐⭐⭐location.reload() vs location.reload(true)(缓存 vs 强制服务器)实际开发常用,面试可能问”如何强制刷新页面”
⭐⭐location.href = url 等价 assign(),是最常见的跳转写法开发中最常用的导航方式,知道三种写法等价即可
⭐⭐history.go() / back() / forward() / length基础导航 API,知道有这些方法即可
⭐⭐location.searchURLSearchParams API 配合使用实际开发中解析查询参数常用,面试可能追问 URLSearchParams
⭐⭐history.state 读取当前状态配合 pushState/replaceState 使用,知道可以读取即可
⭐⭐navigator.userAgent 浏览器检测实际开发中偶尔用于兼容性判断,但现代推荐特性检测而非 UA 检测
⭐⭐navigator.registerProtocolHandler()知道有这个 API 即可,PWA 相关,低频但面试可能作为扩展知识问
location 完整 URL 结构(含 userinfo 如 foouser:barpassword@了解即可,实际开发中几乎遇不到带凭据的 URL
screen 对象(客户端显示器信息)实际开发几乎不用,知道有这么个对象即可
screen.width / screen.height / screen.availWidth极少使用,响应式开发用 window.innerWidth 而非 screen
navigator 其他属性(language/cookieEnabled/onLine 等)个别属性偶尔用到(如 onLine 检测网络),但整体不考
history.go() 传入字符串导航旧特性,现代浏览器不支持,不考
pushState() state 对象大小限制(500KB~1MB)了解即可,实际不会存这么大的状态
pushState() 第二个参数(标题)未被实现知识细节,不影响开发

location对象:

location是最有用的BOM对象之一,提供了当前窗口中加载的文档的信息,以及通常的导航功能。

这个对象独特的地方在于,它既是window的属性,也是document的属性。也就是说,window.location和document.location指向同一个对象。

location对象不仅保存着当前加载文档的信息,也保存着把URL解析为离散片段后能够通过属性访问的信息。这些解析后的属性在下表中有详细说明(location前缀是必需的)。

假设浏览器当前加载的URL是http://foouser:barpassword@www.wiley.com:80/WileyCDA/?q=javascript#contents,location对象的内容如下表所示。

image-20260519002158955

在处理location对象时,URL API和URLSearchParams API非常有用。详情请参阅第18章。

location操作地址:

导航到新 URL:

window.open 也可以实现类似功能,但 window.open 可以打开新窗口,也可以不打开,而 assign() 无法打开新窗口。当window.open 的第二个参数 target_self 时就等同于 location.assign()

它们是同一件事的不同入口。window.open() 更通用,既能新开也能当前窗口跳转;location.assign() 只做当前窗口跳转,但语义更明确。

最常见的是 assign() 方法:

1
location.assign("http://www.wiley.com");

这会立即导航到新 URL,并在浏览器历史记录中增加一条记录。以下两种写法效果和 assign() 完全相同:

1
2
window.location = "http://www.wiley.com";
location.href = "http://www.wiley.com";

三种方式中,设置 location.href 是最常见的。


修改 URL 的各个部分:

修改 location 对象的属性也会修改当前 URL 并触发页面重新加载:

1
2
3
4
5
6
7
// 假设当前 URL 为 http://www.wiley.com/WileyCDA/

location.hash = "#section1"; // → …/WileyCDA/#section1
location.search = "?q=javascript"; // → …/WileyCDA/?q=javascript
location.hostname = "www.example.com"; // → http://www.example.com/WileyCDA/
location.pathname = "mydir"; // → …/mydir/
location.port = 8080; // → …:8080/WileyCDA/

关键区别:

  • hash:修改后不会重新加载页面,但会在浏览器历史中增加一条记录
  • 其他属性:修改后都会重新加载页面

所有这些修改都会在历史记录中增加一条记录,用户可以点”后退”回到前一页。


replace() :不留历史记录的跳转

如果不希望增加历史记录(用户无法后退),使用 replace()

1
2
3
4
5
location.replace("http://www.wiley.com/");

// 和assign的对比
location.assign("http://...") // 新增记录 → 能后退
location.replace("http://...") // 替换当前记录 → 不能后退

调用后用户不能通过”后退”按钮返回前一页,除非手动输入完整 URL。


reload() :重新加载当前页面

1
2
location.reload(); // 可能从缓存加载
location.reload(true); // 强制从服务器加载
  • 不传参数:以最有效的方式重新加载,如果页面未修改过,可能从缓存加载
  • true:强制从服务器重新加载

reload() 之后的代码可能执行也可能不执行,取决于网络延迟和系统资源。最好把 reload() 作为最后一行代码。


地址操作方法对比:

方法/属性是否加载新页面是否增加历史记录
assign(url)
location.href = url
location.hash = val
其他属性(search/port 等)
replace(url)
reload()

navigator是由Netscape Navigator 2最早引入浏览器的,现在已经成为客户端标识浏览器的标准。只要浏览器启用JavaScript,navigator对象就一定存在。但是与其他BOM对象一样,每个浏览器都支持自己的一组属性。

下表列出了这些接口定义的属性和方法。 image-20260519005208944

navigator对象的属性通常用于确定浏览器的类型。

注册处理程序:

navigator上的registerProtocolHandler()方法可以把一个网站注册为处理某种特定类型信息。在线RSS阅读器和电子邮件客户端可以借助这个方法将Web应用程序注册为像桌面软件一样的默认应用程序。 要使用registerProtocolHandler()方法,必须传入3个参数:要处理的协议(如”mailto” 或 “ftp”)、处理该协议的URL,以及应用名称。比如,要把一个Web应用程序注册为默认邮件客户端,可以这样做:

1
2
3
navigator.registerProtocolHandler("mailto",
  "http://www.example.com?cmd=%s",
  "Some Mail Client");

这个例子为 “mailto” 协议注册了一个处理程序,这样邮件地址就可以通过指定的Web应用程序打开。注意,第二个参数是负责处理请求的URL,%s表示原始的请求。

screen对象:

window的另一个属性screen对象是为数不多的几个在编程中很少用到的JavaScript对象之一。这个对象中保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度。每个浏览器都会在screen对象上暴露不同的属性。下表总结了这些属性。

image-20260519005539627

history对象:

history对象表示自当前窗口首次使用以来用户的导航历史记录。因为history是window的属性,所以每个window都有自己的history对象。

出于安全考虑,这个对象不会暴露用户访问过的URL,但可以通过它在不知道实际URL的情况下前进和后退。

导航:

go() 任意方向导航:

接收一个整数参数,表示前进或后退多少步:

1
2
3
history.go(-1); // 后退一页(等同点击"后退"按钮)
history.go(1); // 前进一页(等同点击"前进"按钮)
history.go(2); // 前进两页

旧版浏览器中参数也可以是字符串,浏览器会导航到历史记录中包含该字符串的最近位置(可能前进也可能后退),没有匹配则什么也不做:

1
history.go("wiley.com"); // 导航到最近的 wiley.com 页面

简写方法:

1
2
history.back(); // 后退一页,等同 go(-1)
history.forward(); // 前进一页,等同 go(1)

length 属性:

history.length 表示历史记录中的条目数量(包括可以前进和后退的页面)。对于标签页中加载的第一个页面,history.length === 1

1
2
3
if (history.length == 1) {
  // 这是用户窗口中的第一个页面
}

hash 与历史记录:

页面 URL 变化(包括 location.hash 的改变)会在历史记录中生成新条目。这个行为常被单页应用程序(SPA)框架用来模拟前进和后退,修改 hash 不会触发页面刷新,但能产生历史记录,从而让浏览器的前进/后退按钮正常工作。

历史状态管理:

现代 Web 应用中,“后退”/“前进”按钮对用户来说意味着”切换状态”,而不是刷新页面。HTML5 为 history 对象增加了状态管理 API,可以让开发者改变浏览器 URL 而不加载新页面。

pushState() 推入历史记录:

接收 3 个参数:state 对象、新状态标题、(可选的)相对 URL。

1
2
let stateObject = { foo: "bar" };
history.pushState(stateObject, "My title", "baz.html");

执行后:

  • 状态信息被推入历史记录
  • 浏览器地址栏变为新 URL
  • 浏览器不会向服务器发送请求(即使 location.href 返回新地址)

参数注意:

  • 第一个参数应包含正确初始化页面状态所需的信息,大小限制通常 500KB~1MB
  • 第二个参数当前未被实现,传空字符串或短标题即可
  • state 对象只应包含可序列化的信息,DOM 元素等不适合放入

popstate 事件:后退/前进时触发

pushState() 创建了新的历史记录,用户点击”后退”按钮时会触发 window 上的 popstate 事件。事件对象的 state 属性包含通过 pushState() 传入的 state 对象:

1
2
3
4
5
6
7
window.addEventListener("popstate", (event) => {
 let state = event.state;
 if (state) {
 processState(state); // 根据状态重置页面
 }
 // 页面初次加载时 state 为 null
});

浏览器不会自动帮你恢复页面状态,需要根据 state 对象手动重置。页面初次加载时 event.statenull

replaceState():替换当前状态

pushState() 参数相同,但不会创建新历史记录,只覆盖当前状态:

1
history.replaceState({ newFoo: "newBar" }, "New title");

读取当前状态:

1
history.state; // 获取当前状态对象

注意:假 URL 需要真实后端

通过 pushState() 创建的每个”假”URL 背后都应对应服务器上一个真实的物理 URL,否则用户点击刷新会导致 404。所有单页应用(SPA)框架都必须通过服务器或客户端配置解决这个问题。

方法总结:

方法历史记录用途
pushState(state, title, url)新增一条导航到新状态
replaceState(state, title)不增加更新当前状态
popstate 事件后退/前进时恢复页面
本文由作者按照 CC BY 4.0 进行授权

CSSDAY1 Selectors And Cascade: Selectors

CSSDAY2 Selectors And Cascade: Cascade