当前位置: 首页 > news >正文

精读《JavaScript 高级程序设计 第4版》第12章 BOM

BOM 指的是浏览器对象模型。它不是像DOM那样的官方标准(W3C或WHATWG),但它被所有现代浏览器所实现,提供了一组用于与浏览器窗口本身进行交互的对象。

核心思想:BOM的核心是 window 对象。在浏览器中,window 对象扮演着双重角色:

  1. 它是ECMAScript中的全局对象。所有在全局作用域中声明的变量和函数都会成为 window 对象的属性和方法。
  2. 它是浏览器窗口的JavaScript接口,提供了控制和访问浏览器窗口的能力。

12.1 Window对象

BOM的核心是window对象,表示浏览器的实例。window 对象扮演着双重角色,一个是ECMAScript中的Global对象,另一个就是浏览器窗口的JavaScript接口。这意味着网页中定义的所有对象、变量和函数都以window作为其Global对象,都可以访问其上定义的parseInt()等全局方法。

12.1.1 Global作用域

所有通过var声明的全局变量和函数都会成为window对象的属性:

var greeting = 'Hello World';
console.log(window.greeting); // 'Hello World'

现代注意点:使用 letconst 声明的全局变量不会成为 window 对象的属性。

let greetingLet = 'Hello';
const greetingConst = 'World';
console.log(window.greetingLet); // undefined
console.log(window.greetingConst); // undefined

12.1.2 窗口关系

  • top:始终指向最顶层(最外层)窗口,即浏览器标签页本身。
  • parent:指向当前窗口的父窗口(如果当前窗口是 <iframe>,则 parent 指向包含它的窗口)。
  • self:始终指向当前的 window 对象(与 window 是同义词)。
    现代应用:在单页应用和微前端架构中,处理 iframe 与主应用、或窗口与弹出窗口之间的通信时,这些属性至关重要。

12.1.3 窗口位置与像素比

  • screenLeft / screenTop:窗口相对于屏幕左侧和顶部的位置,返回值单位是CSS像素。
  • screenX / screenY:同上,是标准属性。
  • moveTo()/moveBy():移动窗口。都接收两个参数,moveTo()接收要移动到的新位置的绝对坐标;moveBy()则接收相对当前位置在两个方向上移动的像素数。(依浏览器而定,可能被禁用)
  • devicePixelRatio:物理像素与CSS像素之间的转换比率。值为3时,12像素(CSS)的文字实际上会使用36像素的物理像素来显示。

12.1.4 窗口大小

  • innerWidth / innerHeight视口(viewport) 的尺寸,即页面实际渲染区域的宽高(不包括浏览器UI、滚动条)。
  • outerWidth / outerHeight:整个浏览器窗口的尺寸。
  • resizeTo()/resizeBy():调整窗口大小,接收两个参数,resizeTo()接收新的宽高值,resizeBy()接收宽高各要缩放多少。(可能被部分浏览器禁用)

12.1.5 视口位置

  • pageXoffset/pageYoffset:返回文档相对于视口的滚动距离
  • scrollX/scrollY:同上
  • scroll()/scrollTo()/scrollBy():滚动页面,都接收两个参数表示相对视口距离的x和y坐标,scrollTo()表示要滚动到的位置,scrollBy()表示要滚动的距离。也都接收一个ScrollToOptions字典,通过behavior属性告诉浏览器是否平滑滚动:
window.scrollTo({left: 100,top: 100,behavior: 'smooth'
})

12.1.6 导航与打开新窗口

window.open() 方法用于导航到一个新URL或打开一个新浏览器窗口。

用法window.open(URL, target, features)

    • URL:要加载的地址。
    • target:窗口目标,如 _blank, _self,或一个窗口/框架名。
    • features:一个逗号分隔的设置字符串,用于控制新窗口的UI元素(如工具栏、状态栏、大小等)。
const popup = window.open('https://www.example.com', 'exampleWindow', 'width=400,height=300');

新创建窗口的window对象都有一个属性opener,指向打开它的窗口,可以通过将指定窗口对象的opener属性值置null,实现新窗口的运行在独立进程中。(一旦切断就无法恢复)

  • 现代安全限制与最佳实践
    • 弹出窗口阻止程序:现代浏览器默认会阻止非用户触发的 window.open() 调用(例如在 setTimeout 或异步回调中直接调用)。必须由用户手势(如点击)发起
    • 慎用:由于糟糕的用户体验和潜在的滥用(广告、钓鱼),应尽量避免使用弹出窗口。如果需要打开新标签页,通常使用 target="_blank"<a> 标签是更好的选择。
    • 通信:通过 window.open() 返回的引用,可以实现父子窗口间的有限通信(如 popup.close())。
    • popup.close()只能用于window.open()创建的窗口。

12.1.7 定时器 (setTimeout & setInterval)

这是BOM中最常用、最稳定的API之一。

  • setTimeout(func, delay):在指定的毫秒数 delay 后,将任务 func 推入任务队列执行。返回一个ID,可用于取消。
  • setInterval(func, delay):每隔指定的毫秒数 delay,重复将任务 func 推入任务队列执行。返回一个ID,可用于取消。

现代注意点

    • 最小延迟:在非活动标签页中,现代浏览器会对定时器实施最小延迟(例如1秒)以节省资源和电池。
    • 性能与替代方案:对于高频重复动画,requestAnimationFrame 是比 setInterval 更优的选择,因为它与浏览器的重绘周期同步,能保证动画的流畅性并节省电量。
// 使用 requestAnimationFrame 实现动画
function animate() {// ... 更新动画状态 ...element.style.left = `${newPosition}px`;requestAnimationFrame(animate);
}
animate();
    • 取消定时器:务必使用 clearTimeout(timeoutId)clearInterval(intervalId) 来清理不再需要的定时器,防止内存泄漏。

12.1.8 系统对话框

浏览器调用系统对话框向用户显示消息,这些对话框与网页无关,不包含HTML,外观由操作系统或浏览器决定,无法使用CSS设置。且这些对话框都是同步的静态对话框,显示时代码会停止执行,消失后代码才恢复执行。

  • alert():警告框,接收一个要显示给用户的字符串,该字符串会显示在对话框中,对话框只有一个"OK"(确定)按钮。
  • confirm():确认框,与alert()不同的点在于有两个按钮:"Cancel"(取消)和"OK"(确定)。该方法返回Boolean值表示用户点击ok还是Cancel。
  • prompt():提示框,提示用户输入消息,除了ok和Cancel按钮,还会显示一个文本框,让用户输入内容。该方法接收两个参数,要显示给用户的文本和文本框的默认值(可空串),返回文本中的值或者取消时返回null。

12.2 location对象

它提供了当前窗口加载文档的信息和导航功能。它既是 window 的属性,也是 document 的属性 (window.location === document.location)。

  • 属性:包含了URL的各个部分。
    • location.href:完整的URL。(如"http://www.wrox.com:80/WileyCDA/?q=javascript#contents")
    • location.protocol:协议(如 "http:")。
    • location.host:服务器名和端口号,(如"http://www.wrox.com:80" )。
    • location.hostname:服务器名,(如"www.wrox.com" )。
    • location.port:端口号,(如"80" )。
    • location.pathname:URL中的路径,(如"/WileyCDA/" )。
    • location.search? 之后的查询字符串,(如 "?q=javascript")。
    • location.hash# 之后的片段标识符,(如 "#contents")。

12.2.1 查询字符串

  • location.search():返回从问号开始直到URL末尾的所有内容,需要自己编写函数进行二次处理。
  • URLSearchParams():URLSearchParams提供了一组标准API方法,给该构造函数传入一个查询字符串,就可以创建一个实例。这个实例暴露了get()、set()和delete()等方法,可以对查询字符串执行相应操作。
let qs = "?q=javascript&num=10";
let searchParams = new URLSearchParams(qs);
alert(searchParams.toString());	//" q=javascript&num=10"
searchParams.has("num");	//true
searchParams.get("num");	//10
searchParams.set("page", "3");
alert(searchParams.toString());		//" q=javascript&num=10&page=3"
searchParams.delete("num");
alert(searchParams.toString());	//" q=javascrip&page=3"

12.2.2 操作地址

  • location.assign("https://..."):导航到新URL,在历史记录中生成一条记录。
  • location.replace("https://..."):导航到新URL,替换当前历史记录,用户不能点击“返回”按钮回到前一个页面。
  • location.reload():重新加载当前页面。传 true 会强制从服务器重新加载(绕过缓存)。
  • 修改location对象属性也会修改当前加载的页面,使得页面重新加载新URL(例如:location.hostname="www.baidu.com";
现代应用
  • 单页应用:在React, Vue等SPA框架中,我们通常使用客户端路由库(如React Router, Vue Router)。这些库的核心就是通过监听 location.hash(Hash模式)或使用History API(History模式)来改变URL,而不触发完整的页面刷新。
  • URLSearchParams:现代浏览器提供了 URLSearchParams API,用于方便地解析和操作查询字符串。
const params = new URLSearchParams(location.search);
const id = params.get('id'); // 获取查询参数 'id' 的值
params.set('page', '2'); // 设置参数
console.log(params.toString()); // 输出序列化后的字符串

12.3 navigator对象

它提供了关于浏览器和操作系统的大量信息。其对象属性通常用来确定浏览器的类型。

经典属性

    • navigator.userAgent:浏览器的用户代理字符串。注意:由于历史原因,这个字符串非常混乱且容易被篡改,不推荐用于精确的浏览器检测。
    • navigator.platform:操作系统平台。
    • navigator.languages:返回浏览器的主语言

现代属性与方法(越来越重要)

    • navigator.onLine:返回布尔值,表示浏览器是否联网。可以监听 onlineoffline 事件。
    • navigator.clipboard剪贴板API。提供了安全、异步的读写剪贴板内容的能力。
// 写入文本到剪贴板
navigator.clipboard.writeText('Hello, Clipboard!').then(() => {console.log('Text copied to clipboard');
});
    • navigator.mediaDevices媒体设备API。用于访问摄像头和麦克风。
// 获取用户媒体(摄像头)
navigator.mediaDevices.getUserMedia({ video: true }).then(stream => {videoElement.srcObject = stream;});
    • navigator.serviceWorkerService Worker API。用于创建可编程的网络代理,是实现PWA(渐进式Web应用)、离线体验和后台同步的核心。
    • navigator.geolocation地理定位API。用于获取用户设备的地理位置。

12.4 history 对象

它代表了用户的导航历史记录。出于安全考虑,不允许脚本直接访问具体的URL,但可以对其进行操作。

  • 传统方法
    • history.go(n):在历史记录中导航n步(正数前进,负数后退)。
    • history.back():后退一页。
    • history.forward():前进一页。
    • history.length:历史记录栈中的条目数。

现代核心:History API
这是现代单页应用的基石。它允许我们更新URL而不触发页面刷新,并管理应用状态。

    • history.pushState(state, title, url):向历史记录栈添加一条记录。URL改变,但页面不刷新。state 是一个与新历史记录条目关联的状态对象。
    • history.replaceState(state, title, url)替换当前历史记录条目。URL改变,但页面不刷新。

示例(SPA路由):

// 当用户点击一个“关于我们”的链接时
function navigateToAbout() {// 1. 使用 pushState 改变URLhistory.pushState({ page: 'about' }, 'About Us', '/about');// 2. 然后,通过你自己的路由逻辑,动态地更新页面内容(例如,渲染About组件)renderAboutPage();
}// 监听 popstate 事件,当用户点击前进/后退按钮时触发
window.addEventListener('popstate', (event) => {// 根据 event.state 中的信息,渲染对应的页面if (event.state && event.state.page === 'about') {renderAboutPage();} else {renderHomePage();}
});
http://www.dtcms.com/a/487785.html

相关文章:

  • 临桂城乡建设局网站开源wordpress
  • BRPC基础使用
  • 如何用网站模板建设网站南京模板建网站哪家好
  • 称多县公司网站建设网上做家教那个网站好
  • 做家装模型的效果图网站宁德市住房和城乡建设局网站
  • Burp Suite抓包软件使用说明1-Http history
  • 买了两台服务器可以做网站吗不起眼的暴利小生意
  • glibc升级到指定版本
  • 做一个智能体搭建复盘吧
  • 销售网站建设的意义企业网站建设策划书 前言
  • 做房产网站在百度推广推广费前端素材网
  • 家政服务网站建设方案建筑建设网站
  • DirectShow帮助文档
  • No032:休眠的智慧——当DeepSeek学会在静默中更新
  • 注册什么公司给别人做网站成都市房产透明网官网
  • 租车网站 模板提供中山精品网站建设
  • 用于设计和验证自动驾驶系统的场景库
  • 做网站的抬头怎么做wordpress开发ide
  • 数字图像处理绪论
  • UVa 12494 Distinct Substring
  • 【Linux】Linux进程间通信:命名管道(FIFO)的模拟实现重要知识点梳理
  • 做网站时怎么裁切存图最佳建站模板
  • 020网站建设如何保护我做的网站模板
  • Escrcpy 安卓手机投屏软件中文绿色版
  • 大模型实习
  • 如何做网站旅游产品分析网站建设与数据库管理
  • dw不用代码做网站w3school网页制作
  • 网站备案号如何查询密码室内设计需要什么学历
  • Git 用户名与邮箱配置指南
  • Spring 中使用的设计模式