innerHTML Content between html tags The innerHTML property allows to get the HTML inside the element as a string Can be modified If innerHTML inserts a <script> tag into the document – it becomes a part of HTML, but doesn’t execute
document.body.innerHTML = 'The new BODY!' // replace it
document.body.innerHTML += " How goes?" // be careful, all images and other resources will be reloaded.
outerHTML full HTML of the element That’s like innerHTML plus the element itself outerHTML assignment does not modify the DOM element, but removes it from the DOM and inserts the new HTML in its place
let btn = document.querySelector('button')
btn.innerHTML // "Test"
btn.outerHTML // "<button id="start-test-btn" data-my-tip="... class="no-cursor">Test</button>"
btn.outerHTML = '<p>A new element</p>'
btn // #start-test-btn // still the same el, even it is removed from DOM and screen
data & nodeValue content of a non-html element node (text, comment) property is only valid for element nodes other node types, such as text nodes, have their counterpart: nodeValue and data properties can be modified data & nodeValue are almost the same, we’ll use data, because it’s shorter.
document.body.childNodes[13].data // " tooltip for hovering an el " // comment node
textContent provides access to the text inside the element: only text without any tags writing into it puts the text inside the element, with all special characters and tags treated exactly as text reading such text is rarely needed Writing to textContent is much more useful, because it allows to write text the “safe way”
document.querySelector("#user-logged").textContent // "sherbsherb@gmail.com"
document.querySelector("#user-logged").textContent = "3007887@gmail.com"
hidden elem.hidden = true - same as style="display:none"
document.querySelector("button").hidden = true // btn disappeared
document.querySelector("button").hidden = false // btn appeared
document.querySelector("button").hidden // false
value
input15.value // "xxx"
id Most standard HTML attributes of element nodes automatically become properties of DOM objects But the attribute-property mapping is not one-to-one!
// tag
<body id="page"></body>
// DOM object has
body.id="page"
type
input15.type // "text"
href
document.querySelectorAll('a')[2].href // "https://myvocab.org/"
Custom properties We can add custom properties & methods
document.body.myData = { title: 'Imperator' }
document.body.myData.title // Imperator
document.body.sayTagName = function() { alert(this.tagName) }
document.body.sayTagName() // BODY
And even modify built-in prototypes
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 HTML has tags with attributes browser parses a page & constructs the DOM tree (objects) for tags with properties browser recognizes STANDARD html attributes and creates DOM properties from them it is not the case for non-standard attributes standard attribute for one element can be unknown for another one but can be accessed by HTML attributes are case-insensitive getAttribute('id') = getAttribute('ID') values are always strings We can assign anything to an attribute, it becomes a string All attributes including ones that we set are visible in outerHTML
el.hasAttribute("name") // checks for existence
el.getAttribute("name") // gets the value
el.setAttribute("name", value) // sets the value
el.removeAttribute("name") // removes the attribute
el.attributes // collection of objects // 7 attributes // iterable
setAttribute attribute update leads to property update and backwards
let input = document.querySelector('input')
input.setAttribute('id', 'xxx')
input.id // xxx (updated)
input.id = 'newId'
input.getAttribute('id') // newId (updated)
Except for input.value synchronizes only from attribute → to property, but not back
let input = document.querySelector('input')
input.setAttribute('value', 'text')
input.value // text
input.value = 'newValue'
input.getAttribute('value') // text (not updated!)
Attribute types most properties are strings sometimes booleans or objects checked
let checkbox = document.querySelector('input[type="checkbox"]')
checkbox.checked // true // boolean value
checkbox.getAttribute('checked') // null
style
let div = document.getElementById('fixed-horizontally')
div.getAttribute('style') // "left: 645px;"
div.style // CSSStyleDeclaration {0: "left", … , left: "645px", …} // object
DOM property vs HTML attribute sometimes DOM prop differs from HTML atr
let link = document.querySelector('#left-corner a')
link.getAttribute('href') // "https://myvocab.org"
link.href // "https://myvocab.org/"
dataset, data-* non-standard attributes are used to pass custom data from HTML to JS or to “mark” HTML-elements for JS to avoid conflicts with custom atr use data-* they are available in the dataset property for ex., if an el has an attr "data-about", it’s available as elem.dataset.about Multi word attributes like data-order-state become camel-cased: dataset.orderState
<span id="site-url" data-my-tip="Open in a new tab">
let el = document.getElementById('site-url')
el.dataset // DOMStringMap {myTip: "Open in a new tab"}
el.dataset.myTip // "Open in a new tab"
el.dataset.myTip = "xxx" // update
el.dataset.myTip // "xxx"