BOM
浏览器对象模型(Browser Object Model,简称 BOM)是 JavaScript 的组成部分之一,BOM 赋予了 JavaScript 程序与浏览器交互的能力。
window对象
window 对象是 BOM 的核心,用来表示当前浏览器窗口,其中提供了一系列用来操作或访问浏览器的方法和属性。另外,JavaScript 中的所有全局对象、函数以及变量也都属于 window 对象,甚至我们前面介绍的 document 对象也属于 window 对象。
注意:如果 HTML 文档中包含框架(<
frame> 或 <iframe> 标签),浏览器会为 HTML 文档创建一个 window 对象的同时,为每个框架创建一个额外的 window 对象。
窗口:简单理解就是window对象中包含各种属性和方法
全局变量是window的属性
- 定义的全局变量都是window对象的属性
- 多个js文件中,全局变量是共享的,共享全局作用域
window管理所有的全局变量和全局函数(是js特有的一种机制)
内置函数普遍是window的方法
- 内置的函数基本都是window的方法
示例:
窗口尺寸相关属性
获取浏览器内容区域宽高:(若有滚动条,则包含滚动条)
innerHeight
innerWidth
获取浏览器窗口外部宽高:返回浏览器窗口的完整宽高,包含工具栏与滚动条
outerHeight
outerWidth
若想获取窗口宽高且不包含滚动条 可使用document.documentElement.clientWidth
document.documentElement 表示html根元素
clientWidth
- 它是DOM的方法不是BOM的
- clientWidth 属性是一个只读属性,它返回该元素的像素宽度
clientHeight/clientWidth表示元素内部的高度/宽度。包含内边距,但不包含滚动条、边框、外边距。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<script>
console.log('窗口内宽' + innerWidth);
console.log('窗口内高' + innerHeight);
console.log('窗口外宽' + outerWidth);
console.log('窗口外高' + outerHeight);
console.log('不含滚动条的内宽' + document.documentElement.clientWidth);
console.log('不含滚动条的内高' + document.documentElement.clientHeight);
</script>
</body>
</html>
window.resize
- 当窗口宽高发生变化时,就会触发此事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
window.onresize = function () {
console.log('我的宽变为了' + document.documentElement.clientWidth);
console.log('我的高变为了' + document.documentElement.clientHeight);
};
</script>
</body>
</html>
window.scrollY
- window.scrollY是只读的
解决兼容性问题,可以用以下语句:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 2000px;
}
</style>
</head>
<body>
<script>
window.onscroll = function () {
var scrollTop = window.scrollY || document.documentElement.scrollTop;
console.log(scrollTop);
};
</script>
</body>
</html>
Element.scrollTop
- 获取滚动条的滚动距离
- document.documentElement.scrollTop不是只读的,可以用来设置已卷过多少高度
- 它也是个DOM方法
- scrollTop 可以被设置为任何整数值
注意:当浏览器页面大小不正常,出现缩放或放大,就会出现小数的情况!
window.onscroll
可用于HTML的落地页,比如手机的官网,滚到什么位置出现什么图片。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
height: 2000px;
}
</style>
</head>
<body>
<script>
window.onscroll = function () {
console.log('页面卷过了' + scrollY);
};
</script>
</body>
</html>
练习1
练习2
navigator对象
JavaScript navigator 对象中存储了与浏览器相关的信息,例如名称、版本等,我们可以通过 window 对象的 navigator 属性(即 window.navigator)来引用 navigator 对象,并通过它来获取浏览器的基本信息。
navigator 导航器、航行者(在这里跟这个翻译毫无相关)
由于 window 对象是一个全局对象,因此在使用
window.navigator时可以省略 window 前缀,例如window.navigator.appName可以简写为navigator.appName。
部分了解即可:
| 属性 | 描述 |
|---|---|
| appCodeName | 返回当前浏览器的内部名称(开发代号) |
| appName | 返回浏览器的官方名称 |
| appVersion | 返回浏览器的平台和版本信息 |
| cookieEnabled | 返回浏览器是否启用 cookie,启用返回 true,禁用返回 false |
| onLine | 返回浏览器是否联网,联网则返回 true,断网则返回 false |
| platform | 返回浏览器运行的操作系统平台 |
| userAgent | 返回浏览器的厂商和版本信息,即浏览器运行的操作系统、浏览器的版本、名称 |
navigator.appName
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 浏览器名称
console.log(navigator.appName); // Netscape
</script>
</body>
</html>
navigator.appVersion
version 版本
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 浏览器版本
console.log(navigator.appVersion);
</script>
</body>
</html>
下面是 Chrome 浏览器的
navigator.userAgent
agent 代理人
navigator.userAgent属性返回浏览器的 User Agent 字符串,表示用户设备信息,包含了浏览器的厂商、版本、操作系统等信息。
下面是 Chrome 浏览器的userAgent。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 浏览器内核信息与版本
console.log(navigator.userAgent);
</script>
</body>
</html>
下面是 Firefox 浏览器的
userAgent。
通过
userAgent属性识别浏览器,不是一个好办法。因为必须考虑所有的情况(不同的浏览器,不同的版本),非常麻烦,而且用户可以改变这个字符串。这个字符串的格式并无统一规定,也无法保证未来的适用性,各种上网设备层出不穷,难以穷尽。所以,现在一般不再通过它识别浏览器了,而是使用“功能识别”方法,即逐一测试当前浏览器是否支持要用到的 JavaScript 功能。
不过,通过userAgent可以大致准确地识别手机浏览器,方法就是测试是否包含mobi字符串。
var ua = navigator.userAgent.toLowerCase();
if (/mobi/.test(ua)) {
// 手机浏览器
} else {
// 非手机浏览器
}
如果想要识别所有移动设备的浏览器,可以测试更多的特征字符串。
/mobi|android|touch|mini/.test(ua)
navigator.platform
platform 计算机平台
Navigator.platform属性返回用户的操作系统信息,比如MacIntel、Win32、Linux x86_64等 。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 浏览器名称
// console.log(navigator.appName); // Netscape
// 操作系统
console.log(navigator.platform);
</script>
</body>
</html>
navigator应用
识别用户浏览器品牌
当用户点击页面上的“点击获取浏览器信息”按钮时,页面会弹出窗口告知当前使用的浏览器是什么浏览器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="button" value="点击获取浏览器信息" id="browser">
<script>
const browser = document.getElementById('browser');
const info = navigator.userAgent;
browser.addEventListener('click', () => {
if (info.indexOf('Chrome') != -1) {
alert('谷歌浏览器');
} else if (info.indexOf('Firefox') != -1) {
alert('火狐浏览器');
} else if (info.indexOf('Edg') != -1) {
alert('Edge');
} else if (info.indexOf('Opera') != -1) {
alert('Opera');
} else if (info.indexOf('Safari') != -1) {
alert('Safari');
}
}, false);
</script>
</body>
</html>
history对象
JavaScript history 对象中包含了用户在浏览器中访问过的历史记录,其中包括通过浏览器浏览过的页面,以及当前页面中通过<iframe>加载的页面。我们可以通过 window 对象中的 history 属性来获取 history 对象,由于 window 对象是一个全局对象,因此在使用window.history时可以省略 window 前缀,例如window.history.go()可以简写为history.go()。
下表中列举了 JavaScript history 对象中常用的方法及其描述:
| 方法 | 说明 |
|---|---|
| back() | 参照当前页面,返回历史记录中的上一条记录(即返回上一页),您也可以通过点击浏览器工具栏中的←按钮来实现同样的效果。 |
| forward() | 参照当前页面,前往历史记录中的下一条记录(即前进到下一页),您也可以通过点击浏览器工具栏中的→按钮来实现同样的效果。 |
| go() | 参照当前页面,根据给定参数,打开指定的历史记录,例如 -1 表示返回上一页,1 表示返回下一页。 |
这三个方法用于在历史之中移动。
History.back():移动到上一个网址,等同于点击浏览器的后退键。对于第一个访问的网址,该方法无效果。History.forward():移动到下一个网址,等同于点击浏览器的前进键。对于最后一个访问的网址,该方法无效果。History.go():接受一个整数作为参数,以当前网址为基准,移动到参数指定的网址,比如go(1)相当于forward(),go(-1)相当于back()。如果参数超过实际存在的网址范围,该方法无效果;如果不指定参数,默认参数为0,相当于刷新当前页面。
history.back();
history.forward();
history.go(-2);
history.go(0)相当于刷新当前页面。
history.go(0); // 刷新当前页面
注意,移动到以前访问过的页面时,页面通常是从浏览器缓存之中加载,而不是重新要求服务器发送新的网页。
location对象
JavaScript location 对象中包含了有关当前页面链接(URL)的信息,例如当前页面的完整 URL、端口号等,我们可以通过 window 对象中的 location 属性来获取 location 对象。由于 window 对象是一个全局对象,因此在使用window.location时可以省略 window 前缀,例如window.location.href可以简写为location.href。
window.location.href
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>点击跳转网页</title>
</head>
<body>
<button>点击跳至百度</button>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function () {
window.location = 'https://www.baidu.com';
};
</script>
</body>
</html>
window.location.reload( );
- 重新加载当前页面
- 参数加个true可以强制刷新
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>重新加载</title>
</head>
<body>
<button>点击刷新</button>
<script>
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function () {
window.location.reload(true);
};
</script>
</body>
</html>
window.location.search
- GET请求查询参数
返回一个 URL 中的查询部分,即 URL 中
?及其之后的一系列查询参数。
在访问一个网站的时候,网址上可以用一个问号的形式来带一些参数给服务器的脚本程序,此时:a=1&b=2 中间有个&符号,表示我们要传两个参数,传给服务器,服务器就会收到这两个参数
BOM特效开发
返回顶部效果制作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
height: 3000px;
}
#backToTop {
width: 50px;
height: 50px;
position: fixed;
right: 100px;
bottom: 100px;
background-color: #F1F3F4;
font-size: 18px;
text-align: center;
padding: 8px;
cursor: pointer;
}
#backToTop:hover {
background-color: #E9EBEC;
}
</style>
</head>
<body>
<div id="backToTop">
返回顶部
</div>
<script>
// 点击返回顶部效果
const backToTop = document.getElementById('backToTop');
let timer;
backToTop.addEventListener('click', () => {
clearInterval(timer); // 为防止疯狂点击出现的bug 设表先关
timer = setInterval(() => {
document.documentElement.scrollTop -= 200;
if (document.documentElement.scrollTop <= 0) {
clearInterval(timer);
}
}, 20);
}, false);
</script>
</body>
</html>
楼层导航效果
我们先来了解一下offsetTop属性,它可以获取 div 元素的顶部偏移量
使用这个属性的时候,所有的祖先元素不要有定位,有定位就不好用了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
list-style: none;
}
.lead {
position: fixed;
right: 100px;
top: 50%;
width: 50px;
height: 83px;
margin-top: -40px;
background-color: rgba(0, 0, 0, .2);
color: #5A88FD;
text-align: center;
cursor: pointer;
}
.lead li.current {
background-color: rgba(0, 0, 0, .2);
color: #FC6B58;
}
</style>
</head>
<body>
<!-- 右侧导航 -->
<div class="lead">
<ul id="list">
<li class="current" data-n="娱乐">娱乐</li>
<li data-n="视频">视频</li>
<li data-n="音乐">音乐</li>
<li data-n="新闻">新闻</li>
</ul>
</div>
<!-- 内容区域 -->
<div class="wrapper">
<div class="contents" style="height: 500px; font-size: 30px;" data-n="娱乐">娱乐</div>
<div class="contents" style="height: 800px; font-size: 30px;" data-n="视频">视频</div>
<div class="contents" style="height: 500px; font-size: 30px;" data-n="音乐">音乐</div>
<div class="contents" style="height: 900px; font-size: 30px;" data-n="新闻">新闻</div>
</div>
<script>
const list = document.getElementById('list'); // ul元素
const contents = document.getElementsByClassName('contents');
const rightOptions = document.querySelectorAll('#list li'); // 所有的li元素
// 点击跳转
list.addEventListener('click', (e) => {
if (e.target.tagName.toLowerCase() == 'li') {
const n = e.target.getAttribute('data-n'); // 点击谁获取谁的data-n属性
const contentsHeight = document.querySelector('.contents[data-n=' + n + ']').offsetTop; // 选中data-n等于被点击项的data-n的DOM元素,并获取它到顶部的距离
document.documentElement.scrollTop = contentsHeight; // 进行跳转翻动屏幕
}
}, false);
// 为当前的楼层保持有current css属性
let offsetTopArr = []; // 将每个内容的scrollTop值推入数组中,为显示楼层数
for (var i = 0; i < contents.length; i++) {
offsetTopArr.push(contents[i].offsetTop);
}
offsetTopArr.push(Infinity); // 推入Infinity为后面的比较使用
let nowFloor = -1; // 节流,表示当前楼层,设置成负1,为了一上来就触发
window.addEventListener('scroll', () => {
let scrollTop = document.documentElement.scrollTop; // 获取当前的滚动值
for (var i = 0; i < offsetTopArr.length; i++) {
if (scrollTop >= offsetTopArr[i] && scrollTop < offsetTopArr[i + 1]) {
// console.log(i); // 当前所在楼层数
break;
}
}
if (nowFloor != i) {
nowFloor = i;
// console.log(i);
for (var j = 0; j < rightOptions.length; j++) {
if (j == i) {
rightOptions[j].className = 'current';
} else {
rightOptions[j].className = '';
}
}
}
}, false);
</script>
</body>
</html>
舞台再大,你不上台,永远是个观众。平台再好,你不参与,永远是局外人。能力再大,你不行动,只能看别人成功!没有人会关心你付 出过多少努力,撑得累不累,摔得痛不痛,他们只会看你最后站在什么位置,然后羡慕或鄙夷。