Attributes And Properties
DOM properties
There are a lot of built-in DOM properties, but technically no one limits us, and if there aren't enough, we can add our own.
document.body.myData = {
name: "Caesar",
title: "Imperator",
};
alert(document.body.myData.title); // Imperator
document.body.sayTagName = function () {
alert(this.tagName);
};
document.body.sayTagName(); // BODY (the value of "this" in the method is document.body)
We can also modify built-in prototypes like Element.prototype
and add new methods to all elements:
Element.prototype.sayHi = function () {
alert(`Hello, I'm ${this.tagName}`);
};
document.documentElement.sayHi(); // Hello, I'm HTML
document.body.sayHi(); // Hello, I'm BODY
HTML attributes
<body id="test">
<script>
alert(document.body.id); // test
</script>
</body>
All attributes are accessible by using the following mthods:
elem.hasAttribute(name)
- checks for existenceelem.getAttribute(name)
- gets the valueelem.setAttribute(name, value)
- sets the valueelem.removeAttribute(name)
- removes the attribute
Attribute names are case-insensitive
We can assign anything to an attribute, but it becomes a string
All attributes are visible in
outerHTML
The
attributes
collection is iterable and has all the attributes of the element (standard and non-standard) as objects withname
andvalue
properties
Property-attribute synchronization
When a standard attribute changes, the corresponding property is auto-updated, and (with some exception) vice versa.
<input />
<script>
let input = document.querySelector("input");
// attribute -> property
input.setAttribute("id", "id");
alert(input.id); // id (updated)
// property -> attribute
input.id = "newId";
alert(input.getAttribute("id")); // newId (updated)
</script>
But there are exclusions, for instance input.value
synchronizes only from attribute -> property, but not back:
// attribute => property
input.setAttribute("value", "text");
alert(input.value); // text
// NOT property => attribute
input.value = "newValue";
alert(input.getAttribute("value")); // text (not updated)
DOM properties are typed
DOM properties are not always strings.
For instace, the
input.checked
property (for checkboxes) is a booleanThe
style
attribute is a string, but thestyle
property is an objectThe
href
DOM property is always a full URL, even if the attribute contains a relative URL or just a#hash
<a id="a" href="#hello">link</a>
<script>
// attribute
alert(a.getAttribute('href')); // #hello
//property
alert(a.href); // full URL in the form https://example.com/page#hello
Non-standard attributes, dataset
Sometimes non-standard attributes are used to pass custom data from HTML to JavaScript, or to mark
HTML-elements for JavaScript
<!-- mark the div to show "name" here -->
<div show-info="name"></div>
<!-- and age here -->
<div show-info="age"></div>
<script>
// the code finds an element with the mark and shows what's requested
let user = {
name: "Peter",
age: 25,
};
for (let div of document.querySelectorAll("[show-info]")) {
// insert the corresponding info into the field
let field = div.getAttribute("show-info");
div.innerHTML = user[field]; // first Pete into "name", then 25 into "age"
}
</script>
Also they can be used to style an element.
<style>
/* style rely on the custom attribute "order-state" */
.order[order-state="new"] {
color: green;
}
.order[order-state="pending"] {
color: blue;
}
.order[order-state="canceled"] {
color: red;
}
</style>
<div class="order" order-state="new">A new order.</div>
<div class="order" order-state="pending">A pending order.</div>
<div class="order" order-state="canceled">A canceled order.</div>
To avoid conflicts in development, there exist data-* attributes.
All attributes starting with
data-are reserved for programmers' use. They are available in thedataset
property
<body data-about="Elephants">
<script>
alert(document.body.dataset.about); // Elephants
</script>
</body>