Javascript 即使有循环引用,如何将 DOM 节点序列化为 JSON?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2303713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to serialize DOM node to JSON even if there are circular references?
提问by NVI
I want to serialize DOM node or even whole windowto JSON.
我想将 DOM 节点甚至整个序列化为windowJSON。
For example:
例如:
>> serialize(document)
-> {
"URL": "http://stackoverflow.com/posts/2303713",
"body": {
"aLink": "",
"attributes": [
"getNamedItem": "function getNamedItem() { [native code] }",
...
],
...
"ownerDocument": "#" // recursive link here
},
...
}
JSON.stringify()
JSON.stringify()
JSON.stringify(window) // TypeError: Converting circular structure to JSON
The problem is JSON does not support circular references by default.
问题是 JSON 默认不支持循环引用。
var obj = {}
obj.me = obj
JSON.stringify(obj) // TypeError: Converting circular structure to JSON
windowand DOM nodes have many of them. window === window.windowas will as document.body.ownerDocument === document.
window和 DOM 节点有很多。window === window.window也一样document.body.ownerDocument === document。
Also, JSON.stringifydoes not serialize functions, so this is not what I'm looking for.
此外,JSON.stringify不序列化函数,所以这不是我要找的。
dojox.json.ref
dojox.json.ref
`dojox.json.ref.toJson()` can easily serialize object with circular references:
var obj = {}
obj.me = obj
dojox.json.ref.toJson(obj); // {"me":{"$ref":"#"}}
Good, isn't it?
很好,不是吗?
dojox.json.ref.toJson(window) // Error: Can't serialize DOM nodes
Well not good enough for me.
对我来说还不够好。
Why?
为什么?
I'm trying to make DOM compatibility table for different browsers. For instance, Webkit supports placeholder attribute and Opera doesn't, IE 8 supports localStorageand IE 7 doesn't, and so on.
我正在尝试为不同的浏览器制作 DOM 兼容性表。例如,Webkit 支持占位符属性而 Opera 不支持,IE 8 支持localStorage而 IE 7 不支持,等等。
I don't want to make thousands of test-cases. I want to make generic way for test them all.
我不想制作数千个测试用例。我想用通用的方式来测试它们。
Update, June 2013
2013 年 6 月更新
I made a prototype NV/dom-dom-dom.com.
我做了一个原型NV/dom-dom-dom.com。
回答by Josh Dzielak
http://jsonml.org/takes a shot at a grammar for converting XHTML DOM elements into JSON. An an example:
http://jsonml.org/ 尝试将 XHTML DOM 元素转换为 JSON 的语法。一个例子:
<ul>
<li style="color:red">First Item</li>
<li title="Some hover text." style="color:green">Second Item</li>
<li><span class="code-example-third">Third</span> Item</li>
</ul>
becomes
变成
["ul",
["li", {"style": "color:red"}, "First Item"],
["li", {"title": "Some hover text.", "style": "color:green"}, "Second Item"],
["li", ["span", {"class": "code-example-third"}, "Third"], " Item" ]
]
Haven't used it yet, but thinking about using it for a project where I want to take any web page and re-template it using mustache.js.
还没有使用它,但考虑将它用于我想要获取任何网页并使用 mustache.js 重新模板的项目。
回答by Matthew Taylor
回答by Ates Goral
You could potentially traverse the DOM and generate a pure JS object representation of it and then feed it to the DojoX serializer. But, you have to first decide how you're planning to map DOM elements, their attributes and the text nodes, without ambiguity, to JS objects. For example, how would you represent the following?
您可能会遍历 DOM 并生成它的纯 JS 对象表示,然后将其提供给 DojoX 序列化器。但是,您必须首先决定如何将 DOM 元素、它们的属性和文本节点明确地映射到 JS 对象。例如,您将如何表示以下内容?
<parent attr1="val1">
Some text
<child attr2="val2"><grandchild/></child>
</parent>
Like this?
像这样?
{
tag: "parent",
attributes: [
{
name: "attr1",
value: "val1"
}
],
children: [
"Some text",
{
tag: "child",
attributes: [
{
name: "attr2",
value: "val2"
}
],
children: [
{ tag: "grandchild" }
]
}
]
}
I think the a reason DojoX doesn't immediately support DOM serialization could exactly be this: The need to first pick a scheme for mapping DOM to JS objects. Is there a standard scheme that could be employed? Would your JS object simply mimic a DOM tree without any functions? I think you have to first define what your expectation is from "serializing DOM to JSON".
我认为 DojoX 没有立即支持 DOM 序列化的一个原因可能正是:需要首先选择一种将 DOM 映射到 JS 对象的方案。是否有可以采用的标准方案?你的 JS 对象会简单地模仿一个没有任何功能的 DOM 树吗?我认为您必须首先定义您对“将 DOM 序列化为 JSON”的期望。
回答by Frunsi
It looks like you have to write it on your own. JSON serialized data may also not be the perfect choice for your task (DOM compatibility table). You probably have to iterate the objects on your own, check types of the attributes and so on..
看来得自己写了。JSON 序列化数据也可能不是您任务的完美选择(DOM 兼容性表)。您可能必须自己迭代对象,检查属性的类型等等。
var functions = [];
var strings = [];
for( var key in window ) {
if( typeof window[key] == 'string' ) {
strings[strings.length] = key;
} else if( typeof window[key] == 'function' ) {
functions[functions.length] = key;
} else if( ... ) { ... }
}
...

![Javascript 如何使 input[type=text] 元素作为 textarea 工作?](/res/img/loading.gif)