当前位置: 首页 > news >正文

自己搓一个网页路由管理

实现流程

在<body>中动态添加<f-body>元素, 只显示(style.display)最上方的一个<f-body>

index.html

<!doctype html>
<html lang="zh-cn">
<head><meta charset="UTF-8" /><title>Awesome Capacitor App</title><meta name="viewport"content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /><meta name="format-detection" content="telephone=no" /><meta name="msapplication-tap-highlight" content="no" /><link rel="icon" type="image/x-icon" href="./assets/icon/favicon.ico" /><link rel="png" type="image/png" href="./assets/imgs/logo.png" /><link rel="manifest" href="./manifest.json" /><link rel="stylesheet" href="./css/style.css" /><meta name="theme-color" content="#31d53d" />
</head><body></body>
<script src="./js/index.js" type="module"></script>
</html>

index.js

/**伪页面历史记录管理类 更新时会访问 fbody.fupdate 函数* 调用push(bodyID)加载新页面* 调用pop()返回上一个f-body*/
class PageHistory {data = []push(bodyID) {if (this.data.length > 1) this.data[this.data.length - 1].scrollY = document.documentElement.scrollTop;let res = this.data.push({bodyID: bodyID,scrollY: 0,});console.log("添加伪页面历史:" + bodyID);document.documentElement.scrollTop = 0;this.updatePage();return res;}pop() {if (this.data.length == 0) return;let res = this.data.pop();let ele = document.querySelector("body>f-body#" + res.bodyID);ele?.remove();  // 真正释放内存console.log("删除伪页面历史:" + res.bodyID);this.updatePage();}updatePage() {for (let i = 0; i < this.data.length; i++) {const element = this.data[i];let qbody = document.querySelector('body>f-body#' + element.bodyID);if (!qbody) {console.log("伪页面历史<" + element.bodyID + ">因元素不存在而被删除");this.data.splice(i, 1);i--;continue;}qbody.style.display = "none";}if (this.data.length >= 1) {let history_item = this.data[this.data.length - 1];let qbody = document.querySelector('body>f-body#' + history_item.bodyID);qbody.style.display = "";if(qbody.fupdate) qbody.fupdate();document.documentElement.scrollTop = history_item.scrollY;}}
}
// 暴露pageHistory到主window下
window.pageHistory = new PageHistory();/**加载伪页面文件(位置: ./fakepage/xxx.html)并构建为shadow-root, 隔离css和js环境* 加载文件并构建带有唯一ID的<f-body>元素, 然后加入到document.body下  * 自动记录伪页面历史  * 自动执行fname文件中<script class="script">元素中的代码  * @param {string} fname 文件名称, 不带路径* @param {string} pageID 唯一页面id, 作为伪页面历史的标识* @param {*} data 附加到 shadow-root.data 上的数据, 可为空* @returns shadow-root: 加载的dom元素(shadow-root)*/
async function loadFakePage(fname, pageID, data) {pageID = pageID + "-" + (new Date() - 0);// if (document.querySelector('body>f-body#' + pageID) !== null) {//   console.error("页面ID<" + pageID + ">已存在!");// }const ele = document.createElement('f-body');ele.id = "" + pageID;const res = ele.attachShadow({ mode: 'open' });res.data = data;let resp = await ((await fetch('./fakepage/' + fname)).text());res.innerHTML = resp;document.body.appendChild(ele);pageHistory.push(pageID);const pageScript = res.querySelector('script.script')?.innerText;if (pageScript) (new Function('fbody', pageScript))(res);return res;
}

示例 fakepage

<style>:host {width: 100vw;user-select: none;text-align: center;&>h1 {font-size: 4em;}&>button {font-size: 2em;margin: 5vw;width: 90vw;}}
</style>
<h1>主页面</h1>
<button class="enter">测试按钮</button>
<script class="script">function pageLoad() {let btn = document.createElement('button');btn.innerText = "testing";btn.onclick = () => {fbody.querySelector('h1').innerText = "测试中...";btn.disabled = true;setTimeout(() => {loadFakePage('home.html', 'home');}, 1000);};};pageLoad();
</script>
http://www.jsqmd.com/news/1050547/

相关文章:

  • 基于循环一致性的无监督搜索智能体:原理、实现与调参指南
  • BUUCTF:[HCTF 2018]admin 三种解法背后的Web安全攻防启示
  • 2026更新!陕西汉中叛逆青少年厌学戒网瘾托管机构推荐排名一览(家长必看,避坑指南) - 辛云教育资讯
  • 长途托运摩托车哪家更稳妥?四大整合快运渠道安全、运费、时效、上门服务全方位对比 - 时讯资讯
  • 为Windows 11 LTSC企业版恢复微软商店:3分钟完整解决方案
  • Python+Pytest+Requests+Allure构建电商API自动化测试框架实战
  • 2026年6月最新芝柏中国官方售后电话网点地址及客户服务热线 - 亨得利官方服务中心
  • 孩子叛逆厌学、沉迷手机?黄山 2026 十大戒网瘾特训学校权威榜单,正规封闭军事化,帮娃迷途知返! - 辛云教育资讯
  • ANSYS Workbench循环对称分析实战:从Cyclic Region到Pre-Meshed的避坑指南
  • SERP API + LangChain:10 行代码做实时搜索 Agent 背景
  • 3步解锁:零门槛搭建你的私人三国杀游戏平台
  • 河源家政哪家好?2026河源正规家政推荐+避坑攻略 - 资讯速览
  • 2026 CISSP/CISP备考实战:考纲变动梳理、知识图谱搭建与全套资源清单
  • 北京平谷刑事律所推荐:如何筛选合适刑事辩护律师团队 - 品牌2026
  • 如何轻松退出Windows预览版:OfflineInsiderEnroll终极解决方案指南
  • TSN实战:基于NXP LS1028A的Qbv、Qci、Qav与802.1CB全配置指南
  • 抖音无水印下载终极指南:三步免费获取高清视频的完整教程
  • 2026年陕西商洛叛逆青少年管教学校十大“实力派”榜单出炉! - 辛云教育资讯
  • Autosar CAN开发实战:从接线到通讯,物理层避坑指南
  • 鸿蒙 Flutter 项目打 debug、profile、release 包时分别要检查什么
  • 2026扬州最靠谱汽车贴膜店,性价比高到离谱! - 资讯速览
  • 黄石家长紧急收藏!2026湖北黄石市十大叛逆学生厌学网瘾戒除特训学校权威名单一览 - 辛云教育资讯
  • 深圳居家户型差异化隔音怎么做?|静华轩隔音窗|儿童房/书房/主卧/老人房/电竞房分区降噪,适配全家作息隔音定制 - 维小达科技
  • 显卡驱动彻底清理:DDU深度卸载工具的完整教程与系统维护哲学
  • 5分钟掌握B站视频下载:新手也能轻松获取4K大会员专属内容
  • 装修小白适合积木家装修吗?看懂报价、材料和合同再决定 - 资讯速览
  • 【2027最新】基于SpringBoot+Vue的个人理财系统管理系统源码+MyBatis+MySQL
  • 欧洲卡航哪家专业靠谱 - 资讯速览
  • 从FAB工艺到IC验证:一位材料人的跨界转型实战录
  • 2026厦门GEO优化服务商选型指南:艾奇GEO及主流服务商专业适配分析 - 万事通达