This library converts a DOM tree to an object so that its named properties can be accessed using dot notation.
Example
<div id="mydata">
<input type="text" name="username" value="johndoe" />
<input type="password" name="password" value="secret" />
<button id="mybutton">Click me!</button>
</div>
var data = DOM2Object("#mydata");
data.mybutton.onclick = function() {
console.log(`Button clicked! ${data.username.value}:${data.password.value}`);
};
In this example, the data
object can be seen somehow as the following object:
data = {
username: HTMLElement { ... },
password: HTMLElement { ... },
mybutton: HTMLElement { ... }
}
But data
itself keeps the original attributes and methods of the DOM elements. So you can still get access to data.children
or data.innerHTML
attributes, or data.onclick
event handlers, for example.
You can clone this repo and copy the main file into the appropriate folder, to serve using your server:
$ git clone
$ cp dom2object/dist/dom2object.js /path/to/my/html/folder
You can use this library directly from jsdelivr CDN
<script src="https://cdn.jsdelivr.net/gh/dealfonso/dom2object/dist/dom2object.js"></script>
In an HTML fragment like the next one:
<div id="mydata">
<input type="text" name="username" value="johndoe" />
<input type="password" name="password" value="secret" />
<button id="mybutton">Click me!</button>
</div>
We can use DOM2Object
to get an object with the DOM tree as properties:
var data = DOM2Object("#mydata");
data.mybutton.onclick = function() {
alert(`Button clicked! ${data.username.value}:${data.password.value}`);
};
In this case, we gained access to the button with id mybutton
as a property of the data
object. Have in mind that we are getting access to the raw HTMLElement, So we can access its onclick
event handler and assign a new function to it.
Then we can use the data
object to access the other elements in the DOM tree, like the username
and password
inputs. But, as they are also HTMLElements, we can access their attributes and methods (in the example, we are getting value
).
The expression is equivalent to the following one:
var data = {
username: document.querySelector("#mydata input[name='username']"),
password: document.querySelector("#mydata input[name='password']"),
mybutton: document.querySelector("#mydata button[id='mybutton']")
};
But we also keep access to the root object's attributes and methods, like data.children
or data.innerHTML
.
In case of nested objects, the library will create a new object for each named child. For example, in the following HTML fragment:
<div id="mydata2">
<div id="mainData">
<input type="text" name="name" value="John">
<input type="text" name="surname" value="Doe">
</div>
<div id="userData">
<input type="text" name="username" value="johndoe">
<input type="password" name="password" value="secret">
</div>
<button id="mybutton">Click me!</button>
</div>
If we execute data = DOM2Object("#mydata2")
we will get an object with an structure like the next one (but keeping the access to the attributes and methods of data
):
data = {
mainData: {
name: HTMLElement { ... },
surname: HTMLElement { ... }
},
userData: {
username: HTMLElement { ... },
password: HTMLElement { ... }
},
mybutton: HTMLElement { ... }
}
So it is possible to access the name
input as data.mainData.name
or data["mainData"]["name"]
as in the following example:
var data = DOM2Object("#mydata2");
data.mybutton.onclick = function() {
alert(`Button clicked! ${data.mainData.name.value}:${data.userData.password.value}`);
};
The default behaviour of the library is to ignore anonymous elements. Anonymous elements are those that don't have a name or an id. For example, in the following HTML fragment:
<div id="mydata3">
<div class="nameData">
<input type="text" name="name" value="John">
<input type="text" name="surname" value="Doe">
</div>
<div class="userData">
<input type="text" name="username" value="johndoe">
<input type="password" name="password" value="secret">
</div>
<button id="mybutton">Click me!</button>
</div>
If we execute data = DOM2Object("#mydata3")
we will get an object with an structure like the next one:
data = {
mybutton: HTMLElement { ... }
}
This is because both div
elements don't have a name or an id. So they are ignored.
We can make that the library acquires the children of anonymous elements by passing true
as second parameter to DOM2Object
. In that case, the child elements will be associated to the first parent that has a name or an id. If we make the call data = DOM2Object("#mydata3", true)
we will get an object with an structure like the next one:
data = {
name: HTMLElement { ... },
surname: HTMLElement { ... },
username: HTMLElement { ... },
password: HTMLElement { ... },
mybutton: HTMLElement { ... }
}
Both use cases may coexists. For example, in the following HTML fragment:
<div id="mydata4">
<div id="nameData">
<input type="text" name="name" value="John">
<input type="text" name="surname" value="Doe">
</div>
<div class="userData">
<input type="text" name="username" value="johndoe">
<input type="password" name="password" value="secret">
</div>
<button id="mybutton">Click me!</button>
If we execute data = DOM2Object("#mydata4", true)
we will get an object with an structure like the next one:
data = {
nameData: {
name: HTMLElement { ... },
surname: HTMLElement { ... }
},
username: HTMLElement { ... },
password: HTMLElement { ... },
mybutton: HTMLElement { ... }
}
NOTE: In a common use of the library all the details contained in this section can be ignored in most of cases, but it is important to know them in case you want to use the library in a more advanced way.
The object returned by DOM2Object
is a proxy object. This means that the object itself is not the HTMLElement, but a proxy that will redirect the calls to the HTMLElement. This is done to avoid the problem of the HTMLElements being updated in the DOM tree, but the object properties not being updated.
So it may occurr a conflict if you use HTMLElements with an id or a name that is the same as the name of an attribute or method of the HTMLElement (it is extrange, but it may happen). In that case, the named HTMLElement will substitute the existing attribute or method in the proxy object.
e.g.:
<div id="mydata">
<input type="text" name="children" value="johndoe" />
<input type="password" name="innerHTML" value="secret" />
</div>
<script>
var data = DOM2Object("#mydata");
console.log(data.children.value);
</script>
In this case, the data.children
property will be the HTMLElement with name="children"
, and the data.innerHTML
property will be the HTMLElement with name="innerHTML"
, instead of the legacy attributes of the children
and innerHTML
attributes from the div
element.
If this case happens and it is needed to access the legacy attributes, you can use the
data._el.children
anddata._el.innerHTML
attributes.
Appart from the standard HTMLElement attributes and methods, the proxy object will also have the following attributes:
- _el: the original HTMLElement.
- _children: an object with the named children of the HTMLElement (the keys are the name or id and the values are the raw objects).
- _childrenNames: an array with the names of the children of the HTMLElement. It is the same as
Object.keys(_children)
.
If an object has these properties, that means that it has named children and thus it will be a proxy. If it doesn't have these properties, it will be a raw HTMLElement.
The main function is DOM2Object
, which receives a DOM element or a CSS selector and returns an object with the DOM tree as properties.
DOM2Object(elementOrSelector, acquireChildrenFromAnonymous = false);
- elementOrSelector: a DOM element or a CSS selector.
- acquireChildrenFromAnonymous: a boolean value indicating if the children of anonymous elements should be acquired. Default:
false
.
The DOM2Object
function also has the following attributes and methods:
DOM2Object.version
: contains the version of the library.DOM2Object.multiple(elements, acquireChildrenFromAnonymous = false)
: a function that receives an array of DOM elements or CSS selectors and returns an array of objects with the DOM tree as properties.- elements: an array of DOM elements or CSS selectors, or a single selector may select multiple objects in the DOM (e.g.
div
). Even if associated, the result will be flattened to a single array. - acquireChildrenFromAnonymous: a boolean value indicating if the children of anonymous elements should be acquired. Default:
false
.
- elements: an array of DOM elements or CSS selectors, or a single selector may select multiple objects in the DOM (e.g.