如何使用 JavaScript 操作浏览器历史记录 API


Posted in Javascript onNovember 24, 2020

History 是 window 对象中的一个 JavaScript 对象,它包含了关于浏览器会话历史的详细信息。你所访问过的 URL 列表将被像堆栈一样存储起来。浏览器上的返回和前进按钮使用的就是 history 的信息。

History 对象包含长度属性,它包含了会话历史记录栈中的 URL 数量。例如,如果用户在浏览器中打开一个标签页,历史记录的长度将是 1(新的标签页也是一个网页)。然后用户输入一个网址 foo.com 并点击回车,现在历史记录对象的长度将是 2, 用户转到其他页面 bar.com,历史记录对象的长度将就是 3 了。

Back 和 Forward 方法

你可以使用 history 对象的 back 和 forward 方法来浏览网页。例如,如果你想转到上一个页面,那么可以使用:

history.back()

同样的,如果你想转到下一页,你可以使用:

history.forward()

Go 方法

如果您想向前或向后移动 n 个页面,那么您可以使用 go 方法:

history.go(-2) // 倒退 2 页
history.go(2) // 前进 2 页

所以 history.go(1) 和 history.forward() 效果是相同的,history.go(-1) 和 history.go(-1) 效果是相同的。history.go 方法的默认值为 0,如果不传任何数字,则当前页面会被刷新。

window.history.go(0)
window.history.go()

PushState

你也可以使用 pushState 和 replaceState 方法改变页面的 URL。pushState 会改变页面的 URL,并将改变后的 URL 添加到 history 对象的 URL 栈顶部。语法如下:

history.pushState(state, title, url)

参数 state 是状态数据,它将被存储在 history.state 变量中。参数 title 是标题文本,不过它对大多数浏览器都没有效果,所以一般传空字符串("")或传 null 就可以了。

让我们在控制台中尝试一下,在执行之前,比如打开 baidu.com,然后在控制台输入:

history.pushState('123', '', 'new-url')

执行上面的代码后,它会将页面地址栏中的 URL 改为 baidu.com/new-url,同时将 URL 添加到 history 对象中。此时检查 history.length 会增加 1。

除此之外,我们还可以为每个 URL 存储状态(当前页面的数据)。在上面的例子中,你会把 "123" 存储在 history.state 变量中,当你返回到这个页面时,你就可以 history.state 再次拿到到这些数据。例如:

history.pushState('temp data 1', 'title', 'new-url-1')
history.state //"temp data 1"
history.pushState('temp data 2', 'title', 'new-url-2')
history.state //"temp data 2"
history.back()
history.state // "temp data 1"

每当通过 pushState 返回到之前被添加到历史记录的页面时,浏览器就会触发一个名为 popstate 的事件,并将 state 数据作为参数。比如在浏览器打开一个新标签页,进入某个网页(比如 baidu.com),先监听 popstate 事件:

window.addEventListener('popstate', (e) => console.log(e))

然后调用 pushState:

history.pushState({ name: 'test1' }, 'title', 'test1')

然后按下返回按钮,popstate 事件就会被触发,你可以在监听事件中查看打印出来的数据。在打印的数据中,可以找到 history.state 的值。

注册 pushState 中的 url 可以是完整的 url,但必须和当前页面是相同的域名,否则会抛出跨域异常。

浏览器还有一个 replaceState API,和 pushState 的区别是,它只改变了 URL,不会将 URL 添加到历史记录,这里就不再累述了。

实例演示

现在我们做一个小的网页应用,这个应用将实现如下功能:

  1. 显示用户列表
  2. 可以通过下拉框筛选“先生”和“女士”
  3. 当下列列表发生变化时,URL 也会相应的变化

我们先不关心 history API,先实现功能。下面是 html 关键代码:

<select id="selectbox">
 <option value="both">全部</option>
 <option value="male">先生</option>
 <option value="femalt">女士</option>
</select>
<ul id="userslist">
 <li gender="male">张先生</li>
 <li gender="female">李女士</li>
 <li gender="female">王女士</li>
</ul>

下面是 javascript 关键代码:

let selectBox = document.getElementById('selectBox')
let usersList = document.getElementById('usersList')

selectBox.addEventListener('change', onSelectBoxChange)

function onSelectBoxChange(ev) {
 let val = this.value
 filterList(val)
}

function filterList(val) {
 let users = usersList.children
 for (let i = 0; i < users.length; i++) {
  let user = users[i]
  let gender = user.getAttribute('gender')
  if (gender === val || val === 'both') {
   user.style.display = ''
  } else {
   user.style.display = 'none'
  }
 }
}

实现后的效果如下:

如何使用 JavaScript 操作浏览器历史记录 API

当修改下拉列表时,为了使浏览器地址也发生变化,需要使用 pushSate 方法:

function onSelectBoxChange(ev) {
 let val = this.value
 filterList(val)
 history.pushState({ gender: val }, null, val)
}

如何使用 JavaScript 操作浏览器历史记录 API

此时会有个问题,当我们点击前进/后退时,浏览器地址变了,但对应的数据却不对。因此,当进行前进/后退时,我们需要监听 popstate 重新过滤数据:

window.addEventListener('popstate', onPopState)
function onPopState(ev) {
 let state = ev.state
 filterList(state.gender)
}

我们还需要处理页面刷新的问题。当刷新页面时,历史记录不会改变,history.state 的状态值也保持不变。所以我们可以从 history.state 中取出当前的状态数据,利用 state.gender 的值就可以在 load 事件中来过虑出当前 URL 对应的用户列表:

window.addEventListener('load', function () {
 let gender = history.state ? history.state.gender : 'both'
 filterList(gender)
})

这是个简单的示例,你也可以继续进一步优化。今天的分享就到这里,有问题请在下面留言哦~~

以上就是如何使用 JavaScript 操作浏览器历史记录 API的详细内容,更多关于JavaScript 操作历史记录api的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
javascript Deferred和递归次数限制实例
Oct 21 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
Jun 23 Javascript
Angular2+国际化方案(ngx-translate)的示例代码
Aug 23 Javascript
js+html5生成自动排列对话框实例
Oct 09 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
Oct 16 Javascript
vue2.0在没有dev-server.js下的本地数据配置方法
Feb 23 Javascript
Vue+axios实现统一接口管理的方法
Jul 23 Javascript
javascript闭包的使用之按钮切换功能
Aug 30 Javascript
动态内存分配导致影响Javascript性能的问题
Dec 18 Javascript
Vue 3.0双向绑定原理的实现方法
Oct 23 Javascript
Vue+Element-UI实现上传图片并压缩
Nov 26 Javascript
vue+iview使用树形控件的具体使用
Nov 02 Javascript
JavaScript实现鼠标移入随机变换颜色
Nov 24 #Javascript
原生js实现表格循环滚动
Nov 24 #Javascript
浅析VUE防抖与节流
Nov 24 #Vue.js
解决vue页面刷新,数据丢失的问题
Nov 24 #Vue.js
Js利用正则表达式去除字符串的中括号
Nov 23 #Javascript
jQuery实现动态操作table行
Nov 23 #jQuery
JavaScript前后端JSON使用方法教程
Nov 23 #Javascript
You might like
PHP三元运算的2种写法代码实例
2014/05/12 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
详解PHP实现执行定时任务
2015/12/21 PHP
WordPress中给媒体文件添加分类和标签的PHP功能实现
2015/12/31 PHP
解析PHP之提取多维数组指定列的方法
2017/01/03 PHP
利用PHP判断是否是连乘数字串的方法示例
2017/07/03 PHP
THINKPHP5.1 Config的配置与获取详解
2020/06/08 PHP
使用jQuery简化Ajax开发 Ajax开发入门
2009/10/14 Javascript
form表单中去掉默认的enter键提交并绑定js方法实现代码
2013/04/01 Javascript
JavaScript中对象property的删除方法介绍
2014/12/30 Javascript
jquery插件ajaxupload实现文件上传操作
2015/12/09 Javascript
Js与Jq获取浏览器和对象值的方法
2016/03/18 Javascript
webpack入门必知必会
2017/01/16 Javascript
微信小程序 滚动到某个位置添加class效果实现代码
2017/04/19 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
jquery一键控制checkbox全选、反选或全不选
2017/10/16 jQuery
angular使用md5,CryptoJS des加密的方法
2019/06/03 Javascript
微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析
2019/08/16 Javascript
javascript合并两个数组最简单的实现方法
2019/09/14 Javascript
vue.js实现只能输入数字的输入框
2019/10/19 Javascript
vue+node 实现视频在线播放的实例代码
2020/10/19 Javascript
Python群发邮件实例代码
2014/01/03 Python
Python实现两款计算器功能示例
2017/12/19 Python
基于Python开发chrome插件的方法分析
2018/07/07 Python
django解决订单并发问题【推荐】
2019/07/31 Python
HTML5制作酷炫音频播放器插件图文教程
2014/12/30 HTML / CSS
俄罗斯街头服装品牌:Black Star Wear
2017/03/01 全球购物
加拿大最大的钻石商店:Peoples Jewellers
2018/01/01 全球购物
澳大利亚网上买书:Angus & Robertson
2019/07/21 全球购物
经济管理专业自荐信
2013/12/30 职场文书
环保小标语
2014/06/13 职场文书
2014班子成员自我剖析材料思想汇报
2014/10/01 职场文书
交通事故赔偿协议书
2014/10/16 职场文书
中学生社区服务活动报告
2015/02/05 职场文书
个人房屋租赁合同(标准范本)
2019/09/16 职场文书
MySQL 原理与优化之原数据锁的应用
2022/08/14 MySQL