BOM浏览器对象模型
通过本节学习,希望你可以掌握
能够说出什么是BOM |
---|
能够知道浏览器的顶级对象window |
能够写出页面加载事件以及注意事项 |
能够写出两种定时器函数并说出区别 |
能够说出JS执行机制 |
能够使用location 对象完成页面之间的跳转 |
能够知晓navigator对象涉及的属性 |
能够使用history提供了方法实现页面刷新 |
1. BOM概述
1.1 什么是 BOM
DOM主要包括隐藏或显示某个元素,让某一个元素的样式,内容发生变化
BOM主要包括页面条滚动,刷新页面,跳转页面
1.2 BOM的构成
新建.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>
<script>
// 1.window对象是浏览器的顶级对象
// 之前写的
// document.querySelector()
// 实际完整写法是
// window.document.querySelector()
// 2.window是一个全局对象,定义在全局作用域的变量函数都会变成window的属性和方法
var num = 10; // 此时它实际就是一个window的属性
console.log(num); // 10
// 实际完整的写法
console.log(window.num); // 10
// 定义一个函数,此时它就会变成window的方法
function fn() {
console.log(11);
}
// 以前的写法
fn(); // 11
// 实际完整的写法
window.fn(); // 10
// 3.在调用的时候可以省略window,之前学的alert(),prompt()都是window的对象方法
// alert(123);
// window.alert(123); //完整的写法
// 4.之前为什么不用name做变量名的原因 var name = 10; 不建议这样的写法
// 原因:
// 4-1 打印window
console.log(window);
// 4-2 因为window有个特殊的属性name
console.log(window.name); // 空的字符串
</script>
</body>
</html>
效果如下
2.window 对象的常见事件
2.1 窗口加载事件
(有了这个,写的script可以放在html的任意位置了)
还有一个窗口加载事件
新建.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>
<script>
// window.onload = function() {
// var btn = document.querySelector('button');
// btn.addEventListener('click',function() {
// alert('弹出对话框');
// })
// }
// window.onload = function() {
// var btn = document.querySelector('button');
// btn.addEventListener('click',function() {
// alert('弹出对话框222');
// })
// }
// 推荐写法
window.addEventListener('load', function() {
var btn = document.querySelector('button');
btn.addEventListener('click',function() {
alert('11');
})
})
window.addEventListener('load', function() {
alert('22');
})
document.addEventListener('DOMContentLoaded',function() {
alert(33);
})
// 让JS可以放到页面任何一个位置,可以用页面加载事件来处理
// 这两种页面加载事件的区别
// load 等页面内容全部加载完毕,包含页面dom元素 图片 flash css等
// DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比load更快一些 (适用图片比较多的页面)
</script>
</head>
<body>
<button>点击</button>
<!-- <script>
// 需求:点击按钮,弹出弹窗
var btn = document.querySelector('button');
btn.addEventListener('click',function() {
alert('弹出对话框');
})
</script> -->
<!-- window.onload传统注册事件只能写一次,如果有多个,会以最后一个window.onload为准 -->
</body>
</html>
效果如下
效果如下
效果如下
2.2 调整窗口大小事件
(当浏览器大小改变就会触发的事件)
新建.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>
div {
width: 200px;
height: 200px;
background-color: aquamarine;
}
</style>
</head>
<body>
<!-- 1.当div写上面时 -->
<!-- <div></div>
<script>
// 需求:让盒子小于900px的时候隐藏
var div = document.querySelector('div')
window.addEventListener('resize',function() {
// 获取此时屏幕的宽度
console.log(window.innerWidth);
if (window.innerWidth <= 800) {
div.style.display='none';
}
})
</script> -->
<script>
// 当div写任意位置时,完成上面需求
window.addEventListener('load',function() {
var div = document.querySelector('div')
window.addEventListener('resize',function() {
// 获取此时屏幕的宽度
console.log(window.innerWidth);
if (window.innerWidth <= 800) {
div.style.display='none';
} else {
div.style.display = 'block';
}
})
})
</script>
<div></div>
</body>
</html>
效果如下
3. 定时器
window对象给我们提供了2个非常好用的方法——定时器。
setTimeout()
setlnterval()
3.1 setTimeout() 定时器
window.setTimeout(调用函数,[延迟的毫秒数]);
setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。
注意:
1.window 可以省略
2.这个调用函数可以直接写函数,或者写函数名或者采用字符串 ‘函数名()’ 三种形式。第三种不推荐
3.延迟的毫秒数省略默认是0,如果写,必须是毫秒。
4.因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。
新建.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>
<script>
// 1. setTimeout
// 语法规范: window.setTimeout(调用函数,延时时间);
// 1. 这个windows在调用的时候可以省略
// 2. 这个延时时间单位是毫秒 但是可以省略 如何省略,默认是0
setTimeout(function() {
console.log('2秒后,时间到了');
},2000)
// 3.这个调用函数可以直接写函数,还可以写 函数名
function callback() {
console.log('该吃饭了');
}
setTimeout(callback,3000)
// 4.这个调用函数还有一个写法 '函数名()' 不提倡这个写法
// setTimeout('callback()',8000)
// 5.页面中可能有很多的定时器,我们经常给定时器加标识符 (名字)
function liv() {
console.log('3秒后页面跳转');
}
var time1 = setTimeout(liv,3000)
var time2 = setTimeout(liv,5000)
</script>
</body>
</html>
效果如下
上面的例子中
setTimeout()这个函数我们也称为回调函数callback
普通函数是按照代码顺序直接调用。
而这个函数,需要等待时间,时间到了才去调用这个函数,因此称为回调函数。
简单理解: 回调,就是回头调用的意思。上一件事干完,再回投再调用这个函数。
以前我们讲的 element.onclick=function() {} 或者 element.addEventListener("click",fn);里面的函数也是回调函数
3.2 案例:5秒自动关闭的广告
分析:
1.核心思路:5秒之后,就把这个广告隐藏起来
2.用定时器setTimeout
新建.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>
img {
width: 400px;
height: 400px;
}
</style>
</head>
<body>
<img src="images/1.jpg" alt="" class="ad">
<script>
var ad = document.querySelector('.ad');
setTimeout(function() {
ad.style.display = 'none';
},5000)
</script>
</body>
</html>
效果如下
3.3 停止 setTimeout() 定时器
window.clearTimeout(timeoutID);
clearTimeout() 方法取消了先前通过调用 setTimeout() 建立的定时器。
注意:
1.window 可以省略。
2.里面的参数就是定时器的标识符。
新建.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>
<button>点击停止定时器</button>
<script>
var btn = document.querySelector('button');
var timer = setTimeout(function() {
console.log('五秒之后爆炸了');
},5000);
btn.addEventListener('click',function() {
clearTimeout(timer);
})
</script>
</body>
</html>
效果如下
3.4 setInterval()定时器
window.setInterval(回调函数,[间隔的毫秒数]);
setInterval() 方法重复调用一个函数,每隔这个时间,就去调用一次回调函数
注意:
1、window 可以省略
2、这个调用函数可以直接写函数,或者写函数名或者采用字符串’函数名()'三种形式。
3、间隔的毫秒数省略默认是0,如果写,必须是毫秒,表示每隔多少毫秒就自动调用这个函数。
4、因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。
新建.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>
<script>
// 1.setInerval
// 语法规范:window.setInterval(调用函数,延时时间);
setInterval(function() {
console.log('持续输出');
},1000);
/*
setTimeout和setInterval的区别
1.setTimeout 延时时间到了,就去调用这个回调函数,只调用一次,就结束了这个定时器
2.setInterval 每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
*/
</script>
</body>
</html>
效果如下
3.5 案例:倒计时
新建.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>
div {
background-color: black;
width: 200px;
height: 200px;
margin-left: 20px;
float: left;
color: white;
font-size: 20px;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<!-- div>span*3 -->
<div>
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span></div>
<script>
// 1.获取元素
var hour = document.querySelector('.hour'); // 小时的黑色盒子
var minute = document.querySelector('.minute'); // 分钟的黑色盒子
var second = document.querySelector('.second'); // 秒数的黑色盒子
var inputTime =+ new Date('2022-11-13 00:00:00'); // 返回的是用户输入时间总的毫秒数
// 3.先调用一次这个函数,防止第一次刷新页面有空白
countDown();
// 2.开启定时器 每隔一秒调用
setInterval(countDown,1000);
function countDown() {
var nowTime = +new Date();
var times = (inputTime - nowTime) / 1000;
var h = parseInt(times /60 /60 % 24); // 时
h = h < 10 ? '0' + h : h;
hour.innerHTML = h; // 把剩余的小时 给小时的 黑色盒子
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
minute.innerHTML = m; // 把剩余的分钟 给分钟的 黑色盒子
var s = parseInt(times % 60); // 当前的秒
s = s < 10 ? '0' + s : s;
second.innerHTML = s; // 把剩余的秒 给秒的 黑色盒子
}
</script>
</body>
</html>
效果如下
3.6 停止 setInterval() 定时器
window.clearInterval(intervalID);
clearInterval() 方法取消了先前通过调用 setIntervla() 建立的定时器。
注意:
1、window可以省略。
2、里面的参数就是定时器的标识符。
新建.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>
<!-- button.begin -->
<button class="begin">开启定时器</button>
<button class="stop">停止定时器</button>
<script>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
/* begin.addEventListener('click',function() {
var timer = setInterval(function() {
console.log('持续发出消息');
},1000);
})
stop.addEventListener('click',function() {
clearInterval(timer);
})
这个代码会报错,因为此时begin里面的timer是局部变量,clearInterval()不能调用
*/
var timer = null; // 定义一个全局变量 null 是一个空对象
begin.addEventListener('click',function() {
timer = setInterval(function() {
console.log('持续发出消息');
},1000);
})
stop.addEventListener('click',function() {
clearInterval(timer);
})
</script>
</body>
</html>
效果如下
3.7 案例:发送短信
新建.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>
手机号码: <input type="number"> <button>发送</button>
<script>
// 1.获取元素
var btn = document.querySelector('button');
var time = 3; // 定义剩下的秒数 全局变量
btn.addEventListener('click',function() {
btn.disabled = true;
// 注意button的特殊之处,用innerHTML来修改内容
// 例如:btn.innerHTML = '还剩下10秒';
var timer = setInterval(function() {
if (time == 0) {
// 清除定时器和复原按钮
clearInterval(timer);
// 启用按钮
btn.disabled = false;
// 修改文字
btn.innerHTML = '发送';
// 复原原来的到时间初始时间 这个3需要重新开始
time = 3;
} else {
btn.innerHTML = '还剩下' + time + '秒';
time --;
}
},1000);
})
</script>
</body>
</html>
效果如下
3.8 this
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象
1、全局作用域或者普通函数中this指向全局对象window (注意定时器里面的this指向window)
2、方法调用中谁调用this指向谁
3、构造函数中this指向构造函数的实例
新建.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>
<button>点击</button>
<script>
// this 指向问题 一般情况下this最终指向的是那个调用它的对象
// 1.全局作用域或者普通函数中this指向全局对象window (注意定时器里面的this指向window)
console.log(this); // window
function fn() {
console.log(this); // window
}
fn();
// 实际fn()全写是 window.fn()
setTimeout(function() {
console.log(this); // window
},1000);
// 因为定时器是简写的,全称是 window.setTimeout(function() {},1000);
// 2.方法调用中谁调用this指向谁
var o = {
sayHi:function() {
console.log(this); // this指向的是 o 这个对象
}
}
o.sayHi();
// 点击按钮,查看this的指向
var btn = document.querySelector('button');
// btn.onclick = function() {
// console.log(this); // 当点击按钮后,this指向button按钮对象
// }
btn.addEventListener('click',function() {
console.log(this); // 当点击按钮后,this指向button按钮对象
})
// 3.构造函数中this指向构造函数的实例
function Fun() {
console.log(this); // this指向的是fun 实例对象
}
var fun = new Fun() // new会创建新空间,fun指向了这个新空间
</script>
</body>
</html>
效果如下
通过this的学习,可以讲发送短信代码优化
<!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="number"> <button>发送</button>
<script>
var btn = document.querySelector('button');
var time = 3;
btn.addEventListener('click',function() {
this.disabled = true; // 这里可以把btn替换成this,this指向函数调用,就是btn
var timer = setInterval(function() {
if (time == 0) {
clearInterval(timer);
btn.disabled = false; // 这里的btn不能改成this,因为这句话在定时器里,定时器里面的指向window
btn.innerHTML = '发送';
time = 3;
} else {
btn.innerHTML = '还剩下' + time + '秒';
time --;
}
},1000);
})
</script>
</body>
</html>
4. JS执行机制
4.1 JS 是单线程
JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为JavaScript这门脚本语言诞生的使命所在——JavaScript是为页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
4.2 面临的问题
<script>
console.log(1);
setTimeout(function() {
console.log(3);
},100000);
console.log(2);
</script>
4.3 同步和异步
为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker 标准,允许JavaScript脚本创建多个线程。于是,JS中出现了同步和异步。
同步
前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如:做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。
异步
在做一件事时,因为这件事会花费很长的时间,在做这件事的同时,还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜、炒菜。
同步和异步的本质区别:这条流水线上各个流程的执行顺序不同。
【提醒】虽然JS属于单线程语言,但是允许创建多个任务
新建.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>
<script>
console.log(1);
setTimeout(function() {
console.log(3);
},1000);
console.log(2);
</script>
</body>
</html>
效果如下
4.4 同步任务和异步任务执行过程
如下代码,最后的结果是多少呢?
<script>
console.log(1);
setTimeout(function() {
console.log(3);
},0);
console.log(2);
</script>
执行结果如下
同步任务和异步任务
4.5 JS的执行机制
JS的执行机制——执行多任务时
新建.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>
<script>
console.log(1);
document.onclick = function() {
console.log('click');
}
console.log(2);
setTimeout(function() {
console.log(3);
},3000)
/*
先执行同步任务,当点击之前没发生时,会先让异步进程进行处理,点击之后才会放到异步任务里面
当执行定时任务时,会先让异步进程进行处理,当过了三秒之后,才会放到异步任务里面
*/
</script>
</body>
</html>
效果如下
5.location 对象
5.1 什么是location 对象
window对象给我们提供了一个location属性用于获取或者设置窗体URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。
5.2 URL
【提醒】 href和search比较重要
5.3 location 对象的属性
5.4 案例:5秒之后跳转页面
新建.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>
<button>点击</button>
<div></div>
<script>
// 需求:5秒之后跳转页面
var btn = document.querySelector('button');
var div = document.querySelector('div');
// btn.addEventListener('click',function() {
// // console.log(window.location.href); window可以省略
// // console.log(location.href);
// location.href = 'https://www.jd.com/';
// })
var timer = 5;
// setInterval(function() {
// if (timer == 0) {
// location.href = 'https://www.jd.com/';
// } else {
// div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
// timer--;
// }
// })
// 前面有一秒空白的解决方法
k(); // 刷新页面时,有一秒的空白
setInterval(function() {
k();
},1000)
function k() {
if (timer == 0) {
location.href = 'https://www.jd.com/';
} else {
div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
timer--;
}
}
</script>
</body>
</html>
效果如下
5.5 案例:获取URL的参数数据
主要练习数据在不同页面中的传递。
新建login.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>
<form action="index.html" >
用户名:<input type="text" name="uname" value="" />
<input type="submit" name="" value="登录" />
</form>
</body>
</html>
新建index.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>
<div></div>
<script>
console.log(location.search); // ?uname=andy
// 1.先去掉? substr('起始的位置',截取几个字符);
var params = location.search.substr(1); // uname=andy
console.log(params);
// 2.利用= 把字符串分割为数组 split('=')
var arr = params.split('=');
console.log(arr); // ['uname','andy']
var div = document.querySelector('div');
// 3.把数据写入div中
div.innerHTML = arr[1] + '欢迎您';
</script>
</body>
</html>
布局如下:
效果如下
5.6 location 对象的方法
新建.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>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click',function() {
// 记录浏览历史,所以可以实现后退功能
// location.assign('https://www.jd.com/');
// 不记录浏览历史,不可以实现后退功能
// location.replace('https://www.taobao.com/')
// 重新加载页面
location.reload()
})
</script>
</body>
</html>
效果如下
6. navigator 对象
navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。
下面前端代码可以判断用户那个终端打开页面,实现跳转。
7. history 对象
window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。
history对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能 参数如果是1,前进一个页面;如果是-1,后退一个页面。 |
新建index.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>
<a href="list.html">点击 去列表页</a>
<button>前进</button>
</body>
</html>
新建list.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>
<a href="index.html">点击 去列表页</a>
<button>后退</button>
</body>
</html>
其布局如下
修改完的index.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>
<a href="list.html">点击 去列表页</a>
<button>前进</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click',function() {
// history.forward();
history.go(1);
})
</script>
</body>
</html>
修改完的list.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>
<a href="index.html">点击 去主页</a>
<button>后退</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click',function() {
// history.back();
history.go(-1);
})
</script>
</body>
</html>
示例: