一、BOM概念
BOM,全名为Browser Object Model,翻译过来为浏览器对象模型。
DOM是将HTML文档中的各个元素封装成一个对象(Document),而BOM则是将一个浏览器的各个组成部分封装成对象(Browser)供调用使用。
下面我们就来分析BOM其中包含哪几个对象以及其中的信息吧。
总的来说,BOM对象大致包含五个部分:
- Window对象:浏览器窗口对象
- Navigator:浏览器对象
- Screen:浏览器所处客户端的显示器屏幕对象
- History:浏览器当前窗口的访问历史记录对象
- Location:浏览器当前窗口的地址栏对象
每个对象都有对应的属性和方法,通过这些属性和方法我们可以获取浏览器的信息。在这五个部分中,Window对象尤为重要,根据图片的区域划分,可以很清楚的看出,Window对象其中就已经包含了History,Location对象,还有一个非常重要的Document对象,但由于其重要性太高,所以前面课程我们将其单独区分出来,称为DOM对象。
而另外两个:Navigator、Screen对象,使用到的次数较少。
<!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>
ul {
list-style: none;
}
ul li {
width: 200px;
height: 40px;
border: 1px solid red;
}
</style>
</head>
<body>
<input type="text" id="content" placeholder="请输入内容:">
<input type="button" value="添加节点" id="btnAdd" onclick="Add()">
<input type="button" value="删除节点" id="btnDel" onclick="Del()">
<input type="button" value="修改节点" id="btnUpdate" onclick="Update()">
<input type="button" value="打开新的窗口" id="openNew">
<input type="button" value="关闭新的窗口" id="closeNew">
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
var Add = document.getElementById("btnAdd")
Add.onclick = function() {
// if (test()) {
if (confirm("你确定要添加吗?") == true) {
// 创建节点
var li = document.createElement("li")
// 获取文本框输入的值
var content = document.getElementById("content")
li.innerHTML = content.value
//获取ul标签
var ul = document.getElementById("list")
// 将li添加到ul中
ul.appendChild(li)
alert("添加成功")
} else {
alert("添加失败")
}
// } else {
// alert("格式不正确")
// }
}
// var newWindow //用来存储新打开的窗口
openNew.onclick = function() {
newWindow = window.open("https://ww.baidu.com")
}
closeNew.onclick = function() {
newWindow.close()
}
// 用来验证文本框输入的值得格式是不是只包含数字和字母
function test() {
// 正则表达式:只能是数字和字母,并且不能为空
var reg = /\b[a-zA-Z0-9]{1,}\b/
var content = document.getElementById("#content")
// test()返回一个布尔值:当满足正则表达式时,返回true
if (reg.test(content.value)) {
return true
} else {
return false
}
}
function Del() {
// 删除节点removeChild()
// 先获取到要删除的标签,然后在调用removeChild()
var ul = document.querySelector("ul") //获取ul标签
var li = ul.firstElementChild
ul.removeChild(li)
// ul.remove() //删除元素本身以及所有子元素
}
function Update() {
var ul = document.querySelector("ul") //获取ul标签
var li = ul.firstElementChild
li.innerHTML = "<a href=#>这是更改后的超链接</a>"
// li.innerText = "<a href=#>这是更改后的超链接</a>"
}
</script>
</body>
</html>
二、定时器
定时器:类似闹钟,在一个规定的时间或者时间周期内执行
在window对象中,与定时器相关的方法共有四个,其方法名和大致描述如下:
方法名 | 用法 |
setTimeout() | 在指定的毫秒数后调用函数或计算表达式(一次)。 |
clearTimeout() | 取消由setTimeout()方法设置的时间。 |
setlnterval() | 按照指定的周期(以毫秒计)来调用函数或计算表达式(多次)。 |
clearTimeout() | 取消由setTimeout(方法设置的时间。 |
setTimeout():指定时间后执行1次(只执行一次)
setTimeout()方法规定在指定的时间(毫秒)后执行指定的JavaScript代码,且仅执行一次。语法:
setTimeout(code ,mi17isec);
.code为指定要执行的JS代码, millisec为在执行代码前需要等待的时间(毫秒)
基本的用法为:
//在2秒后弹出一个警告框
setTimeout("alert( 'Holler ');",2000) ;
<!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>
#div0 {
width: 500px;
height: 300px;
margin: 0 auto;
text-align: center;
position: relative;
}
#div0 img {
width: 500px;
height: 300px;
}
ul {
display: flex;
justify-content: space-between;
width: 400px;
height: 30px;
position: absolute;
bottom: 0;
left: 0;
list-style: none;
}
ul li {
width: 20px;
height: 20px;
background-color: rgba(255, 255, 255, 0.661);
border-radius: 50%;
}
</style>
</head>
<body>
<div id="div0">
<img src="img/bg1.jpg" alt="">
<ul id="list">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<script>
var index = 0
function changePic() {
var arr = ["bg1.jpg", "bg2.jpg", "bg3.jpg", "bg4.jpg", "bg5.jpg", "bg6.jpg"]
// 如何获取图片
var img = document.querySelector("#div0 img")
// 更改img的src来实现图片的切换
img.src = "img/" + arr[index]
// 获取所有li标签
var list = document.querySelectorAll("#list li")
// 先将所有li上面的active进行清除
for (var i = 0; i < list.length; i++) {
list[i].classList.remove("active")
}
list[index].classList.add("active")
index++
if (index > 5) {
index = 0
}
console.log(index);
}
// 每隔1s切换一张图片,定时器
setInterval(changePic, 1000);
</script>
</body>
</html>
三、Window对象的属性
在BOM中,window对象就已经包含了大部分的对象,而通过对window对象的属性访问,同样可以获取到其他的BOM对象的引用。
以下是各个 BOM对象诵讨window对象获取的方式.:
属性名 | 描述 | 通过window对象获取方法 |
history | 对History对象的只读引用 | window.history |
location | 对Location对象的只读引用 | window.location |
navigator | 对Navigator对象的只读引用 | window .navigator |
screen | 对Screen对象的只读引用 | window . screen |
四、Location对象
location对象代表浏览器窗口中的地址栏,和window对象一样,无需特殊的创建方式,通过对象名就可使用,并调用其中的方法:
location.方法名(;//或window .1ocation.方法名();
location对象中的方法及用法如下:
方法名 | 方法描述 |
assign() | 可以打开新页面,并且可以返回,可以产生历史记录 |
reload() | 实现的是页面刷新 |
replace() | 用新文档替换当前的文档,可以实现打开新的页面的功能,但不能返回,故没有产生历史记录 |
<!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="assign" id="assign">
<input type="button" value="reload" id="reload">
<input type="button" value="replace" id="replace">
<script>
assign.onclick = function() {
//assign():可以打开新页面,并且可以返回,可以产生历史记录
location.assign("https://ww.baidu.com")
}
reload.onclick = function() {
//reload():实现的是页面刷新
location.reload()
}
replace.onclick = function() {
//replace():用新文档替换当前的文档,可以实现打开新的页面的功能,
// 但不能返回,故没有产生历史记录
location.replace("https://ww.baidu.com")
}
</script>
</body>
</html>
五、 History对象
history对象表示当前窗口的历史记录,同样通过对象名可以直接调用:
history.方法名();
history .属性名
/ /或
window.history .方法名();
window.history .属性名
在historv对象中.共有三个方法.它们分别为:
方法 | 描述 |
back() | 加载当前窗口history列表中的前一个URL。 |
forward() | 加载当前窗口history列表中的下一个URL。 |
go() | 加载当前窗口history列表中的某个具体页面。 |
- back ( )方法相当于后退按钮;
- forward ( )方法相当于前进按钮;
- -go(1代表前进1页,等价于forward( )方法;.
- go(-1)代表后退1页,等价于back()方法;
<!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>
1.html
<input type="button" value="跳转到24-2-History对象.html" id="btn">
<script>
btn.onclick = function() {
location.href = "24-2-History对象.html"
}
</script>
</body>
</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>
</head>
<body>
2.html
<input type="button" value="后退" id="btn">
<input type="button" value="跳转到24-3-History对象.html" id="btn2">
<input type="button" value="forward" id="btn3">
<input type="button" value="go" id="btn4">
<script>
btn.onclick = function() {
history.back()
}
btn2.onclick = function() {
location.href = "24-3-History对象.html"
}
btn3.onclick = function() {
history.forward()
}
btn4.onclick = function() {
history.go(1)
}
</script>
</body>
</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>
</head>
<body>
3.html
<input type="button" value="后退" id="btn">
<input type="button" value="跳转到24-1-History对象.html" id="btn2">
<script>
btn.onclick = function() {
history.back()
}
btn2.onclick = function() {
location.href = "24-1-History对象.html"
}
btn2.onclick = function() {
history.go(-2)
}
</script>
</body>
</html>
六、浏览器事件对象
事件 | 说明 |
onload() | 对象装载完成后触发 |
onscroll() | 窗口的滚动条被拖动时触发 |
onresize() | 窗口的大小改变时触发 |
onscroll()窗口的滚动条被拖动时触发的事件,
<!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 {
background-color: aqua;
}
</style>
</head>
<body>
<script>
window.onresize = function() {
var body = document.body
var w = body.clientWidth
if (w > 1200) {
body.style.backgroundColor = "red"
} else if (w > 992) {
body.style.backgroundColor = "green"
} else if (w > 768) {
body.style.backgroundColor = "yellow"
} else {
body.style.backgroundColor = "black"
}
}
</script>
</body>
</html>
七、防抖
在进行窗口的resize、scrolI、输出框内容校验等操纵的时候,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常之差。那么为了前端性能的优化也为了用户更好的体验,就可以采用防抖(debounce)和节流(throttle)的方式来到达这种效果,减少调用的频率。
函数防抖是指当一个动作连续触发,只执行最后一次。好比我们打英雄联盟或者王者荣耀的时候,比如你按下了回城键,那么在8秒钟之后,就会执行回城事件,但如果你再次按下回城键,那么回城时间又将重新计时,需要在等8秒才会执行回城事件。
函数节流是指一定时间内js方法只跑一次。好比我们打英雄联盟或者王者荣耀的时候,释放技能都有一段冷却时间,比如Q技能有5秒的冷却时间,那么我们在5秒钟的时间内只能释放一次Q技能。
例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔500ms就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次。
<!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="text" id="test">
<script>
//防抖:节约性能,只触发最后一次
/*
防抖的思路与现实:
1.事件函数执行,先创建定时器
2.把逻辑代码放到定时器中
3.当函数再次触发时,清除定时器
4.创建一个新定时器即可
*/
var timer = null
test.oninput = function() {
clearTimeout(timer)
timer = setTimeout(function() {
console.log("input")
}, 1000)
}
</script>
</body>
</html>
八、节流
节流的概念:
官方解释:当持续触发事件时,保证一定时间段内只调用一次事件处理函数。
如果持续触发事件,每隔一段时间只执行—次函数。
节流Throttle情景:
- scroll事件,每隔一秒计算一次位置信息等
- 比如我们常见的谷歌搜索框的联想功能
- 监听浏览器的滚动加载事件
- 高频鼠标点击事件(也可做防抖)
- 拖拽动画
节流的实现:
- 声明一个全局变量存储触发事件。
- 每一次触发事件,获取当前时间。
- 判断当前时间与上一次触发事件,是否超过了间隔。
- 如果超过间隔时间,则执行事件处理代码,然后存储本次触发的时间。
<!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="text" id="test">
<script>
//节流:节约性能,间隔时间,延迟触发
/*
节流的思路与实现:
1.事件函数执行,先判断有定时器,则直接return
2.把逻辑代码放到定时器中
3.定时器执行后置空定时器变量
4. 下载事件函数执行时,再创建一个新定时器即可
*/
var timer = null
test.oninput = function() {
if (timer) {
return
}
timer = setTimeout(function() {
console.log("input")
timer = null //置空定时器,让事件再次触发时,重新创建一个定时器
}, 2000)
}
</script>
</body>
</html>