You can see

How to get elements

Add, delete, change and check nodes

DOM operates across threads

Have to say

Here is not a layman, this is the beginning of programmers.

— Source: Hungry Man Valley

DOM programming

JS uses Document to operate web pages, which is the Document Object Model.

So what is DOM, which is one way of abstracting a web page into a Document object and manipulating it is DOM

  • A web page is a tree

Take a look at the code structure

Look at each node in the tree

How does JS manipulate this tree

The browser just adds a Document to the window

  • JS uses Document to manipulate web pages

That’s the Document Object Mod, DOM

  • The DOM is difficult to use

The API is long and hard to use and has to be wrapped

d


Get elements, also known as tags

Gets the API for any element

1. Window. idxxx or direct idxxx

2. Document.getelementbyld (‘idxxx’) can be used if id conflicts with global variables

3. Document. GetElementsByTagName (‘ div ‘) [0] find all tags called div elements, only can be indexed to manipulate the corresponding div. Such as

4. Document. GetElementsByClassName () ‘red’ [0] according to the class name of the class to obtain, such as the name of the class is a class for red label use subscript get, 0 subscript that first element.

5. Document. querySelector(‘#idxxx’) can be written as complex as CSS selectors, such as a span within a div that is the second son of the div

Document. QuerySelectorAll (‘ red ‘) [0] find all meet the elements of this condition

  • Use which one

QuerySelector and querySelectorAll are used for work, and getElement(s)ByXXX is used for compatibility with IE

Get specific elements

  • Gets the HTML root element

Document. The documentElement so long

: if you hit it the tag name of the document. The documentElement. TagName from HTML element tag name

You’ll notice that the HTML tag, which was originally in lower case, becomes uppercase HTML when you print it out with DOM.

  • Get the head element

Document. The head

  • Get the body element

Document. The body

  • Get Windows (Windows are not elements)

The window

Window is not a tag, but we do get it sometimes, and then we can add event listeners

  • Get all elements

Document. All

You can see how many tabs there are on the current page.

IE write, can be used to determine whether the browser is IE. If (document.all){console.log(‘ Ie browser ‘); }else{console.log(‘ other browsers ‘) can only be run in IE; }

This document.all is an oddity and can be considered the sixth Falsy value. Other browsers have a common convention that, in order to oppose IE, whenever you see oucument.all, you will consider it false, and then you can execute the code that other browsers should execute.

What is the element that you get

All the elements we get are obviously an object, and we need to figure out what properties it has and what its prototype is.

Catch a div object to look at the let div = document. The getElementsByTagName () ‘div’ [9]. Then use console.dir(div1) to look at the prototype chain. You can see a chain of six prototypes

A six-level prototype chain of elements

The above first

  • HTMLDivElement. Prototype

There are attributes common to all divs, so don’t bother looking.

  • HTMLElement. Prototype

There are attributes common to all HTML tags, so don’t bother looking

  • Element. Prototype

These are common attributes for all XML and HTML tags, so you wouldn’t think that browsers could only display HTML

  • The fourth layer is Node. Prototype

Inside these are attributes common to all nodes, including XML tag text comments, HTML tag text comments, and so on

  • EventTarget. Prototype

The most important function property is addEventListener

  • The last layer of prototypes is Object.prototype

Nodes? Element? Stupid can’t tell the difference

So if you type in nodeType on any node, you can get the node type of the node, the element, the text and so on, the element is just a tag, it’s just a different name.

  • Nodes Nodes include the following types

MDN is fully described, x.nodetype gets a number

1 represents the Element Element, also known as Tag

3 indicates Text

8 indicates comments

9 indicates the Document

11 indicates the DocumentFragment

Remember 1 and 3

Figure sample


Add, delete, change and check nodes

The programmer’s destiny is to add, delete, change and check

increase

  • Create a label node

Let div1 = document. The createElement method (‘ div ‘)

Document. The createElement method (‘ style ‘)

Document. The createElement method (‘ script ‘)

Document. The createElement method (‘ li ‘)

Use jQuery, Vue, react

  • Create a text node

Text1 = document.createTextNode(‘ Hello ‘)

  • Insert text inside the tag

Div1.appendchild (text1) — Interface provided by Node

Div1. innerText= ‘hello’ or div1.textContent= ‘Hello’ — the interface provided by Element

Div1.appendchild (‘ Hello ‘) cannot be used.

  • Insert into the page

The tag you create is in the JS thread by default, and you must insert it inside the head or body for it to work

With the document. The body. The appendChild (div), or, has been in the elements in the page. The appendChild (div), can put div in the corresponding position

appendChild
  • code

Suppose the page has div#test1 and div#test2

let div = document.createElement( 'div ' )
test1.appendChild(div)
test2.appendChild(div)
Copy the code
  • Where does the final div appear?

    • In test1

    • Test2 inside

    • Test1 and test2

Answer: inside test2.

An element cannot appear in two places unless it is copied.

Copy all div1 to div2 with div2 = div1.cloneNode(true). (Whether to use deep cloning, if true, all descendants of the node will be cloned, if false, only the node itself will be cloned.)

See cloneNode MDN for details.

delete

  • The two methods

Old method :parentNode. ChildChild (childNode) finds and spits the child

Such as div1 parentNode find div1 papa, then div1. ParentNode. RemoveChild (div1), with a father son to delete

You can also add back the document. The body. The appendChild (div1)…

It’s just been deleted from the tree into memory. It’s not dead yet.

New method: childNode.remove() is not compatible with IE. Same effect

  • thinking

If a node is removed from the page (DOM tree)

Can it come back to the page again?

It’s ok, just moved from the tree into memory

Delete it completely if you make it empty, memory will recycle it as garbage.

Change attributes

  • Write standard attributes

Alter ID: div1.id = “div1”

Class: div. ClassName = ‘red blue’

Class is a reserved word that cannot be added directly to div. Class, so use className to add class

ClassName: div. ClassName += ‘red’

Class: div.classlist.add (‘red’) new API, classList can tell you what classes are and how long they are.

Style: div. Style = ‘width: 100px; color: blue; ‘(The original is gone, overwritten)

Div. Style. width = ‘200px’

Case: div. Style. BackgroundColor = ‘white’ is turn – followed by letters to uppercase. Or div. Style [‘ background – color ‘].

X = ‘dw'(div.dataset. Dataset. Add data- to the name of the property to retrieve the content from the dataset. Change directly = ‘to change ‘) custom property.

Div. SetAttribute (‘data-x’, ‘test’) adds a data-x attribute to the div attribute with the content test. You can get the content by div.getattribute (‘data-x’)

  • Read standard attributes

Basically one to one in the name

Div. ClassList/a.href This can be problematic, example

Div.getattribute (‘class’)/a.getAttribute(‘href’) gets the original value

Either method works, but the values may be slightly different

Change the event handler function

You can also change properties that start with on

  • Div. onclick defaults to null

Code sample

By default, nothing happens when you click on div. Onclick, but if you change div. Onclick to fn, then when you click on div, the browser finds that the onclick for that div exists, and calls the onclick function. And the browser calls fn.call(div, event) with call(trigger element reference, event details). In fn. Call (div, event), div is called this, and the first argument is event, which contains all the information about the clicked event, such as the coordinates. The function is called so that an argument can be passed.

  • div.addEventListener

Onclick is an updated version of div.onclick. You can only write one function, the second one overwrites the previous one. AddEventListener can write an infinite number of functions.

To change the content

Change a son

  • Modify text content

Div. InnerText = ‘XXX’ written by IE

Div.textcontent = ‘XXX’ standard browser

There is little difference between the two, browsers support both

  • To change the HTML content

Div.innerhtml = ‘<strong> Important content </strong>’ Too many characters (around 2W characters) can block the browser

  • To change the label

Div. InnerHTML = “// Empty it

Div. AppendChild (div2)/ add content

To my father

  • Looking for a new dad?

Newparent.appendchild (div) puts itself in the newParent node by calling appendChild

Just like that, just disappear from where you came from and go to your new dad’s house

check

  • Look up dad

Node. ParentNode or node. ParentElement

  • Check the grandpa

Node. ParentNode. ParentNode dad dad called grandpa and so on

  • Check the offspring

Node.childnodes (including text nodes) or Node.children (excluding text nodes)

Console. log(node.childnodes.length) prints the length of childNodes. You may get something you don’t want. Spaces count as a length (including text nodes). Code sample

Node. children (not including text nodes)

  • Think about:

Do both change in real time when the offspring change?

All update in real time, but querySelectorAll doesn’t update in real time

  • Brothers and Sisters

Node. ParentNode..childnodes should not only eliminate all text nodes also ruled out yourself

Node. parentNode.children also exclude themselves

To get your siblings, you need to get all of your dad’s children, and then go through the children and exclude yourself

  • To see the boss

Look at the first son

Node. The firstChild

  • Look at last

Node. LastChild

  • View previous older brother/sister

Node.previoussibling It is possible to view text nodes

Node. PreviousElementSibling look for the element’s brother

  • Check out the next sibling

Node. NextSibling

  • Iterate over all the elements in a div

Traverses the current node before traversing the child nodes

travel = (node, fn) =>{ fn(node) if(node.children){ for(let i=0; i<node.children.length; i++){ travel(node.children[i], fn) } } } travel(div1, (node) =>console.log(node))Copy the code

DOM is cross-threaded

Browsers are divided into rendering engines and JS engines, which run on different threads and are not related to each other

Cross-thread operation

  • Each thread does its job

The JS engine cannot manipulate pages, only JS

Rendering engines cannot manipulate JS, only pages

Document. The body. The appendChild (div1)

This is a JS call, the theory can only exist in memory, why can appear on the screen, how does this JS sentence change the page?

  • Cross-thread communication

When the browser finds that JS has added a div1 object to the body

The browser tells the rendering engine to add a new div element to the page as well

The new div element copies all the attributes of the DIV1 object

Illustrates cross-thread operations

The time spent on browser discovery and notification makes updating div seem slower than everything else

The complete process of inserting a new label

  • Before DIV1 goes into the page

All operations you do to DIV1 belong to the JS thread

  • When you put DIV1 on the page

The browser will discover the intent of JS

The render thread is told to render the div1 element on the page

  • Put div1 after the page

Anything you do to DIV1 can trigger a re-render

Div1.id = ‘newld’ may or may not be re-rendered

Div1.title = ‘new’ may or may not be re-rendered. You can look at CSS Tricks

If you perform multiple operations on div1 in a row, the browser may or may not merge them into one operation (mentioned in the previous animation, code example).

For example test.classlist.add (‘ start’)

//test. clientWidth // This sentence seems useless, but it will trigger the rerender, and the animation will work

Test.classlist.add (‘end ‘) changes the width

Attribute synchronization

  • Standard properties

Changes to div1’s standard properties are synchronized to the page by the browser. Such as ID, className, title, etc

  • Data – * attributes

Same as above

  • Nonstandard attribute

Changes to nonstandard attributes that are not data will only stay in the JS thread and will not be synchronized to the page

For example, the X property, sample code

  • revelation

If you have custom attributes that you want to synchronize to the page, use data- as a prefix

graphic

Property v.s.Attribute

  • The property attribute

Div1 property(id is its property, className is its property) div1 property(id is its property, className is its property)

  • Attribute is also an attribute

Div1 is the attribute of the render engine’s tag (for example, id= “, where id= “is its attribute) called an attribute

  • The difference between

Most of the time, property and attribute values with the same name are equal

But if it’s not a standard property, then it’s only going to be equal at the beginning

Note that attribute only supports strings

Property supports strings, booleans, and so on


Is DOM slow?

The Internet says that DOM operation is slow, in fact, only slower than JS operation, DOM operation is much faster than network request.

For this part of the content, you can read and refer to some articles:

  • Why is DOM slow

  • Why is DOM still so slow after 10 years of effort