前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HTML 面试要点:History 和 Hash 路由方式

HTML 面试要点:History 和 Hash 路由方式

作者头像
Cellinlab
发布2023-05-17 16:07:34
7450
发布2023-05-17 16:07:34
举报
文章被收录于专栏:Cellinlab's BlogCellinlab's Blog

# 为什么要使用路由

越来越多的应用使用 Ajax 请求数据,浏览器 URL 不会发生任何变化。同时,浏览的页面内容在用户下次使用 URL 访问时将无法重新呈现,使用路由可以很好地解决这个问题。

单页面利用了 JavaScript 动态变换网页内容,避免了页面重新加载;路由这提供了浏览器地址变化,网页内容页跟随变化,两个结合提供了体验良好的 单页面应用。

# 前端路由实现方法

路由需要实现以下功能:

  1. 当浏览器地址变化时,切换页面;
  2. 点击浏览器【后退】、【前进】按钮时,网页内容跟随变化;
  3. 刷新浏览器,网页加载当前路由对应的内容。

在单页面 web 网页中,单纯的浏览器地址改变,网页不会重载,如单纯的 hash 网址改变网页不会变化,因此路由主要通过监听事件,并利用 JavaScript 实现动态改变网页内容,有以下实现方法:

  • hash 模式: 监听浏览器地址 hash 值变化,执行相应的 JavaScript 切换网页
  • history 模式:利用 history API 实现 URL 变化,网页内容跟随变化

二者的区别是 hash 会在浏览器地址后面增加 #,而 history 可以自定义地址。

# hash 模式

使用 window.location.hash 属性及窗口的 onhashchange 事件 (opens new window),可以实现监听浏览器地址 hash 值变化,执行相应的 JavaScript 切换网页。一些需要注意的地方:

  • hash 指地址中 # 以及后面的字符,也叫散列值
    • 也叫 锚点,本身是用来做页面跳转定位的,如 https://cellinlab.xyz/#/home 的 hash 即 #/home
  • 散列值不会随请求发送到服务器端,所以改变 hash,不会重新加载页面
  • 监听 windowhashchange 事件,当散列值改变时,可以通过 location.hash 来获取和设置 hash 值
  • location.hash 值的变化会直接反应到浏览器的地址栏

# 触发 hashchange 的情况

  • 浏览器地址散列值的变化(包括浏览器的前进、后退)会触发 window.location.hash 值的变化,从而触发 onhashchange 事件
  • 当浏览器地址栏中 URL 包含 哈希 如 https://cellinlab.xyz/#/home,此时按下回车,浏览器发送 https://cellinlab.xyz/ 请求到服务器,请求完毕之后设置散列值为 #/home,此时触发 onhashchange 事件
  • 当值改变浏览器地址栏 URL 的哈希部分,按下回车,浏览器不会发送任何请求到服务器,只是设置散列值修改,并触发 onhashchange 事件
  • html<a> 标签的属性 href 可以设置为页面的元素 ID 如 #top,当点击链接时页面跳转到该 ID 元素所在区域,同时浏览器自动设置 window.location.hash 属性,地址栏中的哈希值也会发生变化,并触发 onhashchange 事件
代码语言:javascript
复制
window.location.hash = 'home';
let hash = window.location.hash; // '#home'

window.addEventListener('hashchange', function () {
  console.log('hashchange');
});

# history 模式

# 概述

  • window.history 属性指向 History 对象 (opens new window),它表示当前窗口的浏览历史,当发生改变时,只会改变页面的路径,不会刷新页面
  • History 对象保存了当前窗口访问过的所有页面网址,可以通过 history.length 获知当前窗口访问过的页面数量
  • 由于安全原因,浏览器不允许脚本读取这些地址,但允许在地址之间跳转
  • 浏览器工具栏的 “前进” 和 “后退” 按钮,其实就是对 History 对象进行操作

# 属性

History 对象主要有两个属性:

  • History.length 当前窗口访问过的页面数量(含当前页面)
  • History.state History 堆栈最上层的状态值
代码语言:javascript
复制
history.length; // 1

history.state; // undefined

# 方法

  • History.back() 移动到上一个网址,相当于点击浏览器后退键,该方法对于第一个访问的页面无效
    • 注意移动到以前访问的页面时,页面通常是从浏览器缓存中加载,而不是重新请求服务器发送新的网页
  • History.forward() 移动到下一个网址,相当于点击浏览器前进键,该方法对于最后一个访问的页面无效
  • History.go() 接收一个整数作为参数,以当前网址为基准,移动到参数指定的网址
    • 如果参数超过实际存在的网址范围,该方法无效果
    • 如果不指定参数,默认参数为 0,相当于刷新当前
代码语言:javascript
复制
history.back();
history.forward();
history.go(1); // 相当于 history.forward()
history.go(-1); // 相当于 history.back()
history.go(0); // 相当于刷新当前页面

History.pushState() 用于在历史中添加一条记录

  • pushState() 不会触发页面刷新,只是导致 History 对象发生变化,地址栏会有变化
  • history.pushState(obj, title, url)
    • obj 一个对象,通过 pushState 可以将该对象内容传递到新页面中,不需要是可以填 null
    • title 指标题,但多数浏览器不支持,建议传空字符串
    • url 新的网址,必须与当前页面处于同一个域,不指定的话则为当前路径,如果设置一个跨域网址会报错
代码语言:javascript
复制
const data = { foo: 'bar' };
history.pushState(data, '', '/about.html');
console.log(history.state); // { foo: 'bar' }

  • 注意:如果 pushState 的 URL 参数设置了一个新的锚点值(即 hash),并不会触发 hashchange 事件。相反,如果 URL 的锚点值变了,会在 History 对象创建一条浏览记录。
  • 如果 pushState() 方法设置了一个跨域网址,会报错

History.replaceState() 用来修改 History 对象的当前记录,用法与 pushState 相同

popstate() 每当 History 对象出现变化时,就会触发 popstate 事件

  • 仅仅调用 pushState() 方法或 replaceState() 方法,并不会触发该事件
  • 只有用户点击浏览器倒退按钮或前进按钮,或者使用 JavaScript 调用 history.back()history.forward()history.go() 方法,才会触发该事件
  • 该事件只针对同一个文档,如果浏览历史的切换导致加载不同的文档,该事件不会触发
  • 页面第一次加载时,浏览器不会触发 popstate 事件
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/2/25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 为什么要使用路由
  • # 前端路由实现方法
  • # hash 模式
    • # 触发 hashchange 的情况
    • # history 模式
      • # 概述
        • # 属性
          • # 方法
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档