Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to JSON.stringify a dom element?

Tags:

javascript

dom

As title , how to JSON.stringify a dom element, and change back the json to a dom element.

Any one know how to do , thanks.

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":[...]}
like image 530
mack873 Avatar asked Oct 23 '17 01:10

mack873


People also ask

Can you JSON Stringify an object?

Stringify a JavaScript ObjectUse the JavaScript function JSON. stringify() to convert it into a string. const myJSON = JSON. stringify(obj);

What does JSON Stringify () method do?

The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.

Can you use JSON Stringify on an array?

While we're converting an object literal into a JSON string in this example, JSON. stringify() also works with arrays.

Does JSON Stringify nested objects?

stringify does not stringify nested arrays. Bookmark this question. Show activity on this post.


2 Answers

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).

like image 174
ncardeli Avatar answered Sep 25 '22 13:09

ncardeli


I wondered the same thing, and I appreciate the answer from @ncardeli. In my app, I needed something a little different, and I thought I'd share in case anyone is interested. It recursively displays properties of any children too.

Press the button below to run the example. You can add whatever properties you want to obj and therefore to the result.

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>
like image 20
Kent Weigel Avatar answered Sep 26 '22 13:09

Kent Weigel