为啥在浏览器中调用和显示时存储在 localStorage 中的 HTML 会发生变化?
Posted
技术标签:
【中文标题】为啥在浏览器中调用和显示时存储在 localStorage 中的 HTML 会发生变化?【英文标题】:Why does HTML stored in localStorage change when recalled and displayed in the browser?为什么在浏览器中调用和显示时存储在 localStorage 中的 HTML 会发生变化? 【发布时间】:2020-11-25 04:53:14 【问题描述】:抱歉,如果之前有人问过这个问题,我已经搜索过但找不到任何相关的内容...
我在这里有一个非常简单的网站,它有 3 个按钮:
添加组件
保存当前状态
恢复保存状态
添加组件按钮正是我想要的,即在
<div data-role="collapsible-set" class="flow" id="collapsibleComponent"></div>
标签。
另外,保存当前状态
storeCurrentState();
按钮似乎捕获了所需的代码完全相同到正在显示的内容(这是正确的)。
但是,当我点击Restore Saved State按钮(运行restorePriorState();
方法)时,从localStorage读取并放回页面的代码与得救了。结果,我最终得到了一个嵌套的折叠项,如下所示...
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>TutorialW3a</title>
<link href="jquery-mobile/jquery.mobile.theme-1.3.0.min.css" rel="stylesheet" type="text/css" />
<link href="jquery-mobile/jquery.mobile.structure-1.3.0.min.css" rel="stylesheet" type="text/css" />
<script src="jquery-mobile/jquery-1.11.1.min.js"></script>
<script src="jquery-mobile/jquery.mobile-1.3.0.min.js"></script>
</head>
<body>
<div data-role="page" id="page">
<div data-role="header">
<h1>Header</h1>
</div>
<div data-role="content">
<div data-role="collapsible-set" class="flow" id="collapsibleComponent">
<!--New collapsible divs go here-->
</div>
</div>
<button onclick="addCollapsibleComponent()">Add component</button>
<button onclick="storeCurrentState()">Save current state</button>
<button onclick="restorePriorState()">Restore saved state</button>
<div data-role="footer" data-position="fixed">
<h4>Footer</h4>
</div>
</div>
</body>
</html>
<script>
//
var collapsibleComponentContent = document.getElementById("collapsibleComponent");
var collapsibleDiv;
function addCollapsibleComponent()
//create div element
collapsibleDiv = $('<div id="new" data-role="collapsible" data-collapsed="true"><h3>Heading</h3><p>Paragraph</p></div>"');
//append new collapsible div to #collapsibleComponent
$("#collapsibleComponent").append(collapsibleDiv);
//collapse all collapsible divs
$('div[data-role="collapsible"]').collapsible();
//
function storeCurrentState()
collapsibleDiv = document.getElementById("new");
localStorage.setItem("html_data", JSON.stringify(collapsibleComponentContent.innerHTML));
//
function restorePriorState()
collapsibleComponentContent.innerHTML = JSON.parse(localStorage.getItem("html_data"));
$("#new").collapsible();
</script>
这是在创建新的可折叠组件时生成的...
<div id="new" data-role="collapsible" data-collapsed="true" class="ui-collapsible ui-collapsible-inset ui-collapsible-collapsed">
<h3 class="ui-collapsible-heading ui-collapsible-heading-collapsed">
<a href="#" class="ui-collapsible-heading-toggle ui-btn ui-btn-icon-left ui-btn-up-c" data-corners="false" data-shadow="false" data-iconshadow="true" data-wrapperels="span" data-icon="plus" data-iconpos="left" data-theme="c"
><span class="ui-btn-inner"
><span class="ui-btn-text">Heading<span class="ui-collapsible-heading-status"> click to expand contents</span></span
><span class="ui-icon ui-icon-plus ui-icon-shadow"> </span></span
></a
>
</h3>
<div class="ui-collapsible-content ui-collapsible-content-collapsed" aria-hidden="true"><p>Paragraph</p></div>
这就是我重新加载时创建的...
<h3 class="ui-collapsible-heading ui-collapsible-heading-collapsed">
<a href="#" class="ui-collapsible-heading-toggle ui-btn ui-btn-icon-left ui-btn-up-c" data-corners="false" data-shadow="false" data-iconshadow="true" data-wrapperels="span" data-icon="plus" data-iconpos="left" data-theme="c"
><span class="ui-btn-inner"
><span class="ui-btn-text"
><a href="#" class="ui-collapsible-heading-toggle ui-btn ui-btn-icon-left ui-btn-up-c" data-corners="false" data-shadow="false" data-iconshadow="true" data-wrapperels="span" data-icon="plus" data-iconpos="left" data-theme="c"
><span class="ui-btn-inner"
><span class="ui-btn-text">Heading<span class="ui-collapsible-heading-status"> click to expand contents</span></span
><span class="ui-icon ui-icon-plus ui-icon-shadow"> </span></span
></a
><span class="ui-collapsible-heading-status"> click to expand contents</span></span
><span class="ui-icon ui-icon-plus ui-icon-shadow"> </span></span
></a
>
【问题讨论】:
不一致是什么意思?恢复到已保存的数据时,您会得到完全不同的数据? 是的,它添加了以前没有的跨度并将其他类添加到 div 标签。 @AlwaysHelping 我已经编辑了我的原始帖子以显示生成和保存的代码,然后从本地存储重新加载更改后显示的内容 我无法重现此问题。对我来说一切似乎都很好。 多么令人困惑?,我最终看起来像i.stack.imgur.com/BU7iM.png 中所示的所有嵌套 【参考方案1】:你在问“为什么”,所以这是答案:
JQM 是一个混合的 JS/CSS 框架,即 widgets
由 JS 增强并由 CSS 样式化。页面初始化后,框架通过添加一些嵌套元素(div
、span
)、pseudo-elements
(图标)和事件处理程序来增强小部件(由“data-role
”标签标识)。
也就是说,在您的代码中,您将初始标记的增强版本与data-role
属性一起保存,但您只保存标记,这意味着您不会保存 JS data
,它将在小部件初始化期间由框架创建。简而言之,您只节省了已经增强的小部件的一半。
下一次,框架将再次找到data-role
属性,但找不到关联的data
对象,通过调用$("#new").collapsible();
,您最终会得到该双重嵌套标记。
更多信息:
你可以看一下JQM小部件对象如下:
$.data(document.getElementById("new"),"mobile-collapsible")
或:
$("#new").jqmData("mobile-collapsible")
您的任务有不止一种可能的解决方案。
也许您可以恢复最初的未增强标记:
$("#collapsibleComponent :jqmData(role='collapsible')").collapsible("destroy");
并保存:
localStorage.setItem("html_data", JSON.stringify($("#collapsibleComponent").html()));
最后,你假设
以与显示的内容相同的方式捕获所需的代码是正确的
错了。
【讨论】:
非常感谢您的详细解释!这是一个完美的答案,因为它给了我一些我需要了解更多的明确定义的领域......谢谢你指出我正确的方向? @Nathan:感谢您的反馈!要从社区获得更多帮助,您可能需要切换到最新的 JQM 版本 1.4.5以上是关于为啥在浏览器中调用和显示时存储在 localStorage 中的 HTML 会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章
JS惰性删除和定时删除可过期的localStorage缓存,或sessionStorage缓存
JS惰性删除和定时删除可过期的localStorage缓存,或sessionStorage缓存
刷新浏览器后显示 localStorage 中的收藏项 - Next.js 和 Typescript 项目