The original
DOM manipulation is not as difficult as you might think.
A preliminary introduction
Many Web developers think DOM is really hard (or slow) and that you need a lot of frameworks to tame it. Then they spend a lot of time learning the framework, and after a year or two, another framework becomes popular, and you have to learn everything from scratch. Repeat this a few times, and JavaScript fatigue sets in. Not to mention a whole lot of dependencies. Would you believe me if I told you DOM wasn’t that difficult? If it’s cool not to have to rely on third-party libraries to master DOM, would you give DOM a second chance? Let’s take a look:
DOM is not that hard and especially not slow.
First, I’ll show you some basic techniques from my own personal library RE:DOM
Create the element
To create an HTML element, you need to use the document.createElement(tagName) method:
const h1 = document.createElement('h1')
// Copy the code
Modify text content
If the HTML element has no content, it is empty:
h1.textContent = 'Hello world! '/ /Hello world!
Copy the code
Attributes
h1.setAttribute('class', 'hello')
// Hello world!
Copy the code
To manage classes, use the element.className attribute
h1.className = 'hello'
// Hello world!
Copy the code
However, the best way is to use classList
h1.classList.add('hello')
// Hello world!
h1.classList.remove('hello')
// Hello world!
Copy the code
To set the ID of an element, you can use attribute or set the ID attribute directly
h1.setAttribute('id', 'hello-world')
h1.id = 'hello-world'
// Hello world!
Copy the code
If you’re unsure whether to use Attributes or properties, use Attributes, in addition to form element states like Value and Checked
You cannot use element.setAttribute(someBoolean, false) to set bool values except for the following:
input.checked = true
//
input.checked = false
// Input. SetAttribute (" checked ", "') / /
input.removeAttribute('checked')
// Copy the code
Add elements
document.body.appendChild(h1)
// Hello world!
Copy the code
Remove elements
document.body.removeChild(h1)
// Copy the code
Look for the element
- document.getElementById(id)
- element.childNodes[i]
- element.firstChild === element.childNodes[0]
- element.lastChild === element.childNodes[element.childNodes.length – 1]
- element.getElementsByTagName(tagName)
- element.getElementsByClassName(className)
- element.querySelector(query)
- element.querySelectorAll(query)
Note: GetElementsByTagName, getElementsByClassName, and querySelectorAll return not an array, but a NodeList, so you can’t iterate with ES5’s array iterator. Here’s a little bit about NodeList
Insert elements between elements
/*
*
*
*
*/
document.body.insertBefore(h1, document.body.firstChild)
/*
* Hello world!
* * * /Copy the code
Create a lot of elements
const data = [
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
const table = document.createElement('table')
data.forEach(row => {
const tr = document.createElement('tr')
row.forEach(cell => {
const td = document.createElement('td')
td.textContent = cell
tr.appendChild(td)
})
table.appendChild(tr)
})
document.body.appendChild(table)Copy the code
Update a set of elements
const table = document.createElement('table') document.body.appendChild(table) updateTable(table, [ [ 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8, 9 ] ]) setTimeout(() => { updateTable(table, [ [ 1, 2, 3, 4 ], [ 5, 6, 7 ], [ 8, 9 ] ]) }, 1000) function updateTable (table, data) { const rowLookup = table._lookup || (table._lookup = []) setChildren(table, updateRows(rowLookup, data)) } function updateRows (rowLookup, rows) { return rows.map((row, y) => { const tr = rowLookup[y] || (rowLookup[y] = document.createElement('tr')) const cellLookup = tr._lookup || (tr._lookup = []) setChildren(tr, updateCells(cellLookup, row)) return tr }) } function updateCells (cellLookup, cells) { return cells.map((cell, x) => { const td = cellLookup[x] || (cellLookup[x] = document.createElement('td')) td.textContent = cell return td }) } function setChildren (parent, children) { let traverse = parent.firstChild for (let i = 0; i < children.length; i++) { const child = children[i] if (child == null) { return } if (child === traverse) { traverse = traverse.nextSibling } else if (traverse) { parent.insertBefore(child, traverse) } else { parent.appendChild(child) } } while (traverse) { const next = traverse.nextSibling parent.removeChild(traverse) traverse = next } }Copy the code
What kind of magic is this? Two things are happening here:
- 1. There is a hidden element, element._lookup = [], which looks for child elements (possibly an element with an ID) and uses this method to reuse existing DOM and update them
- 2. The setChildren(parent, children) method has a list of child elements
You can also mount/unmount child elements using the setChildren method
setChildren(login, [
email,
!forgot && pass
])Copy the code
Followed by an AD for the author’s RE:DOM.