持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
每个 JavaScript 环境都有一个 全局对象。在全局范围内创建的任何变量实际上都是这个对象的属性,任何函数都是它的方法。在浏览器环境中,全局对象是 window对象,它表示包含网页的浏览器窗口。
在本文中,我们将介绍 Window 对象的一些重要用途:
-浏览器对象模型
- 在 JavaScript 中获取浏览器信息
- 获取和使用浏览器历史记录
- 创建和控制窗口
- 获取屏幕尺寸和显示细节
浏览器对象模型
浏览器对象模型(或简称 BOM)是包含有关浏览器和计算机屏幕信息的属性和方法的集合。例如,我们可以找出正在使用哪个浏览器查看页面(尽管这种方法不可靠)。我们还可以找出查看它的屏幕尺寸,以及在当前页面之前访问过哪些页面。如果您讨厌用户,它也可以用于创建弹出窗口的相当可疑的做法。
BOM 没有官方标准,尽管所有主要浏览器都支持许多属性和方法,从而形成了一种事实上的标准。这些属性和方法可通过 window 对象获得。每个浏览器窗口、选项卡、弹出窗口、框架和 iframe 都有一个 window 对象。
BOM 仅在浏览器环境中才有意义
请记住,JavaScript 可以在不同的环境中运行。BOM 仅在浏览器环境中才有意义。这意味着其他环境(例如 Node.js)可能没有 window 对象,尽管它们仍然有一个全局对象;例如,Node.js 有一个名为 global.
如果不知道全局对象的名称,也可以 this 在全局范围内使用关键字来引用。以下代码提供了一种将变量分配给 global 全局对象的快速方法:
const global = this;
全局变量
全局变量是不使用const, let 或 var关键字创建的变量。可以在程序的所有部分访问全局变量。
全局变量是全局对象的实际属性。在浏览器环境中,全局对象就是 window 对象。这意味着创建的任何全局变量实际上都是 window 对象的属性,如下例所示:
x = 6;
window.x
// 6
一般来说,你应该在不使用 window 对象的情况下引用全局变量;它的输入更少,您的代码将在环境之间更具可移植性。一个例外是如果您需要检查是否已定义全局变量。例如,如果 x 尚未定义,以下代码将抛出 ReferenceError:
if (x) {
}
但是,如果变量作为window 对象的属性被访问,那么代码仍然可以工作,就像 window.x 简单地 return 一样false,这意味着代码块不会被评估:
if (window.x) {
}
我们已经遇到的一些函数,例如 parseInt() and isNaN(),实际上是全局对象的方法,在浏览器环境中,它们使它们成为 window对象的方法:
像变量一样,习惯上省略通过 window对象访问它们。
对话框
在浏览器中生成对话框的函数有 3 个alert(): confirm() 和 prompt()。这些不是 ECMAScript 标准的一部分,尽管所有主流浏览器都支持它们作为 window对象的方法。
该 window.alert() 方法将暂停程序的执行并在对话框中显示一条消息。消息作为方法的参数提供,并 undefined始终返回:
警报对话框
window.alert('Hello');
确认对话框
该 window.confirm() 方法将停止程序的执行并显示一个确认对话框,该对话框显示作为参数提供的消息,并提供 OK 或 Cancel 选项。true 如果用户单击确定, 它返回布尔值, 如果false 用户单击取消:
window.confirm('点击确认');
提示对话框
该 window.prompt() 方法将停止程序的执行。它显示一个对话框,显示作为参数提供的消息,以及一个允许用户输入文本的输入字段。然后,当用户单击“确定”时,此文本将作为字符串返回。如果用户单击取消, null 则返回:
window.prompt('请输入你的名字:');
小心使用窗口对话框
值得再次重申的是,这些方法将停止程序在其轨道上的执行。这意味着一切都将在调用方法时停止处理,直到用户单击 OK 或 Cancel。如果程序需要同时处理其他事情或程序正在等待回调函数,这可能会导致问题。
在某些情况下可以将此功能用作优势,例如, window.confirm() 可以使用对话框作为最终检查以查看用户是否要删除资源。这将阻止程序继续执行并在用户决定要做什么时删除资源。
还值得记住的是,大多数浏览器允许用户禁用任何重复出现的对话框,这意味着它们不是一个值得依赖的功能。
浏览器信息
该 window对象具有许多属性和方法,可提供有关用户浏览器的信息。
使用 Navigator 对象获取浏览器信息
该 window 对象有一个 navigator 属性,该属性返回对该 Navigator 对象的引用。该 Navigator 对象包含有关正在使用的浏览器的信息。它的 userAgent 属性将返回有关正在使用的浏览器和操作系统的信息。例如,如果我运行以下代码行,则表明我在 Mac OS 上使用的是 Safari 版本 10:
window.navigator.userAgent
//Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
但是不要依赖这些信息,因为它可以被用户修改以伪装成不同的浏览器。也很难理解返回的字符串,因为所有浏览器都在某种程度上伪装成其他浏览器。例如, userAgent 出于遗留 Netscape 兼容性的原因,每个浏览器都会在其属性中包含字符串“Mozilla”。该 userAgent 属性已从官方规范中弃用,但在所有主要浏览器中仍然得到很好的支持。
获取 URL 详细信息:路径、协议、端口等。
该 window.location属性是一个对象,其中包含有关当前页面 URL 的信息。它包含许多提供有关 URL 不同片段的信息的属性。
该 href属性以字符串形式返回完整的 URL:
window.location.href
// "http://127.0.0.1:5500/dome.html"
此属性(以及本节中的大多数其他属性)是一个读/写属性,这意味着它也可以通过赋值来更改。如果这样做了,页面将使用新属性重新加载。例如,在浏览器控制台中输入以下行会将页面重定向到 SitePoint 主页:
window.location.href = 'https://juejin.cn/user/984800147801687'
// "https://juejin.cn/user/984800147801687"
该 protocol 属性返回一个描述所使用协议的字符串(例如 http、 https、 pop2等 ftp )。请注意,末尾有一个冒号 ( :):
window.location.protocol
// "http:"
该 host 属性返回一个描述当前 URL 的域 和 端口号的字符串(如果使用默认端口 80,则通常会省略该字符串):
window.location.host
// "127.0.0.1:5500"
该 hostname属性返回一个描述当前 URL 域的字符串:
window.location.hostname
// "127.0.0.1"
该 port属性返回一个描述端口号的字符串,但如果端口未在 URL 中明确说明,它将返回一个空字符串:
window.location.port
// "5500"
该 pathname属性返回域之后的路径字符串:
window.location.pathname
// "/dom.html"
该 search属性返回一个以“?”开头的字符串 后跟查询字符串参数。如果没有查询字符串参数,则返回一个空字符串。这是我在 SitePoint 上搜索“Darren Jones”时得到的结果:
window.location.search
// " "
该 hash 属性返回一个以“#”开头的字符串,后跟片段标识符。如果没有片段标识符,则返回一个空字符串:
window.location.hash
// ""
该origin属性返回一个字符串,该字符串显示当前页面源自的协议和域。此属性是只读的,因此无法更改:
window.location.origin
// "http://127.0.0.1:5500"
- 该
window.location对象还具有以下方法: - 该
reload()方法可用于强制重新加载当前页面。如果给它一个参数true,它将强制浏览器从服务器重新加载页面,而不是使用缓存页面。 - 该
assign()方法可用于从作为参数提供的 URL 加载另一个资源,例如:
window.location.assign('https://juejin.cn/user/984800147801687')
- 该
replace()方法与该方法几乎相同assign(),只是当前页面不会存储在会话历史中,因此用户将无法使用后退按钮导航回该页面。 - 该
toString()方法返回一个包含整个 URL 的字符串:
window.location.toString();
// "https://juejin.cn/user/984800147801687"
浏览器历史
该 window.history 属性可用于访问有关当前浏览器会话中任何先前访问的页面的信息。
该 window.history.length 属性显示在到达当前页面之前已经访问了多少页面。
该 window.history.go() 方法可用于转到特定页面,其中 0 是当前页面:
window.history.go(1); // 前进
window.history.go(0); // 重新加载当前页面
window.history.go(-1); //返回+刷新
还有 window.history.forward() 和 window.history.back() 方法可用于分别向前和向后导航一页,就像使用浏览器的前进和后退按钮一样。
控制窗口
一个弹出窗口
可以使用该 window.open() 方法打开一个新窗口。这将要打开的页面的 URL 作为其第一个参数,将窗口标题作为其第二个参数,并将属性列表作为第三个参数。这也可以分配给一个变量,因此稍后可以在代码中引用该窗口:
const popup = window.open('https://juejin.cn/user/984800147801687/posts', '掘金', 'width=700,height=700);
该 close() 方法可用于关闭窗口,假设您有一个对它的引用:
popup.close();
也可以使用该 window.moveTo() 方法移动窗口。这需要两个参数,即窗口要移动到的屏幕的 X 和 Y 坐标:
window.moveTo(0,0);
window.resizeTo()您可以使用该方法调整窗口大小 。这需要两个参数来指定调整后窗口尺寸的宽度和高度:
window.resizeTo(600,400);
烦人的弹出窗口
这些方法主要负责给 JavaScript 一个坏名声,因为它们被用于创建通常包含侵入性广告的烦人的弹出窗口。从可用性的角度来看,调整或移动用户窗口的大小也是一个坏主意。
许多浏览器会阻止弹出窗口,并且在某些情况下不允许调用其中一些方法。例如,如果打开了多个选项卡,则无法调整窗口大小。您也不能移动或调整不是使用 window.open().
使用这些方法中的任何一种都是不明智的,因此在使用它们之前要仔细考虑。几乎总会有更好的选择,忍者程序员会努力找到它。
屏幕信息
该 window.screen 对象包含有关显示浏览器的屏幕的信息。height 您可以分别使用和 width 属性找出屏幕的高度和宽度(以像素 为单位):
window.screen.height
// 1024
window.screen.width
// 1280
和 可用于查找屏幕的高度availHeight 和 availWidth 宽度,不包括任何操作系统菜单:
window.screen.availWidth
// 1280
window.screen.availHeight
// 995
该 colorDepth 属性可用于查找用户显示器的颜色位深度,尽管除了收集用户统计信息之外,很少有这样做的用例:
window.screen.colorDepth;
// 24
在移动设备上更有用
Screen 对象对移动设备有更多用途。它还允许您执行诸如关闭设备屏幕、检测其方向变化或将其锁定在特定方向等操作。
文档对象
每个 window 对象都包含一个 document 对象。该对象具有处理已加载到窗口中的页面的属性和方法。在第 6 章中,我们介绍了文档对象模型以及用于操作页面上的项目的属性和方法。该 document 对象包含一些其他值得关注的方法。
document.write()
该 write() 方法只是将一串文本写入页面。如果页面已经加载,它将完全替换当前文档:
document.write('Hello, world!');
这将用字符串替换整个文档 Hello, world!。可以在字符串中包含 HTML,这将成为 DOM 树的一部分。例如,以下代码将创建一个 <h1> 标记节点和一个子文本节点:
document.write('<h1>Hello, world!</h1>');
该 document.write() 方法还可以在 <script> 标签内的文档中使用,以将字符串注入标记。这不会覆盖页面上的其余 HTML。以下示例将文本 "Hello, world!" 放置在 <h1> 标签内,页面的其余部分将正常显示:
<h1>
<script>document.write("你好,世界!")</script>
</h1>
document.write() 由于只能通过在 HTML 文档中混合 JavaScript 来实际使用它,因此基本上都不使用它。
总结
通过上面的案例,我们对window对象的重要性及用法已经有了一定的了解,然而上述只是对表格中window对象的属性和方法做了简单的介绍。关于窗口的操作还有很多需要更进一步的学习和提升。如果对此感兴趣,欢迎持续关注。