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"