HTML5 history api

前言

由于笔者在网络上没有找到比较好的关于 history api 的实践案例,有的案例过于杂乱,没有重点,有些案例只是告诉读者 api 是什么,却没告诉怎么用,本文章从零开始带读者实践 history api ,建议和笔者一起写一遍。

效果

注意 url 变化,另外用到了 虎裤里老师 和 狼大老师 的图,侵权马上删。

流程

  1. html 部分

    需要引入 jquery

<!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" />
<link rel="stylesheet" href="./index.css" />
<script src="./jquery.js"></script>
<script src="./index.js"></script>
<title>history html5</title>
</head>
<body>
<div class="row">
<button data-id="1" data-name="tiger" class="btn">来一只虎虎</button>
<button data-id="0" data-name="cow" class="btn">来一只牛牛</button>
</div>
<div class="row">
<img class="image" />
</div>
</body>
</html>
  1. css 部分
.row {
display: flex;
justify-content: space-around;
} .image {
width: 25%;
height: 25%;
padding: 20px;
cursor: pointer;
}
  1. 等待页面 dom 加载完毕再执行 JS
window.onload = () => {
// ...
}
  1. 获取 btn 添加事件

    获取请求所需的 id 以及界面需要展示的 url 路径

  const btns = document.querySelectorAll(".btn");
btns.forEach(btn => {
const dataId = btn.getAttribute("data-id"); // 请求 id
const dataName = btn.getAttribute("data-name"); // 页面 url 路径 btn.addEventListener("click", () => {
// ...
});
});
  1. 模拟网络请求

    接上方的代码,这里的话我写了一份模拟数据

{
"images": [
"./images/牛牛.jpg",
"./images/虎虎.jpg"
]
}

​ 并在对应文件夹下存放了图片,接下来进行 ajax 网络请求

btn.addEventListener("click", () => {
$.ajax({
url: "./mock/mock.json",
success: (res) => {
const { images } = res;
const state = images[dataId];
displayContent(state); // 接下来会提到这个函数
history.pushState(state, null, dataName); // 接下来会提到这个函数
},
});
});

​ 这里的话,一般来说是传入 id 给服务端返回一个图片的 url 由于为了实现简单,全部返回后,根据先前从 dom 属性上获得的 dataId 获取图片的 url

  1. 根据获得的 url 进行展示
const image = document.querySelector(".image");
const displayContent = (src) => {
image.setAttribute("src", src);
};
  1. 页面变化后,利用 html5 history api 进行修改页面地址,并传入 state
history.pushState(state, null, dataName);

其中第一个参数后面有个监听事件会用到,而第二个参数代表标题,没必要传,第三个参数是路径。

如果当前路径是 /history 则如果传入的路径是 cow 则会变成 /history/cow

经过上面的几个步骤,已经成功完成了利用按钮切换界面的时候,展示不同的图片信息。

这个时候,如果点击返回或者页面的前进按钮,跳转到上一页或下一页,是无法显示网页信息的。

  1. 前进后退显示网页信息
window.addEventListener("popstate", (e) => {
const { state } = e;
if (state) displayContent(state);
});

这里的 state 就是前面 pushState 传的 state,可以根据这个 state 渲染当前界面,这就保证了在前进后退的时候渲染对应的图像。

这个时候当我们点击前进和后退的时候,基本是已经可以展示对应的界面的,这样非常好,但是仍然有个问题,当后退到第一个界面的时候,没有数据

  1. 替换第一个界面的数据
 history.replaceState("./images/虎虎.jpg", null, location.href);
image.setAttribute("src", "./images/虎虎.jpg");

这里的话,把第一个界面的数据补充上,其实一般都是经过网络请求的,这里省略了。现在还存在一个问题,如果跳到某个界面后,刷新,可能会出现获取不到资源的情况。

这很正常,例如我们在 /history 下有一个 index.html 文件,那么访问 /history 是可以直接访问到这个文件的,但是当我们通过上述方法跳转路由的时候 /history/cow 并不存在 index.html 文件,这意味刷新界面后获取不到对应的资源了,这个时候上线后还需要 nginx 的辅助配置

  1. 通过 nginxurl rewrite 配置,使得总是命中 history/

总结

不知道大家有没有用过之前的 vue router 里面如果开启了 mode: history 的话,最后还要通过 nginx 进行辅助配置,可能就是这个原理。

一篇文章图文并茂地带你轻松实践 HTML5 history api的更多相关文章

  1. 一篇文章图文并茂地带你轻松学会 HTML5 storage

    html5 storage api localStorage 和 sessionStorage 是 html5 新增的用来存储数据的对象,他们让我们可以以键值对的形式存储信息. 为什么要有 stora ...

  2. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(一)

    JavaScript 设计模式(一) 本文需要读者至少拥有基础的 ES6 知识,包括 Proxy, Reflect 以及 Generator 函数等. 至于这次为什么分了两篇文章,有损传统以及标题的正 ...

  3. 一篇文章图文并茂地带你轻松学完 JavaScript 设计模式(二)

    JavaScript 设计模式(二) 本篇文章是 JavaScript 设计模式的第二篇文章,如果没有看过我上篇文章的读者,可以先看完 上篇文章 后再看这篇文章,当然两篇文章并没有过多的依赖性. 5. ...

  4. 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)

    JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...

  5. 一篇文章图文并茂地带你轻松学完 JavaScript 继承

    JavaScript 继承 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 继承种类 简单的继承种类可以分为 构造函数继承 原型链继承 clas ...

  6. 一篇文章图文并茂地带你轻松学完 JavaScript 原型和原型链

    JavaScript 原型和原型链 在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 . 本篇文章旨在为 JavaScript继承 打下基础 原型 在 ...

  7. 一篇文章图文并茂地带你轻松学完 JavaScript 闭包

    JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过 ...

  8. 一篇文章搞定百度OCR图片文字识别API

    一篇文章搞定百度OCR图片文字识别API https://www.jianshu.com/p/7905d3b12104

  9. HTML5 history API实践

    一.history API知识点总结 在HTML4中,我们已经可以使用window.history对象来控制历史记录的跳转,可以使用的方法包括: history.forward();//在历史记录中前 ...

随机推荐

  1. 基于Dockfile构建JAVA环境网站镜像

    查看本地目录 [root@docker tomcat]# ls apache-tomcat-8.5.16.tar.gz  Dockerfile  jdk-8u91-linux-x64.tar.gz   ...

  2. Array.of使用实例

    Array.of是es6新增的API,其实粗暴点理解,光看of,就可以猜到它是数组的意思,所以猜测可以用来把字符串转换成数组. 像这样的table,有批量删除和单个删除的功能,,但是又不想写两个方法, ...

  3. Py层次递进与文件修改大程序,模块,name与file

    层次的递进与返回 #输入quit的时候返回上一阶层,输入exit退出所有的循环 tag=True while tag==True: level1=input('level1:') if level1= ...

  4. ORM动态表达式树查询

    前言 接口获取参数后,创建返回值模型的条件表达式作为参数,传入使用依赖注入实例化后的业务层. 业务层创建返回值模型的IQUERY后,再使用参数条件表达式.最后进行延迟查询. 代码实现 参数模型Demo ...

  5. Spring-01-事务

    Spring事务机制 spring事务机制最重要的两个配置项,隔离级别和传播特性. 1. 隔离级别 隔离级别针对高并发问题导致的数据库丢失更新问题 1.1 数据库的4大基本特征 原子性(Atomic) ...

  6. Python+Selenium+Unittest实现PO模式web自动化框架(2)

    1.Common目录下的具体模块讲解. 2.basepage.py basepage.py模块里面是封装的对元素的操作.例如:查找元素.点击元素.文本输入等等. # --^_^-- coding:ut ...

  7. selenium八大元素定位方法

    1.ID定位 可以根据元素的id来定位属性,id是当前整个HTML页面中唯一的,所以可以通过id属性来唯一定位一个元素,是首选的元素定位方式.(动态ID不做考虑) # 导入webdriver和By f ...

  8. tcpdump安装与参数详解

    Centos7安装Tcpdump 对于大部分的Linux操作系统,已经默认安装了tcpdump,可以通过以下命令查看: [root@localhost local]# tcpdump --versio ...

  9. Dubbo 最基本的几个需求

    需求 http://dubbo.apache.org/zh-cn/docs/user/preface/requirements.html 在大规模服务化之前,应用可能只是通过 RMI 或 Hessia ...

  10. 奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术

    奇艺iOS移动端网络优化实践 | 请求成功率优化篇 原创 Charles 爱奇艺技术