Skip to content

oasis-cloud/History.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 

Repository files navigation

History.js

轻量级 HTML5 History API 封装库,暴露全局对象 hjs。在现代浏览器上包装 history.replaceState,在不支持该 API 的旧浏览器上自动降级为 #! hash 路由,并提供统一的历史变化监听入口。

特性

  • 统一 replaceState 调用入口
  • 自动处理 data 默认值({})与 title 默认值(当前 document.title
  • 旧浏览器 hash 降级(#!path 格式)
  • 防止重复初始化(global.hjs 守卫)
  • 内部维护状态列表,回调时可获取完整 state 对象

浏览器兼容性

环境 行为
支持 history.replaceState 使用原生 API + URL 轮询检测变化
不支持 history.replaceState 通过 location.href = baseUrl + '#!' + path 模拟
变化检测 固定 100ms 轮询(非原生 popstate / hashchange 事件)

快速开始

通过 <script> 标签引入(当前无 npm 包):

<script src="history.js"></script>
<script>
  hjs.replaceState({ page: 1 }, '首页', '/home');

  hjs.bind('popstate', function(state) {
    console.log(state.data, state.title, state.path);
  });
</script>

注意bind 的第一个参数 evtName 当前未被实际使用,仅为占位;回调通过 100ms 轮询触发。

API 文档

hjs.version

  • 类型string
  • 当前值'1.0.0'

hjs.replaceState(data, title, path)

替换当前历史记录条目,等效于原生 history.replaceState 的封装版本。

参数

参数 类型 说明
data object 状态对象,默认 {}
title string 页面标题,默认当前 document.title
path string 路由路径,必填,否则静默 return

返回值

  • 现代浏览器:返回递增的 subscribeId(内部索引)
  • 旧浏览器:无明确返回值(异步 hash 跳转)

副作用

  • 更新 document.title
  • { target, data, title, path } 写入内部 dataList

hjs.bind(evtName, callback)

注册历史变化监听。每 100ms 检测 URL 是否变化,变化时调用 hjs.fire(callback) 触发回调。

参数

参数 类型 说明
evtName string 事件名(占位,当前未使用)
callback function 变化时的回调函数,接收 state 对象

已知限制:多次调用会创建多个独立的 setInterval,无法取消。

hjs.fire(callback)

手动触发回调(内部方法,也可直接调用)。

  • 现代浏览器:回调接收 dataList[subscribeId](当前最新状态)
  • 旧浏览器:遍历 dataList,对 path 与当前 hash 匹配的项逐一触发回调

回调 state 对象结构

{
  target: window,   // 全局对象
  data: {},         // replaceState 传入的 data
  title: '...',     // 页面标题
  path: '/xxx'      // 路径
}

使用示例

基础用法

// 替换当前历史记录
hjs.replaceState({ id: 1 }, '页面标题', '/page/1');

// 监听历史变化
hjs.bind('popstate', function(state) {
  console.log('当前状态:', state);
  console.log('数据:', state.data);
  console.log('标题:', state.title);
  console.log('路径:', state.path);
});

简化调用(来自源码注释)

hjs.replaceState('test', 'test title', '/2');

使用注意事项

  • 仅实现了 replaceState,尚未实现 pushState
  • 变化监听基于 100ms 轮询,存在性能开销与最多 100ms 的触发延迟
  • 旧浏览器降级使用 #!(bang hash),而非常见的 #/ 格式
  • 代码中声明了 uri 变量但未使用;parseUrl() 已在源码中注释,尚未实现
  • package.json,当前仅支持 script 标签引入

扩展方向

以下功能可按优先级继续扩展:

高优先级 — 补齐 History API 核心能力

扩展项 现状 建议
pushState 未实现 参照 replaceState 实现,旧浏览器可用 hash 栈或 history 长度模拟
原生事件监听 使用 100ms 轮询 现代浏览器绑定 popstate;旧浏览器绑定 hashchange,轮询作兜底
go / back / forward 未实现 封装 history.go(n),旧浏览器需维护内部 history 栈

中优先级 — API 易用性与健壮性

扩展项 现状 建议
parseUrl() 源码中已注释 恢复并暴露为 hjs.parseUrl(),解析 protocol / hostname / path / search / hash
unbind / 单次监听 多次 bind 无法取消 返回 listener id,支持 off(id);避免重复 setInterval
getState() 无公开读取接口 暴露当前 dataList[subscribeId] 或从 history.state 读取
参数校验与错误提示 path 无效时静默 return 开发模式下 console.warn,生产模式保持兼容

低优先级 — 工程化与生态

扩展项 现状 建议
模块化导出 仅 IIFE 挂 window.hjs 支持 UMD / ESM / CommonJS
TypeScript 类型 添加 hjs.d.ts
单元测试 使用 jsdom + 测试框架覆盖现代 / 降级两条路径
构建与发布 无 package.json 添加 npm 包、版本管理与 CI
hash 格式可配置 硬编码 #! 支持 #/ 或自定义 prefix
与前端路由框架集成 独立库 提供 React Router / Vue Router 适配示例

已知待修复问题

  1. 旧浏览器 fire 逻辑:循环中可能对多个历史项重复触发回调,应只匹配当前 hash 最新项
  2. bind 内存泄漏:每次调用新建 interval,无清理机制
  3. replaceState 旧浏览器分支:未返回 subscribeId,与现代浏览器行为不一致

许可证

请查阅仓库根目录的 LICENSE 文件(如有)。

About

History.js

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors