【问题标题】:How to JSON.stringify a dom element?如何 JSON.stringify 一个 dom 元素?
【发布时间】:2017-10-23 01:31:13
【问题描述】:

作为标题,如何 JSON.stringify 一个 dom 元素,并将 json 改回一个 dom 元素。

谁知道怎么做,谢谢。

Here is the code :
var container = document.querySelectorAll('.container')
 var json=JSON.stringify(container)
 {"0":{},"1":{},"2":{},"3":{}}"//result

  expected result:
  {"tagname":"div","class":"container","value":"test","childelement":[...]}

【问题讨论】:

  • 您是否尝试将 HTML 标记或 HTMLElement 对象存储为 JSON
  • 您能否在问题中包含 HTML 和预期结果?见stackoverflow.com/help/mcve
  • 你为什么要 JSON.stringify 它,只使用它的 outerHTML 值。
  • 您好 guest271314,是的,我想将 HTMLElement 更改为 JSON 格式,谢谢。
  • 您好 guest271314,我已经更新了代码,谢谢。

标签: javascript dom


【解决方案1】:

我认为最合理的方法是将要序列化的 DOM 元素的哪些属性列入白名单:

JSON.stringify(container, ["id", "className", "tagName"])

JSON.stringify 函数的第二个参数允许您更改字符串化过程的行为。您可以使用要序列化的属性列表指定一个数组。更多信息在这里:JSON.stringify

如果您也想序列化其子节点,则需要做一些额外的工作。在这种情况下,您必须将替换函数指定为 JSON.stringify 的第二个参数,而不是数组。

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;
})

replacer 函数将childNodes 中的托管对象转换为本地对象,JSON.stringify 知道如何序列化。 whitelist 数组具有要序列化的属性列表。您可以在此处添加自己的属性。

如果您想要序列化引用托管对象的其他属性(例如,firstChild),可能需要在替换函数中进行一些额外的工作。

【讨论】:

  • 你好 ncardeli ,如果有一个子元素呢?
  • 我编辑了我的答案以显示如何序列化子节点。
【解决方案2】:

我想知道同样的事情,我感谢@ncardeli 的回答。在我的应用程序中,我需要一些不同的东西,我想我会分享以防有人感兴趣。它也递归地显示任何孩子的属性。

按下面的按钮运行示例。您可以将任何您想要的属性添加到 obj 并因此添加到结果中。

function showStringifyResult(target) {
  let result = document.getElementById("result");
  result.select();
  result.setRangeText(JSON.stringify(stringify(target), null, ' '));
}

function stringify(element) {
  let obj = {};
  obj.name = element.localName;
  obj.attributes = [];
  obj.children = [];
  Array.from(element.attributes).forEach(a => {
    obj.attributes.push({ name: a.name, value: a.value });
  });
  Array.from(element.children).forEach(c => {
    obj.children.push(stringify(c));
  });
  
  return obj;
}
#list {
  margin-top: 18px;
}
<h1>
  Press the Stringify button to write the stringified object to the textarea below.
</h1>

<button onClick="showStringifyResult(document.body)" class="c1">
  Stringify
</button>

<div id="list">
  A list for example:
  <ul class="first second">
    <li id="First Item">Item 1</li>
    <li>Item 2</li>
    <li class="inactive">Item 3</li>
    <li data-tag="tag">Item 4</li>
  </ul>
</div>

<textarea id="result" cols="200" rows="20" ></textarea>

【讨论】:

  • 感谢分享,这正是我需要从WKWebView .evaluateJavaScript(_:completionHandler:) 导出整个 DOM 以进行进一步处理。
【解决方案3】:

尽管这是一个旧线程,但我补充一下:

JSON.stringify(target, Object.getOwnPropertyNames(target["__proto__"]), 2)

快速列出 DOM 元素的一些属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 2012-04-17
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多