Due to the rise and improvement of Vue and React technology stacks, many times the front-end is no longer writing pure native JS and a large number of DOM operations, and those original DOM operations have faded into our view.

Preliminary memories

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.

Create the element

Let’s start creating the DOM element. To create the DOM element we need to use the document.createElement(tagName) method

let h1Ele = document.createElement("h1")
Copy the code

Modify text content

h1Ele.textContent = "hello dom"
Copy the code

Attributes

h1Ele.setAttribute("class"."hello")
Copy the code

To manage classes, use the element.className attribute

h1Ele.className = "hello"
Copy the code

And then there’s an even easier way to do it which is the classList method

h1Ele.classList.add("hello")
h1Ele.classList.remove("hello")
Copy the code

If you’re unsure whether to use Attributes or properties, use Attributes, except that some form element state like Value or Checked needs to be used

You cannot use element.setAttribute(someBoolean, false) to set bool values except for the following:

input.value = "ture"
input.setAttribute("value"."ture")
input.checked = false
Copy the code

Add elements

document.body.append(input)
Copy the code

Remove elements

document.body.remove(input)
Copy the code

To find the time

document.getElementById(id)
document.getElementsByClassName(className)
document.getElementsByName(name)
document.getElementsByTagName(tagName)
document.querySelector(query)
document.querySelectorAll(query)
element.childNodes[i]
element.lastChild
element.firstChild
Copy the code

Insert nodes between elements

document.body.insertBefore(h1Ele, document.body.firstChild)
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(col= > {
        const td = document.createElement("td")
        td.textContent = col
        tr.appendChild(td)
    })
    table.appendChild(tr)
})
document.body.appendChild(table)
Copy the code

The operation to update an element


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

The idea is derived from RE:DOM open source

Welcome to wechat search xiaoying said to learn and explore.