SkillAgentSearch skills...

DomJSON

Convert DOM trees into compact JSON objects, and vice versa, as fast as possible.

Install / Use

/learn @azaslavsky/DomJSON
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

domJSON

License Bower version npm version Coverage Status Dependencies Travis Build

Convert DOM trees into compact JSON objects, and vice versa, as fast as possible.

Jump To

Description

The purpose of domJSON is to create very accurate representations of the DOM as JSON, and to do it very quickly. While there are probably dozens of viable use cases for this project, I've made two quick demos to showcase the library's versatility. The first simply makes a copy of a given branch of the DOM tree, which could be useful for end user bug logging, state tracking, etc. The second demo does a batch update of a large number of DOM Nodes, but much more performantly than the "traditional" jQuery select > .each() > update pattern.

Broadly speaking, the goals of this project are:

  • Provide as accurate a copy of a given node's DOM properties as possible, but allow option filtering to remove useless information
  • Be able to rebuild JSON nodes into DOM nodes as performantly as possible
  • Speed, speed, speed
  • No frivolous data: produce JSON objects that are as compact as possible, removing all information not relevant to the developer
  • Keep the library lightweight, with no dependencies

DomJSON works in the following browsers (mobile and desktop versions supported):

  • Chrome Chrome 39+
  • Chrome Firefox 24+
  • Chrome Safari 7+
  • Chrome IE 9+

Installation

Installing domJSON is easy. You can pull it from Bower...

bower install domjson

...or grab it from NPM and manually include it as a script tag...

npm install domjson --save

or just download this repo manually and include the file as a dependency.

<script src="./lib/domJSON.js"></script>

Demos

Coming soon...

Usage

Using domJSON is super simple: use the .toJSON() method to create a JSON representation of the DOM tree:

var someDOMElement = document.getElementById('sampleId');
var jsonOutput = domJSON.toJSON(myDiv);

And then rebuild the DOM Node from that JSON using .toDOM():

var DOMDocumentFragment = domJSON.toDOM(jsonOutput);
someDOMElement.parentNode.replaceChild(someDOMElement, DOMDocumentFragment);

When creating the JSON object, there are many precise options available, ensuring that developers can produce very specific and compact outputs. For example, the following will produce a JSON copy of someDOMElement's DOM tree that is only two levels deep, contains no "offset*," "client*," or "scroll*" type DOM properties, only keeps the "id" attribute on each DOM Node, and outputs a string (rather than a JSON-friendly object):

var jsonOutput = domJSON.toJSON(myDiv, {
	attributes: ['id'],
	domProperties: {
		exclude: true,
		values: ['clientHeight', 'clientLeft', 'clientTop', 'offsetWidth', 'offsetHeight', 'offsetLeft', 'offsetTop', 'offsetWidth', 'scrollHeight', 'scrollLeft', 'scrollTop', 'scrollWidth']
	},
	deep: 2,
	stringify: true
});

FilterLists

A FilterList is a custom type for certain options passed to domJSON's .toJSON() method. It allows for very granular control over which fields are included in the final JSON output, allowing developers to eliminate useless information from the result, and produce extremely compact JSON objects. It operates based on boolean logic: an inclusive FilterList allows the developer to explicitly specify which fields they would like to see in the output, while an exclusive FilterList allows them to specify which fields they would like to omit (e.g., "Copy every available field except X, Y, and Z"). The FilterList accepts an object as an argument, or a shorthand array (which is the recommended style, since it's much less verbose).

Take this example: suppose we have a single div that we would like to convert into a JSON object using domJSON. It looks like this in its native HTML:

<div id="myDiv" class="testClass" style="margin-top: 10px;" data-foo="bar" data-quux="baz">
	This is some sample text.
</div>

Let's try and make a JSON object out of this field, but only include the class and style attributes, and only the offsetTop and offsetLeft DOM properties. Both of the following inputs will have the same output:

var myDiv = document.getElementById('myDiv');

//Using object notation for our filterLists
var jsonOutput = domJSON.toJSON(myDiv, {
	attributes: {
		values: ['class', 'style']
	},
	domProperties: {
		values: ['offsetLeft', 'offsetTop']
	},
	metadata: false
});

//Same thing, using the array notation
var jsonOutput = domJSON.toJSON(myDiv, {
	attributes: [false, 'class', 'style'],
	domProperties: [false, 'offsetLeft', 'offsetTop'],
	metadata: false
});

The result:

{
	"attributes": {
		"class": "testClass",
		"style": "margin-top: 10px;"
	},
	"childNodes": [{
		"nodeType": 3,
		"nodeValue": "This is some sample text"
	}],
	"nodeType": 1,
	"nodeValue": "This is some sample text",
	"offsetLeft": 123,
	"offsetTop": 456,
	"tagName": "DIV"
}

The array notation is much shorter, and very easy to parse: the first value is a boolean that determines whether the list is exclusive or not, and the remaining elements are just the filter values themselves. Here is an example for making an exclusive list of attributes on the same div as above:

var myDiv = document.getElementById('myDiv');

//Using object notation for our filterLists, but this time specify values to EXCLUDE
var jsonOutput = domJSON.toJSON(myDiv, {
	attributes: {
		exclude: true,
		values: ['class', 'style']
	},
	domProperties: {
		values: ['offsetLeft', 'offsetTop']
	},
	metadata: false
});

//Same thing, using the array notation
var jsonOutput = domJSON.toJSON(myDiv, {
	attributes: [true, 'class', 'style'],
	domProperties: [false, 'offsetLeft', 'offsetTop'],
	metadata: false
});

The result:

{
	"attributes": {
		"id": "myDiv",
		"data-foo": "bar",
		"data-quux": "baz"
	},
	"childNodes": [{
		"nodeType": 3,
		"nodeValue": "This is some sample text"
	}],
	"nodeType": 1,
	"nodeValue": "This is some sample text",
	"offsetLeft": 123,
	"offsetTop": 456,
	"tagName": "DIV"
}

Objects

<dl> <dt><a href="#domJSON">domJSON</a> : <code>object</code></dt> <dd><p>domJSON is a global variable to store two methods: <code>.toJSON()</code> to convert a DOM Node into a JSON object, and <code>.toDOM()</code> to turn that JSON object back into a DOM Node</p> </dd> </dl>

Typedefs

<dl> <dt><a href="#FilterList">FilterList</a> : <code>Object</code> | <code>Array</code></dt> <dd><p>An object specifying a list of fields and how to filter it, or an array with the first value being an optional boolean to convey the same information</p> </dd> </dl>

<a name="domJSON"></a>

domJSON : <code>object</code>

domJSON is a global variable to store two methods: .toJSON() to convert a DOM Node into a JSON object, and .toDOM() to turn that JSON object back into a DOM Node

Kind: global namespace

<a name="domJSON.toJSON"></a>


domJSON.toJSON(node, [opts]) ⇒ <code>Object</code> | <code>string</code>

Take a DOM node and convert it to simple object literal (or JSON string) with no circular references and no functions or events

Kind: static method of <code>domJSON</code>
Returns: <code>Object</code> | <code>string</code> - A JSON-friendly object, or JSON string, of the DOM node -> JSON conversion output
Todo

  • [ ] {boolean|FilterList} [opts.parse=false] a FilterList of properties that are DOM nodes, but will still be copied PLANNED

| Param | Type | Default | Description | | --- | --- | --- | --- | | node | <code>Node</code> | | The actual DOM Node which will be the starting point for parsing the DOM Tree | | [opts] | <code>Object</code> | | A list of all method options | | [opts.allowDangerousElements] | <code>boolean</code> | <code>`false`</code> | Use true to parse the potentially dangerous elements <link> and <script> | | [opts.absolutePaths] | <code>boolean</code> | <code>FilterList</code> | <code>`'action', 'data', 'href', 'src'`</code> | Only relevant if opts.attributes is not false; use true to convert all relative paths found in attribute values to absolute paths, or specify a FilterList of keys to boolean search | | [opts.attributes] | <code>boolean</code> | <code>FilterList</code> | <code>`true`</code> | Use true to copy all attribute key-value pairs, or

View on GitHub
GitHub Stars128
CategoryDevelopment
Updated6mo ago
Forks43

Languages

HTML

Security Score

72/100

Audited on Sep 26, 2025

No findings