JavaScript
BOM
Browser Object Model 浏览器对象模型
+ 浏览器给我们提供的一套操作浏览器窗口的属性和方法
+ BOM 的顶级对象是 window
=> 是一个对象, 当你打开一个页面的时候就有一个window
=> 你在全局定义的所有变量都在 window 下
+ 所有和 BOM 相关的 API 都是 window.xxx
=> 在 JS 代码书写的时候,可以省略 window. 不写
浏览器窗口尺寸
+ 指的是 浏览器 可视窗口的尺寸
+ 浏览器可能会出现滚动条
=> 在一般浏览器,滚动条是算浏览器的一部分的
=> 但在 mac 的 safari 浏览器是不算的
+ 两个属性
1. innerWidth
2. innerHeight
+ 共同点: 包含滚动条的尺寸
=> DOM 级别的获取是不包含滚动条的
console.log(window.innerWidth);
console.log(window.innerHeight);
// 可省略 window. 不写
console.log(innerWidth);
console.log(innerHeight);
浏览器的弹出层
+ 在 BOM 里面, 给我们提供了三个弹出层
+ 可以在浏览器弹出一些信息
1. alert() 警告框
-> 弹出一段提示文本
-> 只有一个确定按钮
2. confirm() 选择框
-> 弹出一段提示文本
-> 有确定和取消两个按钮
3. prompt() 输入框
-> 弹出一个提示文本
-> 有一个 input 输入框
-> 有确定和取消两个按钮
语法:
1. alert()
语法: alert('提示文本')
返回值: undefined
2. confirm()
语法: confirm('提示文本')
返回值: 布尔值
-> 当用户点击ok确定的时候,是 true
-> 当用户点击cancel取消的时候,是 false
3. prompt()
语法: prompt('提示文本')
返回值:
-> 如果用户点击确定,那么就是文本框中的内容
-> 如果用户点击取消,那么就是 null
共同点:
+ 会阻断程序的继续执行
=> 因为 JS 单线程
=> 弹出层弹出以后, 如果用户没有点击按钮,代表当前弹出层没有结束
+ 直到用户操作以后,才会继续向下执行代码
+ 所以用户体验不好,大多不会使用,都是自己写一个弹出层
// 1. alert()
var res = alert('我是提示文本');
// 2. confirm()
var res = confirm('请选择');
console.log(res);
// 3. prompt()
var res = prompt('请输入一段文本');
console.log(res);
浏览器的地址栏(重点!!!)
+ 一个地址包含哪些内容(了解)
=> http://www.baidu.com?a=100&b=200#abc
=> http 传输协议
=> www.baidu.com 域名
=> ?a=100&b=200 查询字符串(queryString)
=> #abc 哈希(hash)
+ 地址里面包含的内容的作用(了解)
=> 传输协议: 前后端交互的方式
=> 域名: 找到一台服务器电脑
=> 查询字符串:
-> 不影响你打开页面
-> 打开这个页面的时候携带的信息
=> 哈希: 锚点定位
console.log(window.location);
+ 在 window 下有一个成员叫做 location
=> location 是一个对象,里面存储着和网页地址所有内容相关的信息
=> hash: 当前页面的哈希值
=> href: 是一个读写的属性(当前地址栏地址)
-> 读: 获取当前打开的页面的地址(中文是 url 编码格式)
-> 写: 设置当前打开页面的地址(跳转页面)
=> search: 当前地址中的查询字符串(queryString)
-> 读: 查询到的是一个字符串
-> 这个是其他页面跳转到当前页面的时候带来的信息
-> 我们为了使用,需要把它解析出来(变成一个对象)
href属性
<button id="btn">跳转页面</button>
<script>
// 1. href
// 读取
console.log(window.location.href);
// 设置
btn.onclick = function(){
window.location.href = 'https://www.baidu.com';
};
</script>
search属性
<form action="">
<input type="text" name="username">
<input type="text" name="password">
<button>提交</button>
</form>
<script>
// 2. search
// 读取: 读取到当前地址的 查询字符串
console.log(window.location.search); // ?username=&password=
/*
解析查询字符串
+ 两种情况
1. ''
2. '?key=value&key=value'
步骤:
1. 准备一个函数接受一个参数
=> 参数: 要解析的查询字符串
2. 开始解析
2-1. 判断如果是空字符串,直接返回 空对象
-> 如果不是空字符串, 要把字符串解析放在对象里返回
-> 在最开始定义一个对象
-> 判断如果 str 有,就向对象里面添加内容
-> 返回创建好的对象
2-2.截取一部分字符串
-> ? 表示 queryString 的开始,只要 ? 后面的部分
-> slice(1)
-> 使用 & 切割开
2-3. 循环这个切割好的数组
-> 拿到每一项
-> 把每一项再次切割,用 = 切割
-> 切割好以后 [0] 就是对象的 key
-> [1] 就是对象的 value
*/
var str = '?a=100&b=200';
function parseQueryString(str){
var obj = {};
if(str){
// 向对象里添加内容
var tmp = str.slice(1).split('&');
tmp.forEach(function(item){
var t = item.split('=');
obj[t[0]] = t[1];
})
};
return obj;
};
var res = parseQueryString(str);
console.log(res); // {a: "100", b: "200"}
</script>
reload方法
+ location 里面 还有一个方法
=> reload()
=> 重新加载当前页面
=> 就相当于按下了浏览器左上角的刷新按钮
=> 注意: **不能写在打开页面就能执行的地方!**
<button id="r">刷新</button>
// 3. reload()
r.onclick = function(){
window.location.reload();
}
浏览器的历史记录
+ 操作浏览器前进后退
+ window 下有一个叫做 history 的成员
=> 是一个对象
=> 里面包含了一些操作历史记录的属性和方法
console.log(window.history);
back()
=> 语法: window.history.back()
=> 作用: 回退到上一条历史记录,相当于 ←
=> 前提: 你需要有历史记录,不然没得退
<h1>我是 a.html 页面</h1>
<a href="./b.html">跳转到b页面</a>
<h1>我是 b.html 页面</h1>
<button id="back">历史回退</button>
<script>
back.onclick = function(){
window.history.back();
}
</script>
forward()
=> 语法: window.history.forward()
=> 作用: 前进到下一条历史记录,相当于 →
=> 前提: 你需要回退过以后,才可以操作
<h1>我是 a.html 页面</h1>
<a href="./b.html">跳转到b页面</a>
<button id="forward">历史前进</button>
<script>
forward.onclick = function(){
window.history.forward();
}
</script>
go()
=> 语法: window.history.go(整数)
-> 正整数: 表示前进
-> 0: 表示刷新当前页面
-> 负整数: 表示后退
<h1>我是 a.html 页面</h1>
<a href="./b.html">跳转到b页面</a>
<button id="forward">历史前进</button>
<script>
forward.onclick = function(){
//window.history.forward();
window.history.go(1);
}
</script>
<h1>我是 b.html 页面</h1>
<a href="./c.html">跳转到 c 页面</a>
<button id="back">历史回退</button>
<script>
back.onclick = function(){
// window.history.back();
window.history.go(-1);
}
</script>
<h1>我是 c.html 页面</h1>
<button id="back">历史回退</button>
<script>
back.onclick = function(){
window.history.go(-2); // 点击直接回到 a 页面
}
</script>
浏览器的版本信息
+ 用来区分浏览器(了解即可,不太用了)
+ 在 window 下有一个成员叫做 navigator
=> navigator 是一个对象,里面存储着浏览器的版本信息
1. userAgent 属性
=> 表示浏览器的版本及型号信息
2. appName
=> 所有浏览器都是统一的名字 netscape网景
=> IE 低版本浏览器除外
=> IE 高版本也是 netscape
3. platform
=> 表示浏览器所在的操作系统
// 1. userAgent
console.log(window.navigator.userAgent);
google下
firefox下
// 2. appName
console.log(window.navigator.appName); // Netscape
// 3. platform
console.log(window.navigator.platform); // Linux x86_64, 移动端下比如 ios
浏览器的常见事件
+ 由浏览器行为触发的事件
onload
1. window.onload = function(){}
=> 页面所有资源加载完毕后执行
=> 所有资源: 图片, 视频, 音频, ...
=> 作用: JS 前置(script写在<head></head>标签中)
-> 当你需要把 JS 代码写在 head 标签里面的时候
-> 最好加上一个 window.onload
注: 否则会出错:Uncaught ReferenceError: btn is not defined
onscroll
2. window.onscroll = function(){}
=> 浏览器滚动条滚动的时候触发
=> 不管横向还是纵向,只要滚动就触发
=> 作用:
1. 楼层导航
2. 顶部通栏和回到顶部按钮的显示
3. 瀑布流 (以上三点可参考京东网页)
4. 渐进显示页面
// 2. onscroll
<style>
body{ width: 2000px; height: 2000px;}
</style>
<script>
window.onscroll = function(){
console.log('滚动条在滚动');
}
</script>
onresize
3. window.onresize = function(){}
=> 浏览器可是窗口改变的时候触发
=> 只要改变就会触发
=> 一般结合 innerWidth 和 innerHeight 来判断屏幕尺寸
-> 移动端: 横屏
-> 响应式布局: 判断窗口大小
// 3. onresize
window.onresize = function(){
console.log('浏览器可视窗口改变大小了');
}
浏览器卷去的高度和宽度
+ 当页面比窗口宽或者高的时候
+ 会有一部分是随着滚动被隐藏的
+ 我们把上面隐藏的叫做 卷去的高度
+ 我们把左边隐藏的叫做 卷去的宽度
小扩展: 短路表达式
1. ||
+ 作用: 可以用 || 运算符分隔两个表达式
+ 如果前面的表达式结果为 true
=> 那么后面的就不执行了
=> 只有前面为 false 的时候, 才会执行后面的表达式
+ 当你使用短路表达式赋值的时候
=> 如果前面表达式是 true,那么就得到前面表达式的结果
=> 如果前面表达式是 false,那么就得到后面表达式的结果
2. &&
+ 作用: 可以用 && 运算符分隔两个表达式
+ 如果前面的表达式结果为 true
=> 那么后面的才会执行
=> 如果前面的是false, 那么后面的就不执行了
+ 当你使用 && 短路表达式赋值的时候
=> 如果前面表达式是true, 那么直接运算后面表达式的结果赋值
=> 如果前面表达式是false, 那么直接把前面的结果返回
// 1. ||
// false || alert('你好');
// 因为 1 + 1 是true,所以 n 得到的就是 1 + 1 的结果
// 后面的 10 + 10 不再执行
var n = 1 + 1 || 10 + 10;
// 因为 1 - 1 是false,所以 n 得到的就是 10 + 10 的结果
var n = 1 - 1 || 10 + 10;
console.log(n);
// 1 - 1 || 10 + 10 表达式的结果是 20
// 当 20 在 if 条件里面就是 true
if(1 - 1 || 10 + 10){}
// 1 - 1 || 10 - 10 表达式的结果是 0
// 当 0 在 if 条件里面就是 false
if(1 - 1 || 10 + 10){}
// 2. &&
// true && alert('你好');
// 因为 1 + 1 是 true, 所以一定会执行后面的表达式
// 不管后面的表达式是什么,都会把结果赋值给 n
var n = 1 + 1 && 10 - 10; // 0
// 因为 1 - 1 是 false, 所以后面的表达式不再执行
// 直接把 1 - 1 的结果赋值给 n
var n = 1 - 1 && 10 + 10; // 0
console.log(n);
document.documentElement.scrollTop 和 document.body.scrollTop
+ 获取卷去的高度:
文档 html
1. document.documentElement.scrollTop
=> 使用必须要有 DOCTYPE 标签, 没有就一直为 0
2. document.body.scrollTop
=> 使用必须要没有 DOCTYPE 标签, 不然就一直为 0
3. 兼容写法
=> var scrollTop = document.documentElement.scrollTop || document.body.scrollTop
=> || 当作短路表达式使用的
-> 当前面为 true 的时候, 那么就直接返回前面的值
-> 当前面为 false 的时候, 那么就返回后面的值,不管后面是不是false
// 1. scrollTop
window.onscroll = function(){
// console.log('html', document.documentElement.scrollTop);
// console.log('body', document.body.scrollTop);
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
console.log(scrollTop);
}
document.documentElement.scrollLeft 和 document.body.scrollLeft
+ 获取卷去的宽度:
文档 html
1. document.documentElement.scrollLeft
=> 使用必须要有 DOCTYPE 标签, 没有就一直为 0
2. document.body.scrollLeft
=> 使用必须要没有 DOCTYPE 标签, 不然就一直为 0
3. 兼容写法
=> var scrollTop = document.documentElement.scrollLeft || document.body.scrollLeft
// 2. scrollLeft
window.onscroll = function(){
// console.log('html', document.documentElement.scrollLeft);
// console.log('body', document.documentElement.scrollLeft);
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
console.log(scrollLeft);
}
浏览器滚动到
+ 通过 JS 代码指定 浏览器滚动到什么位置
1. scrollTo()
语法:
1. window.scrollTo(横向坐标, 纵向坐标)
=> 书写不需要单位, 给个数字就可以
=> 如果你传递数字,必须两个参数,一个参数会报错
=> 特点: 瞬间定位
2. window.scrollTo({
top: 纵向坐标,
left: 横向坐标,
})
=> 对象里面写几个值无所谓
=> 特点: 可以依靠第三个配置项来决定是瞬间定位还是平滑滚动
-> behavior: 'smooth', 'instant'
-> 不能决定滚动时间
<div id="btn"></div>
btn.onclick = function(){
// 语法1
// 让浏览器滚动到 300 500 的位置
// window.scrollTo(300, 500);
// 语法2
window.scrollTo({
top: 0,
left: 100,
// 决定定位方式
behavior: 'smooth'
});
}
如果你想自己操作滚动时间, 需要自己来完成
自己完成浏览器回到顶部:
1. document.documentElement.scrollTop
document.documentElement.scrollLeft
是读写的属性
可以获取可以设置
设置: 直接赋值就可以了
2. 定时器
=> 作用: 每间隔一段时间执行依次代码
=> 如果: 我每间隔 30ms,让当前浏览器卷去的高度 - 20
3. 滚动以后,就停不下来了
=> 因为你点击的时候,开启了定时器
=> 这个定时器就一直存在
=> 解决问题
-> 直接在定时器里面判断
-> 当卷去的高度 <= 0 的时候,停止定时器
4. 假设你的滚动速度比较慢
=> 在没有滚动到指定位置的时候
=> 是没有办法中断的
=> 回到顶部,数字是越来越小
-> 一旦下一次滚动比上一次滚动数字要大
-> 说明反方向移动
-> 就要停下来
=> 浏览滚动事件的时候做这个事情
-> 记录上一次的位置
var timer = 0;
btn.onclick = function(){
// 设置一个定时器,来让滚动条向上滚动
timer = setInterval(function(){
document.documentElement.scrollTop -= 20;
// 滚动到目标位置后停止定时器
if(document.documentElement.scrollTop <= 0){
clearInterval(timer);
}
}, 50);
}
// 在外面记录上一次的位置
var st = 0;
// 滚动过程中, 你改变滚动方向时停下来
window.onscroll = function(){
// 在你给 str 赋值之前, st 的值是上一次的值
// 进行比较
if(document.documentElement.scrollTop >= st){
// 停止定时器
clearInterval(timer);
}
// 把当前位置赋值给 st
// 随着滚动记录每一次滚动的位置
st = document.documentElement.scrollTop;
console.log(st);
}