gpt4 book ai didi

javascript - 将准确的 innerHTML 还原为 DOM

转载 作者:技术小花猫 更新时间:2023-10-29 11:59:36 30 4
gpt4 key购买 nike

我想保存 DOM 的 html 字符串,稍后将其恢复为完全相同。代码看起来像这样:

var stringified = document.documentElement.innerHTML
// later, after serializing and deserializing
document.documentElement.innerHTML = stringified

这在一切都完美的情况下有效,但是当 DOM 不符合 w3c 时,就会出现问题。第一行工作正常,stringified 与 DOM 完全匹配。但是当我从(非 w3c 兼容的)stringified 恢复时,浏览器做了一些魔术,生成的 DOM 与原来的不一样。

例如,如果我的原始 DOM 看起来像

<p><div></div></p>

那么最终的 DOM 会是这样的

<p></p><div></div><p></p>

因为 div 元素不允许位于 p 元素内。有什么方法可以让浏览器使用与页面加载时相同的 html 解析并按原样接受损坏的 html?

为什么 html 一开始就坏了? DOM 不是我控制的。

这是一个展示行为的 jsfiddle http://jsfiddle.net/b2x7rnfm/5/ .打开您的控制台。

<body>
<div id="asdf"><p id="outer"></p></div>
<script type="text/javascript">
var insert = document.createElement('div');
var text = document.createTextNode('ladygaga');
insert.appendChild(text);
document.getElementById('outer').appendChild(insert);
var e = document.getElementById('asdf')
console.log(e.innerHTML);
e.innerHTML = e.innerHTML;
console.log(e.innerHTML); // This is different than 2 lines above!!
</script>
</body>

最佳答案

如果您需要能够保存和恢复无效的 HTML 结构,您可以通过 XML 来完成。以下代码来自this fiddle .

要保存,请创建一个新的 XML 文档,向其中添加要序列化的节点:

var asdf = document.getElementById("asdf");
var outer = document.getElementById("outer");
var add = document.getElementById("add");
var save = document.getElementById("save");
var restore = document.getElementById("restore");

var saved = undefined;
save.addEventListener("click", function () {
if (saved !== undefined)
return; /// Do not overwrite

// Create a fake document with a single top-level element, as
// required by XML.
var parser = new DOMParser();
var doc = parser.parseFromString("<top/>", "text/xml");

// We could skip the cloning and just move the nodes to the XML
// document. This would have the effect of saving and removing
// at the same time but I wanted to show what saving while
// preserving the data would look like
var clone = asdf.cloneNode(true);
var top = doc.firstChild;
var child = asdf.firstChild;
while (child) {
top.appendChild(child);
child = asdf.firstChild;
}
saved = top.innerHTML;
console.log("saved as: ", saved);

// Perform the removal here.
asdf.innerHTML = "";
});

要恢复,您可以创建一个 XML 文档来反序列化您保存的内容,然后将节点添加到您的文档中:

restore.addEventListener("click", function () {
if (saved === undefined)
return; // Don't restore undefined data!

// We parse the XML we saved.
var parser = new DOMParser();
var doc = parser.parseFromString("<top>" + saved + "</top>", "text/xml");
var top = doc.firstChild;

var child = top.firstChild;
while (child) {
asdf.appendChild(child);
// Remove the extra junk added by the XML parser.
child.removeAttribute("xmlns");
child = top.firstChild;
}
saved = undefined;
console.log("inner html after restore", asdf.innerHTML);
});

使用 fiddle ,您可以:

  1. 按“添加 LadyGaga...”按钮创建无效的 HTML。

  2. 按“保存并从文档中删除”将结构保存在 asdf 中并清除其内容。这会将保存的内容打印到控制台。

  3. 按“恢复”恢复保存的结构。

上面的代码旨在通用。如果可以对要保存的 HTML 结构做出一些假设,则可以简化代码。例如,blah 不是格式正确的 XML 文档,因为您需要 XML 中的单个顶级元素。所以上面的代码煞费苦心地添加了一个顶级元素(top)来防止这个问题。通常也不可能仅将 HTML 序列化解析为 XML,因此保存操作序列化为 XML。

这更像是一个概念验证。将在 HTML 文档中创建的节点移动到 XML 文档或相反的方式可能会产生我没有预料到的副作用。我已经在 Chrome 和 FF 上运行了上面的代码。我手边没有 IE,无法在那里运行它。

关于javascript - 将准确的 innerHTML 还原为 DOM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31077690/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com