I think the most reasonable approach would be to whitelist which properties of the DOM element you want to serialize:
JSON.stringify(container, ["id", "className", "tagName"])
The second parameter of the JSON.stringify
function allows you to change the behavior of the stringification process. You can specify an array with the list of properties to serialize. More information here: JSON.stringify
If you want to serialize its child nodes too, some extra work is needed. In this case you will have to specify a replacer function as the second parameter of JSON.stringify
, instead of an array.
let whitelist = ["id", "tagName", "className", "childNodes"];
function domToObj (domEl) {
var obj = {};
for (let i=0; i<whitelist.length; i++) {
if (domEl[whitelist[i]] instanceof NodeList) {
obj[whitelist[i]] = Array.from(domEl[whitelist[i]]);
}
else {
obj[whitelist[i]] = domEl[whitelist[i]];
}
};
return obj;
}
JSON.stringify(container, function (name, value) {
if (name === "") {
return domToObj(value);
}
if (Array.isArray(this)) {
if (typeof value === "object") {
return domToObj(value);
}
return value;
}
if (whitelist.find(x => (x === name)))
return value;
})
The replacer function transforms the hosted objects in childNodes
to native objects, that JSON.stringify
knows how to serialize. The whitelist
array has the list of properties to serialize. You can add your own properties here.
Some extra work in the replacer function might be needed if you want to serialize other properties that reference hosted objects (for example, firstChild
).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…