JavaScript高级程序设计第四版学习--第十二章


title: JavaScript高级程序设计第四版学习–第十二章
date: 2021-5-24 22:47:30
author: Xilong88
tags: JavaScript

本章内容:
理解BOM的核心——window 对象
控制窗口及弹窗
通过location 对象获取页面信息
使用navigator 对象了解浏览器
通过history 对象操作浏览器历史
可能出现的面试题:
1.什么是BOM?
2.CSS像素?
3.如何获取窗口或者屏幕大小,几种属性的区别?
4.如何打开新窗口?有哪些常见参数?
5.了解过定时器吗?
6.弹窗有哪几种?
7.怎么把URL里的参数获取出来?
8.怎么查看浏览器信息?
9.了解过H5的历史管理吗?(怎么改变URL而不刷新页面)

总结:
这一章的开始象征着之前的ECMAscript的部分基本完成了,开始BOM和DOM的内容。
这章主要是讲了BOM中的一些对象,还有这些对象的属性方法。
常用的location还是history的常见属性方法应该要掌握。

知识点:

1.浏览器对象模型BOM,BOM的核心是window 对象,表示浏览器的实例。网页中定义的所有对象、变量和函数都以window 作为其Global 对象,都可以访其上定义的全局方法。

2.Global 作用域

因为window 对象被复用为ECMAScript的Global 对象,所以通过var声明的所有全局变量和函数都会变成window 对象的属性和方法。

var age = 29;
var sayAge = () => alert(this.age);
alert(window.age); // 29
sayAge();          // 29
window.sayAge();   // 29

如果在这里使用let 或const 替代var ,则不会把变量添加给全局对象:

let age = 29;
const sayAge = () => alert(this.age);
alert(window.age);  // undefined
sayAge();           // undefined
window.sayAge();    // TypeError: window.sayAge is not a function

访问未声明的变量会抛出错误,但是可以在window 对象上查询是否存在可能未声明的变量。比如:

// 这会导致抛出错误,因为oldValue没有声明
var newValue = oldValue;
// 这不会抛出错误,因为这里是属性查询
// newValue会被设置为undefined
var newValue = window.oldValue;

3.窗口关系
window.top
window.self
window.parent
top表示最上层的窗口对象,也就是浏览器本身,parent指向当前窗口的父窗口,也就是谁用window.open打开了它。self就是窗口自己,指向window本身。

4.screenLeft,screenTop,表示窗口对于屏幕左侧和顶部的位置,返回CSS像素

moveTo()和moveBy()移动窗口,传入x,y
(有些浏览器禁用了,比如Chorme)

// 把窗口移动到左上角
window.moveTo(0,0);
// 把窗口向下移动100像素
window.moveBy(0, 100);
// 把窗口移动到坐标位置(200, 300)
window.moveTo(200, 300);

// 把窗口向左移动50像素
window.moveBy(-50, 0);

CSS像素不是物理的屏幕像素,它大概是一个固定的物理大小,大约1/96英寸,这样是为了在不同分辨率屏幕上显示字体大小差不多。

window.devicePixelRatio:物理像素与CSS像素之间的转换比率

对于分辨率从1920×1080转换为640×320的设备,window.devicePixelRatio 的值就是3

5.innerWidth 、innerHeight 、outerWidth 和
outerHeight、(clientWidth、clientHeight这两个是DOM的属性)

outerWidth 和outerHeight 返回浏览器窗口自身的
大小

innerWidth 和innerHeight 返回浏览器窗口中页面视口的大小,不包含浏览器边框和工具栏。

document.documentElement.clientWidth 和document.documentElement.clientHeight 返回页面视口的宽度和高度(因为是DOM的属性,所以不包含滑动条)。

也就是说,inner是包含窗口的边框工具栏的,outer只包含窗口里面的东西,也就是不包含边框工具栏,而client是DOM的属性,滑动条是BOM提供的。

resizeTo() 和resizeBy() 方法调整窗口大小

// 缩放到100×100
window.resizeTo(100, 100);
// 缩放到200×150
window.resizeBy(100, 50);
// 缩放到300×300
window.resizeTo(300, 300);

有的浏览器不能用,比如Chrome。

5.视口位置

度量文档相对于视口滚动距离的属性有两
对,返回相等的值:
window.pageXoffset /window.scrollX 和
window.pageYoffset /window.scrollY

scroll() 、scrollTo() 和scrollBy() 滚动页面
前两个方法一样

// 相对于当前视口向下滚动100像素
window.scrollBy(0, 100);
// 相对于当前视口向右滚动40像素
window.scrollBy(40, 0);
// 滚动到页面左上角
window.scrollTo(0, 0);
// 滚动到距离屏幕左边及顶边各100像素的位置
window.scrollTo(100, 100);

这几个方法也都接收一个ScrollToOptions 字典,除了提供偏移值,还可以通过behavior 属性告诉浏览器是否平滑滚动。

// 正常滚动
window.scrollTo({
  left: 100,
  top: 100,
  behavior: 'auto'
});
// 平滑滚动
window.scrollTo({
  left: 100,
  top: 100,
  behavior: 'smooth'
});

6.导航与打开新窗口

window.open()

4个参数:要加载的URL、目标窗口、特性字符串和表示新窗口在浏览器历史记录中是否替代当前加载页面的布尔值。

第二个参数是一个已经存在的窗口或窗格
(frame)的名字,则会在对应的窗口或窗格中打开URL。下面是一个例子:

// 与<a href="http://www.wrox.com" target="topFrame"/>相同
window.open("http://www.wrox.com/", "topFrame");

如果有一个窗口名叫"topFrame" ,则这个窗口就会打开这个URL;否则
就会打开一个新窗口并将其命名为"topFrame" 。第二个参数也可以是
一个特殊的窗口名,比如_self 、_parent 、_top 或_blank 。

第三个参数,即特性字符串,特性字符串是一个逗号分隔的设置字符串,用于指定新窗口包含的
特性。
选项表

window.open("http://www.wrox.com/",
            "wroxWindow",
            "height=400,width=400,top=10,left=10,resizable=yes");

这行代码会打开一个可缩放的新窗口,大小为400像素×400像素,位于离屏幕左边及顶边各10像素的位置。

跟使用任何window 对象一样,
可以使用这个对象操纵新打开的窗口。

let wroxWin = window.open("http://www.wrox.com/",
              "wroxWindow",
              "height=400,width=400,top=10,left=10,resizable=yes");
// 缩放
wroxWin.resizeTo(500, 500);
// 移动
wroxWin.moveTo(100, 100);

还可以使用close() 方法像这样关闭新打开的窗口:

wroxWin.close();
wroxWin.close();
alert(wroxWin.closed); // true

可以看窗口是不是已经关闭了

opener指向打开窗口的对象

let wroxWin = window.open("http://www.wrox.com/",
              "wroxWindow",
              "height=400,width=400,top=10,left=10,resizable=yes");
alert(wroxWin.opener === window); // true

如果一个标签页打开了另一个,而window 对象需要跟另一个标签页通信,那么标签便不能运行在独立的进程中。在这些浏览器中,可以将新打
开的标签页的opener 属性设置为null ,表示新打开的标签页可以运行在独立的进程中。比如:

let wroxWin = window.open("http://www.wrox.com/",
              "wroxWindow",
              "height=400,width=400,top=10,left=10,resizable=yes");
wroxWin.opener = null;

把opener 设置为null 表示新打开的标签页不需要与打开它的标签页通信,因此可以在独立进程中运行。这个连接一旦切断,就无法恢复了。

7.定时器

setTimeout()
第一个参数可以是包含JavaScript代码的字符
串(类似于传给eval() 的字符串)或者一个函数
第二个参数是要等待的毫秒数

返回一个ID,表示这个是这个定时器的唯一标识

clearTimeout()取消定时器

// 设置超时任务
let timeoutId = setTimeout(() => alert("Hello world!"), 1000);
// 取消超时任务
clearTimeout(timeoutId);

所有超时执行的代码(函数)都会在全局作用域中的一个匿名函数中运行,因此函数中的this 值在非严格模式下始终指向window ,而在严格模式下是undefined 。

如果给setTimeout() 提供了一个箭头函数,那么this 会保留为定义它时所在的词汇作用域。

setInterval()

重复传入的函数

接收两个参数:要执行的代码(字符串或函数),以及把下一次执行定时代码的任务添加到队列要等待的时间(毫秒)

浏览器不关心方法执行没有,只是把方法添加到队列里去。

由此可看出,执行时间短、非阻塞的回调函数比较适合setInterval()

同样返回一个ID标识,用来取消。

clearInterval()

let num = 0, intervalId = null;
let max = 10;
let incrementNumber = function() {
  num++;
  // 如果达到最大值,则取消所有未执行的任务
  if (num == max) {
    clearInterval(intervalId);
    alert("Done");
  }
}
intervalId = setInterval(incrementNumber, 500);

clearInterval会取消未执行的任务。

let time = 0;
    let timer = setInterval(()=>{
		console.log(`第${time}次`);
		time++;
	},1000);
	setTimeout(()=>{
		clearInterval(timer);
		timer = null;
		console.log("关闭")
	},3500)

实验结果
timer设为null释放定时器

8.系统对话框

alert() 、confirm() 和prompt()

alert是单纯弹窗
confirm返回true or false表示用户点击确定没有

prompt要求用户输入一个值,返回这个值,没写的话,或关闭返回null

while (1) {
	if(confirm("我是你爸爸"))break;
}
alert("儿子乖");

嘿嘿嘿,恶趣味

while (1) {
	if(["对","是的","yes"].indexOf(prompt("我是你爸爸"))>-1)break;
}
alert("儿子乖");

9.find() 和print()

find()可以打开浏览器的搜索,print打开打印界面,但是很少用

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

它既是window的属性,也是document 的属性。也就是说,window.location 和document.location 指向同一个对象

location的属性
把search里的参数提取成键值对

let getQueryStringArgs = function() {
  // 取得没有开头问号的查询字符串
  let qs = (location.search.length > 0 ? location.search.substring(1) : ""),
    // 保存数据的对象
    args = {};

  // 把每个参数添加到args对象
  for (let item of qs.split("&").map(kv => kv.split("="))) {
    let name = decodeURIComponent(item[0]),
      value = decodeURIComponent(item[1]);
    if (name.length) {
      args[name] = value;
    }
  }
  return args;
}
// 假设查询字符串为?q=javascript&num=10
let args = getQueryStringArgs();
alert(args["q"]);    // "javascript"
alert(args["num"]);  // "10"

URLSearchParams
提供has,get,set方法修改url的参数

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("q");
alert(searchParams.toString());  // " num=10&page=3"

URLSearchParams
返回一个参数的类数组对象

let qs = "?q=javascript&num=10";
let searchParams = new URLSearchParams(qs);
for (let param of searchParams) {
  console.log(param);
}
// ["q", "javascript"]
// ["num", "10"]

操作地址

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

如果给location.href 或window.location 设置一个
URL,会以同一个URL值调用assign() 方法。

会立即启动导航到新URL的操作

会在历史中添加记录

replace() 方法就不会添加记录,而是取代

reload()会重新加载,不传参数会从缓存中取数据,假如传入true会强制性去请求数据,相当于ctrl加f5

11.navigator 对象
就是返回浏览器信息的,针对不同浏览器返回的内容可能不一样.

12.检测插件

// 插件检测,IE10及更低版本无效
let hasPlugin = function(name) {
  name = name.toLowerCase();
  for (let plugin of window.navigator.plugins){
    if (plugin.name.toLowerCase().indexOf(name) > -1){
      return true;
    }
  }
  return false;
}
// 检测Flash
alert(hasPlugin("Flash"));
// 检测QuickTime
alert(hasPlugin("QuickTime"));

plugins是插件的数组
每个plugin有这些属性:

name :插件名称。
description :插件介绍。
filename :插件的文件名。
length:由当前插件处理的MIME类型数量。

13.注册处理程序

registerProtocolHandler() 方法,把一个网站注
册为处理某种特定类型信息应用程序。

14.screen 对象

属性              说明

availHeight       屏幕像素高度减去系统组件高度(只读)
availLeft         没有被系统组件占用的屏幕的最左侧像素(只读)
availTop          没有被系统组件占用的屏幕的最顶端像素(只读)
availWidth        屏幕像素宽度减去系统组件宽度(只读)
colorDepth        表示屏幕颜色的位数;多数系统是32(只读)
height            屏幕像素高度
left              当前屏幕左边的像素距离
pixelDepth        屏幕的位深(只读)
top               当前屏幕顶端的像素距离
width             屏幕像素宽度
orientation       返回Screen Orientation API中屏幕的朝向

15.history 对象
go()

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

history.length表示历史长度,有多少个网页

历史状态管理

可以改变URL而不触发页面加载:

history.pushState() 方法

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

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

pushState() 会创建新的历史记录,所以也会相应地启用“后退”按钮。此时单击“后退”按钮,就会触发window 对象上的popstate 事件。popstate 事件的事件对象有一个state 属性,其中包含通过pushState() 第一个参数传入的state 对象:

window.addEventListener("popstate", (event) => {
  let state = event.state;
  if (state) { // 第一个页面加载时状态是null
    processState(state);
  }
});

可以通过history.state 获取当前的状态对象

这让我想到VUE的路由,有一种好像是在同一个页面营造出多个页面的效果,估计用了这个方法。

使用HTML5状态管理时,要确保通过pushState() 创建的每个“假”URL背后都对应着服务器上一个真实的物理URL。否则,单击“刷新”按钮会导致404错误。所有单页应用程序(SPA,SinglePage Application)框架都必须通过服务器或客户端的某些配置解决这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值