JS 刷新保持iframe页面并支持浏览器前进后退

news2024/11/15 19:27:29

参考资料

  1. html5新特性:利用history的pushState等方法来解决使用ajax导致页面后退和前进的问题
  2. 击按钮切换iframe的src,这个路径如何不会被记录到history中?
  3. iframe 后退 浏览器history 问题
  4. ajax与HTML5 history pushState/replaceState实例

目录

  • 一. 遇到的问题
  • 二. 问题分析
  • 三. 代码示例
  • 四. 代码分析
  • 五. 效果


一. 遇到的问题

我们使用iframe嵌套自己系统的页面,但是浏览器刷新之后,无法保持当前打开的页面

在这里插入图片描述


二. 问题分析

⏹原因
之所以会刷新页面后无法保持住当前打开的页面,是因为浏览器地址栏的url始终是固定的,我们打开的页面改变的是iframe标签的src属性值,从而实现不同页面之间的切换。

⏹解决
在url的后面添加?name=当前画面id,当我们进入页面之后,根据name的参数值,来改变iframe标签,从而实现刷新后页面保持。


三. 代码示例

⏹登录页面,点击后登录到系统的首页

<!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">
    <title>Document</title>
</head>
<body>
    <button id="login">点击登录系统</button>
</body>
<script>
    login.addEventListener("click", function() {
        location.replace("./03-2-系统页面.html?name=home");
    });
</script>
</html>

⏹主系统页面

<!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">
    <style>
        #contanier {
            display: flex;
            justify-content: space-between;
        }
        iframe {
            /* 根据视口的宽度和高度计算iframe的宽和高 */
            width: calc(100vw - 150px);
            height: calc(100vh - 30px);
        }
    </style>
    <title>系统首页</title>
</head>
<body>
    <div id="contanier">
        <div id="menu">
            <li id="es6">ES6网站</li>
            <li id="css">css网站</li>
            <li id="java">java网站</li>
            <li id="php">php网站</li>
        </div>
        <div id="content">
            <iframe></iframe>
        </div>
    </div>
</body>
<script src="https://code.jquery.com/jquery-3.6.3.js"></script>
<script>
	// 页面的工具类
    class Utils {
		
		// 模拟从后台获取到的菜单栏以及其url
        static urlMap = new Map([
            ['es6', './03/02-es6.html'],
            ['css', './03/03-css.html'],
            ['java', './03/04-java.html'],
            ['php', './03/05-php.html'],
            ['home', './03/01-首页.html']
        ]);

        // 获取本页面不含参数的url
        static getUrl() {

            const {
                origin,
                pathname
            } = location;

            return origin + pathname;
        }

        // 获取url中指定的参数
        static getParamFromUrl(url, param) {
            return new URLSearchParams(new URL(url).search).get(param);
        }
    }

    $(function() {

        // 事件绑定
        eventBind();

        // 加载页面
        loadPage();
    });

    function eventBind() {

        // 当浏览器前进后退时,会触发popstate事件
        window.addEventListener("popstate", function(evnet) {
            loadPage();
        });

        $("#menu li").click(function(event, triggerFlg) {

            const pageId = this.id;
            reloadIframe(pageId);

            /*
                如果是用户手动点击触发,则将当前url添加到浏览器的history中
                如果是通过函数来触发的点击事件,则不将url添加到浏览器的history中
            */
            if(!triggerFlg) {
                history.pushState(null, "", `${Utils.getUrl()}?name=${pageId}`);
            }
        });
    }

    function loadPage() {
        
        const pageId = Utils.getParamFromUrl(location.href, "name");
        
        // 如果url中没有 ?name=对应的属性值,或者Utils.urlMap中没有pageId对应值的话
        if(!pageId || !Utils.urlMap.get(pageId)) {
            // 将当前 url + ?name=home 的路径替换到浏览器的history中
            history.replaceState(null, "", `${Utils.getUrl()}?name=home`);
            // 重载页面,此时url中的参数为?name=home
            loadPage();
            return;
        }
        
        // 如果当前是home页的话,就重载iframe标签
        if(pageId == "home") {
            reloadIframe(pageId);
            return;
        }

        /*
            手动触发点击事件
            第二个参数是为了在手动触发点击事件的时候传递一个参数
            传递此参数的目的是为了让点击事件的回调区分,当前点击事件是用户主动点击触发,
            还是通过函数来手动触发的
        */
        $("#" + pageId).trigger("click", true);
    }

    function reloadIframe(pageId) {
        // 清空iframe标签
        $("#content").empty();
        
        // 创建新的iframe标签,并指定url
        $("<iframe>", {
            src: Utils.urlMap.get(pageId)
        }).appendTo($("#content"));
    }
</script>
</html>

四. 代码分析

  • reloadIframe方法中,我们并不是直接修改的iframe标签的src属性,而是销毁掉既存的iframe标签,并新创建一个。如果直接修改src属性的话,src中的地址会直接存入history对象中,给浏览器前进后退功能带来影响。直接创建iframe标签,src中的地址并不会写入history对象中。
  • 由于新创建的iframe标签的src属性值并不会存入history对象中,因此我们需要手动调用history.pushState()这个api来存入到history对象中。
  • $("#menu li")上的点击事件可由用户主动点击触发,也可由window上的popstate事件手动触发,当是由popstate事件手动触发时,说明用户使用了浏览器的前进后退功能,此时不需要将url存储history中。

五. 效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/655878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Matlab论文插图绘制模板第104期—带缺口的分组箱线图

在之前的文章中&#xff0c;分享了Matlab分组箱线图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一下带缺口的分组箱线图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需…

PyQT5介绍及基本使用

文章目录 PyQt51. PyQt5的下载与安装1.1 PyQt5介绍1.2 windows PyQt5的安装 2.PyQt5基本UI2.1 第一个PyQt程序2.2 argv2.3 模块介绍 3.基本UI3.1 按钮QPushButton3.2 文本QLabel3.3 输入框3.4 调整窗口大小3.5 调整窗口显示屏幕中间3.6 设置窗口icon 4.布局4.1 QBoxLayout4.1.1…

Spring Security系列之授权(Authorization)架构

文章目录 AuthorizationManagerAuthorizationFilterRequest Matcher AuthorizationManager AuthorizationManager 被授 AuthorizationFilter 调用&#xff0c;负责做出最终的访问控制决定。AuthorizationManager 接口包含两个方法。 default void verify(Supplier<Authent…

ABBYY FineReader15最新版图片文字识别转换软件

在日常生活中&#xff0c;我们会遇到需要将各种文字、图片、扫描图片等转换为文字的情况。想要轻松解决这些问题&#xff0c;需要使用到OCR文字识别。但对于许多新手来说&#xff0c;OCR文字识别是陌生的。今天小编就给大家介绍一下&#xff0c;OCR文字识别怎么使用&#xff0c…

RabbitMQ如何保证消息幂等性

用户对于同一操作发起的一次请求或者多次请求的结果是一致的&#xff0c;不会因为多次点击而产生副作用。 举个简单的例子&#xff0c;那就是支付&#xff0c;用户购买商品后支付&#xff0c;支付扣款成功&#xff0c;但是返回结果的时候网络异常&#xff0c;此时钱已经扣了&am…

DJ8-4 shell 语句的分类、shell 的结构性语句

目录 8.7 shell 编程 8.7.1 shell 编程的基本过程 8.7.2 实例 8.7.3 shell 程序和语句 8.8 说明性语句和功能性语句 8.8.1 说明性语句&#xff08;注释行&#xff09; 8.8.2 常用的功能性语句 8.9 结构性语句 8.9.1 条件语句 if 8.9.2 测试语句 test 8.9.…

什么牌子的电容笔质量好耐用?平板第三方电容笔了解下

苹果的电容笔和普通的电容笔有何区别&#xff1f;其实&#xff0c;就书写情况而言&#xff0c;两者相差不多。只是苹果电容笔生在重量上&#xff0c;更加的沉重&#xff0c;而且还配备了一个特殊的重力传感器&#xff0c;能够准确的感觉到重力对线条的粗细变化。由于苹果这款产…

手机操作系统的沉浮往事(上)

移动终端操作系统&#xff0c;也就是指手机、平板电脑等设备所使用的操作系统。 在移动互联网高度发达的今天&#xff0c;我们使用移动终端操作系统的时长&#xff0c;可能已经远远超过了Windows等桌面操作系统。 那么&#xff0c;你真正了解这些移动终端操作系统吗&#xff1f…

抖音seo源码开发部署技术解析

抖音seo源码开发是一项非常重要的技术&#xff0c;开发需要深入了解抖音平台的特点和用户需求&#xff0c;积累丰富的SEO经验&#xff0c;并不断学习和更新SEO技能&#xff0c;才能不断提高视频在搜索引擎中的曝光率和播放量。 抖音seo开发需要哪些技术 了解抖音的算法和规则&…

浏览器被2345劫持了怎么搞

起因我下载了某些修改东西&#xff0c;然后就被2345篡改了浏览器的数据。我是在虚拟机里下载的&#xff0c;但是虚拟机其实也是物理机的一部分&#xff0c;实际上下载的还是到了物理机里面&#xff0c;于是浏览器打开就变成了2345的导航页面 1 解决方案&#xff1a; 浏览器主页…

DJ8-2 shell 的命令形式、shell 的变量、shell 的内部命令

目录 8.3 shell 可识别的命令形式 8.3.1 单条命令 8.3.2 多条命令 8.3.3 复合命令 8.3.4 后台命令 8.4 shell 变量和引用符 8.4.1 环境变量 plus. echo 命令的使用 8.4.2 系统变量 8.4.3 局部变量&#xff08;用户变量&#xff09; 8.4.4 单引号、双引号、…

跨境电商领域的ChatGPT使用攻略

今天分享一个电商领域的ChatGPT应用指南! 一、写谷歌广告词 提示词: 现在你是一名谷歌广告的编写人员&#xff0c;你需要为xxx产品写10条谷歌广告标题和谷歌广告描述。要求是: 1.用英文输出你的答案 2.广告的标题和广告描述的字数等要符合谷歌的标准 3.广告要引人入胜&#xf…

OceanBase—01(入门篇——使用docker安装OceanBase以及介绍连接OB的几种方式)

OceanBase—01&#xff08;入门篇——使用docker安装OceanBase以及介绍连接OB的几种方式&#xff09; 1. 前言1.1 安装部署参考1.1.1 安装前提1.1.2 参考 1.1 修改数据库用户名密码1.2 总结常见连接命令 2. 安装部署OceanBase2.1 启动 OceanBase 数据库实例2.1.1 默认拉取最新版…

代码审计——XSS详解

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 跨站脚本攻击&#xff08;Cross Site Script&#xff09;是一种将恶意JavaScript代码插入到其他Web用户页面里执行以达到攻击…

没网络的CentOS7的Docker容器安装Java诊断神器Arthas

操作过程 1. 先把jar包下载到本地的windwos2. 打包复制到服务器3. 启动容器设置4.重启容器并使用Arthas 1. 先把jar包下载到本地的windwos 下载地址 下载好后jar&#xff0c;然后CMD执行命令 java -jar arthas-boot.jar 然后随便进入某个jvm进程查看&#xff0c;会见到Conso…

【技术新趋势】面向图像文档的版面智能分析与理解

目录 一、什么是OCR&#xff1f;什么是版面分析理解&#xff1f;二、文档版面分析2.1、版面布局类型2.2、面向文档图像版面分析的实例分割2.3、逻辑结构分析 三、文档版面理解3.1、位置嵌入3.2、表格数据提取 四、智能文档处理技术新解决方案 人类撰写文档是为了记录和保存信息…

Zoho Books助力跨境贸易!深入了解其多币种处理功能

对于跨境行业而言&#xff0c;合作不同的客户以当地货币收取付款是一个不简单的任务。现在&#xff0c;Zoho Books 推出了新的高级多币种处理功能&#xff0c;让多货币付款或收款不再困扰。&#xff08;注意&#xff1a;此功能在Zoho Books的专业版&#xff0c;高级版&#xff…

使用 ChatGPT 创建 APP 的最佳实践

导读&#xff1a;如果你想用用ChatGPT创建应用程序来赚钱&#xff0c;这是你需要知道的。 本文字数&#xff1a;2900&#xff0c;阅读时长大约&#xff1a;18分钟 如果你想用ChatGPT创建应用程序来赚钱&#xff0c;这是你需要知道的。 我最好先说出坏消息。如果你认为可以两手…

【后端开发】尚硅谷 SpringCloud 学习笔记

文章目录 一、cloud组件二、环境搭建2.1 创建父工程2.2 支付模块构建2.3 消费者模块构建2.3.1 引入RestTemplate2.3.2 远程调用支付模块 三、Eureka3.1 基础知识3.2 单机版Eureka安装3.3 服务注册3.4 Eureka集群3.4.1 Eureka端配置3.4.2 微服务端配置3.4.3 restTemplate负载均衡…

如何让ChatGPT制作XMind思维导图

一、使用ChatGPT辅助生成内容 给大家一个思路&#xff0c;比如我想制作《股神巴菲特给儿女的一生忠告》相关的思维导图&#xff0c;那我们可以在ChatGPT上提问“请使用markdown格式写出股神巴菲特给儿女的一生忠告的思维导图&#xff0c;以代码格式输出”。 生成后&#xff0…