- BOM
- window对象
- window对象结构
- window对象的属性
- history
- pushStaete
- replaceState
- location
- navigator
- userAgent
- user-agent的作用
- screen 屏幕
- window的函数
- 思考一下代码的执行顺序
- 同步 Synchronous
- 异步 Asynchronous
BOM
BOM是 Browser Object Model的缩写,中文翻译过来就是 浏览器对象模型. 从名字上就可以看出,它是用于访问浏览器功能的对象.
window对象
window对象是BOM的核心对象,一个window表示一个浏览器实例.当你打开多个选项卡的时候,每个选项卡对应一个window对象.
在下图中,我们在浏览器中 打开了 两个选项卡,那么每个选项卡就对应一个自己的window对象.
window对象结构
window 对象处于 JavaScript 结
构的最顶层,对于每个打开的窗口,系统都会自动为其定义 window 对象。
window对象的属性
属性名 | 含义 |
---|---|
document | 当前窗口中的文档对象 |
frames | 当前窗口中的框架数 |
history | 记录浏览器的浏览历史 |
location | 当前页面的URL地址 |
navigator | 与浏览器相关的信息 |
screen | 屏幕信息 |
注意: 以上所有的属性都可以直接在页面中使用或者通过window.xxx的方式访问
history
负责管理浏览器的浏览记录,控制页面的前进或者后退 数
获取history对象
var historyObj = window.history;
//可以直接使用history对象
console.log(history);
属性名 | 含义 |
---|---|
length | 历史记录条数 |
go | 跳转到指定页数 |
back | 后退一页 |
forward | 前进一页 |
pushStaete | 不刷新页面修改URL链接 |
replaceState | 修改当前历史记录 |
history.go(-2); //后退2页
history.go(3);//前进三页
history.back();//后退一页
history.forward();//前进一页
pushStaete
在不刷新浏览器的情况下,将新的浏览器记录插入到历史记录中
history.pushState(stateObject, title, url);
参数说明:
stateObject: 状态对象.将要传递到新页面中的内容存储在该对象中.
titile: 标题,由于兼容性问题,这里建议传递一个空值
url: 新的历史URL记录.浏览器在调用pushState()方法后不会加载该地址;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。
示例
- 打开我们的测试页面 http://www.githuo.com/jsbook/ 查看相关的History信息,
- 在控制台中 输入
然后再查看history记录,如下图history.pushState({status:0},'','?info=110')
地址栏也变成了
http://www.githuo.com/jsbook/?info=110
从上面的例子中我们可以看到,通过 pushState 改变了 地址栏的内容,但是浏览器并没有重新加载.并且 history里的state也多了一个status属性
replaceState
history.replaceState() 的使用与 history.pushState() 非常相似,区别在于 replaceState() 是修改了当前的历史记录项而不是新建一个。 注意这并不会阻止其在全局浏览器历史记录中创建一个新的历史记录项。
history.replaceState(stateObj, "page 3", "bar2.html");
示例
地址栏发生变化
http://www.githuo.com/jsbook/bar.html
历史记录新增了一条
location
location 对象存储了当前文档位置(URL)相关的信息
属性说明
属性名 | 含义 |
---|---|
origin | 返回URL的协议,主机名和端口号 |
protocol | url的协议 |
host | url中的主机名和端口号 |
hostname | 主机名 |
port | 端口号 |
pathname | url地址的路径部分 |
search | 查询部分 |
hash | url中 锚部分 |
href | 文档的完整url地址 |
protocol 协议头
表示访问资源和服务的协议,
- http 超文本传输协议 (用于网页传输),默认端口号是 80,不会显示
- https 超文本安全传输协议.(用于网页传输,比http协议要安全)
- mailto URL指向E-mail地址
- file 文件协议,表示一台主机上可以直接访问的文件
- ftp 文件传输协议.
- rtsp,rtspu 通过实时流传输协议(Real Time Streaming Protocol)解析的音/视频媒体资源的标识符
hostname 主机名
每台电脑在网络上都会有一个唯一的由小于255一组数字组成的地址,我们称之为IP地址.当我们去访问一个网站的时候,实际上是通过IP地址访问这个网站所在的的电脑上的内容.
查看网站的 主机名
ping www.baidu.com //14.215.177.38
ping www.githuo.com //120.78.135.42
ping www.taobao.com //113.96.109.100
ping www.jd.com //183.60.141.1
网络访问流程
port 端口号
所谓端口号,就像是门牌号一样.你通过我给你的地址,你找到我这栋大楼,由于大楼里有很多个房间,你需要通过门牌号才能找到我.而端口号,就是我们通过ip地址找到互联网上的电脑,但是这台电脑上运行着很多软件,我们就需要根据端口号来找到对应的软件,然后才能进行通信.
如图
pathname 路径
有时候需要访问某个网站的图片,就需要在网址后面加上图片在网站电脑上的位置 例如 上个例子中图片的完整地址就是
http://localhost:4000/images/BOM/10.%E7%AB%AF%E5%8F%A3%E5%8F%B7.png
其中下面这部分就是图片所在的路径
/images/BOM/10.%E7%AB%AF%E5%8F%A3%E5%8F%B7.png
search 查询
获取url地址中 ?以及之后的内容,例如
http://www.githuo.com/jsbook?page=1&&size=20
我们经常通过search来获取 ?page=1&&size=20 部分内容,然后将 这段内容转换成对象
var str = location.search; //?page=1&&size=20
//去掉问号
str = str.slice(1,str.length);
//拆分字符串成数组
var arr = str.split("&&"); // ["page=1","size=20"]
var result = {}
//遍历数组,
for(var i=0;i<=arr.length-1;i++){
//拆分数组元素
var ele = arr[i].split("=");
result[ele[0]] = ele[1];
}
输出结果
{page: "1", size: "20"}
hash 哈希值
在url地址后面加上以#开头的内容,这些内容就是url的哈希值. 常见于 锚点和调用pushState函数.
http://www.githuo.com/jsbook/%E8%BF%9B%E9%98%B6/05.BOM%E5%AF%B9%E8%B1%A1.html#page1
href
完整的url地址
location.href
"http://www.githuo.com/jsbook/%E8%BF%9B%E9%98%B6/05.BOM%E5%AF%B9%E8%B1%A1.html#page1"
navigator
包含了浏览器的一些基本信息,但每个浏览器的表现不一.这里以chrome为例,在控制台输入 navigator 得到以下内容:
以上内容并非是每个浏览器都适用.我们这里只挑选常用的来学习 属性名|含义 ---|:--: appCodeName|浏览器的代码名,chrome,safari,firfox都是"Mozilla" appName | 浏览器的名称,默认值都是Netscape appVersion | 浏览器的版本号(废弃) platform | 浏览器运行所在的平台 language | 当前使用的语言 userAgent | 用户代理(user agent)字符串 geolocation | 定位
userAgent
用户代理(user agent)字符串,不同的浏览器或者不同版本的浏览器返回的字符串可能也不一样.
mac端Chrome浏览器
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.
3987.122 Safari/537.36
安卓端 Chrome浏览器
Mozilla/5.0 (Linux; Android 9; meizu 16Xs)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.
3987.119 Mobile Safari/537.36
Firfox浏览器
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:73.0) Gecko/20100101 Firefox/73.0
Safari浏览器
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5)
AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.
1 Safari/605.1.15
ios端
Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_0 like Mac OS
X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/
9A334 Safari/7534.48.3
Gecko
Gecko 是 Firefox 的呈现引擎。Gecko 首次开发是作为 Mozilla 浏览器 Netscape 6 的一部分
WebKit
Apple 宣布发布首款他们自主开发的 web 浏览器:Safari。它的呈现引擎叫 WebKit
Chrome
Chrome浏览器以 WebKit 作为呈现引擎,但是用了其他的javascript引擎.user-agent字符串是在webkit信息的基础上增加一些新的内容
user-agent的作用
通过user-agent不能完全准确的判断是属于那款浏览器。
统计用户浏览器使用情况。有些浏览器说被多少人使用了,实际上就可以通过判断每个IP的UA来确定这个IP是用什么浏览器访问的,以得到使用量的数据。
根据用户使用浏览器的不同,显示不同的排版从而为用户提供更好的体验。有些网站会根据这个来调整打开网站的类型,如是手机的就打开wap,显示非手机的就打开pc常规页面。用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的UA来判断的。
//判断是否是pc
function IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone","SymbianOS", "Windows Phone","iPad", "iPod"];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
if(flag){
location.href = "http://www.githuo.com"
}else{
location.href = "http://m.jd.com";
}
}
//判断是否是移动端
if (/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent)) { //移动端
//TODO
location.href = "http://m.jd.com";
}else{
location.href = "http://www.githuo.com"
}
screen 屏幕
获取和屏幕相关的属性
属性 | 说明 |
---|---|
availWidth | 返回显示屏幕的宽度 (除 Windows 任务栏之外) |
availHeight | 返回显示屏幕的高度 (除 Windows 任务栏之外) |
width | 返回显示屏幕的宽度 |
height | 返回显示屏幕的高度 |
colorDepth | 返回目标设备或缓冲器上的调色板的比特深度 |
pixelDepth | 返回显示屏幕的颜色分辨率(比特每像素) |
availLeft | 和屏幕左侧的距离 |
availTop | 和屏幕顶部的距离 |
orientation | 屏幕旋转的方向 |
orientation
获取屏幕旋转方向
type属性
type 属性主要通过描述来表达屏幕的旋转方向,type 的返回值总共有四个,对应着四个不同的旋转方向:
portrait-primary:竖屏状态并且旋转角度为 0 度,也就是设备的自然位置
portrait-secondary:竖屏状并且即旋转角度为 180 度,也就是倒着拿的位置
landscape-primary:横屏状态并且旋转角度为 90 度
landscape-secondary:横屏状态并且旋转角度为 180 度
function rotationChange() {
console.log('rotation changed to:', screen.orientation.type);
var screenType = screen.orientation.type;
if(screenType === "portrait-primary"){
alert("竖屏主方向");
}else if(screenType === "portrait-secondary"){
alert("竖屏次方向");
}else if(screenType === "landscape-primary"){
alert("横屏主方向");
}else if(screenType === "landscape-secondary"){
alert("横屏次方向");
}else{
alert("不支持旋转");
}
}
//屏幕发生旋转的时候触发该函数
screen.orientation.addEventListener('change', rotationChange);
锁定屏幕和解锁屏幕
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button onclick="lockPortrait()">锁屏</button>
<button onclick="unlockPortrait()">解锁</button>
</body>
</html>
<script>
function lockPortrait(){
// 首先进入全屏模式
document.documentElement.requestFullscreen();
// 锁定竖屏方向
screen.orientation
.lock('portrait')
.catch(e => alert(e.message));
}
function unlockPortrait(){
//解锁屏幕方向
screen.orientation.unlock();
}
</script>
window的函数
在这里只列举常用的一些方法进行说明
方法名 | 函数 |
---|---|
alert | 弹出警告框 |
confirm | 弹出确认会话框 |
prompt | 弹出对话框 |
focus | 让窗口获得聚焦 |
blur | 让窗口失去焦点 |
open | 打开一一个新的顶级窗口 |
resizeBy()、resizeTo() | 重设窗口大小。 |
scrollBy()、scrollTo() | 滚动当前窗口中的HTML文档。 |
setTimeout()、clearTimeout() | 设置、删除定时器。 |
setInterval()、clearlnterval() | 也是设置重复定时器 |
open
打开一一个新的顶级窗口,并可以导航到一个特定的URL.
window.open(URL,name,specs,replace)
open('http://www.githuo.com/jsbook');//新建窗口并打开极火网
open('http://www.githuo.com/jsbook','极火网');
open('http://www.githuo.com/jsbook','_blank','width=200,height=100')
scrollTo
scrollTo(x,y);
- x 横向滚动距离
- y 纵向滚动距离
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.main {
width: 100%;
height: 200%;
background-color: cyan;
}
</style>
</head>
<body>
<button onclick="scrollView()">滚动</button>
<div class="main"></div>
</body>
</html>
<script>
function scrollView(){
window.scrollTo(100,300);
}
</script>
setTimeout
设置定时器,在某个时间后执行函数,只执行一次 setTimeout(arg1,arg2)
- arg1: 要执行的函数
- arg2: 超时时间(毫秒数)
下面的例子中,是要在1000毫秒之后,打印 "hello"
setTimeout(function(){
console.log("hello");
},1000)
clearTimeout
每使用一次setTimeout函数,就会生成一个定时器ID,我们可以通过clearTimeout方法来清除这个定时器.
var timer = null;
timer = setTimeout(function(){
console.log("zmt");
},3000)
setTimeout(function(){
console.log("githuo");
clearTimeout(timer)
},1000)
上面的最终的执行结果是,在1秒的时候输出 "githuo",然后取消 3秒的定时器,当时间走到三秒的时候,就不会再输出 "zmt"
setInterval
每隔特定的毫秒数之后,执行函数
var i = 0;
setInterval(function(){
console.log("i="+i);
i++;
},1000)
上面例子中,每隔一秒就输出i的值,并对i进行加1运算,
clearInterval
清除循环定时器
var i = 0;
var intervalTime = null;
intervalTime = setInterval(function(){
console.log("i="+i);
i++;
},1000)
//在5秒之后,停止interval定时器
setTimeout(function(){
cleartInterval(intervalTime)
},5000)
使用 setTimeout实现setInterval功能
var timer = null;
var i = 0;
function interval(time){
timer = setTimeout(function(){
console.log(i);
i++;
clearTimeout(timer);
interval(time);
},time)
}
interval(1000);
思考一下代码的执行顺序
setTimeout(function(){
console.log("1");
},1000)
setTimeout(function(){
console.log("0");
},0)
console.log("3");
//斐波那契数列函数
function fbn(n){
if(n==1 || n==2){
return 1;
}
return fbn(n-1)+fbn(n-2)
}
var rs = fbn(42);
console.log(rs);
同步 Synchronous
同步就是方法一旦调用就必须等到该方法执行结束之后,才会继续往后执行
function f1(){
console.log("1");
}
function f2(){
console.log("2");
}
f1();
f2();
调用f1函数
执行f1函数的内容
f1函数执行完成,从执行栈中离开.调用f2函数
执行f2函数
所有同步函数执行完毕,执行栈为空
异步 Asynchronous
在js中的异步,它必须等所有同步行为都执行完成之后,才会执行异步操作.
function f1(){
console.log("1");
}
function f2(){
console.log("2");
}
setTimeout(function(){
console.log("2");
},0)
f1();
f2();
- 调用setTimeout方法
- 执行setTimeout方法,将setTimeout方法里的函数注册到事件队列中,等待执行
接下来就是调用f1和f2,和同步的方法一样,这里就放图了
当同步函数f1和f2都执行完成之后,再到事件队列里调用排队等待执行的事件
异步事件在JS编程中的地位非常重要,因此你需要好好琢磨它!