[全面教程]Javascript DOM操作(一)

js的DOM操作大致可以分为几个section介绍,从DOM的基础概念,选择元素,遍历元素,控制元素,控制属性,处理事件等等.

DOM

document是根节点,document.doctype是文档节点,document.documentElement是元素节点

node type

ConstantValueDescription
Node.ELEMENT_NODE1An Element node like <p> or <div>.
Node.TEXT_NODE3The actual Text inside an Element or Attr.
Node.CDATA_SECTION_NODE4A CDATASection, such as <!CDATA[[ … ]]>.
Node.PROCESSING_INSTRUCTION_NODE7A ProcessingInstruction of an XML document, such as <?xml-stylesheet … ?>.
Node.COMMENT_NODE8A Comment node, such as <!-- … -->.
Node.DOCUMENT_NODE9A Document node.
Node.DOCUMENT_TYPE_NODE10A DocumentType node, such as <!DOCTYPE html>.
Node.DOCUMENT_FRAGMENT_NODE11A DocumentFragment node.

利用node type对不同的node进行区分

  • 文档节点( document):9,对应常量 Node.DOCUMENT_NODE
  • 元素节点( element):1,对应常量 Node.ELEMENT_NODE
  • 属性节点(attr):2,对应常量 Node.ATTRIBUTE_NODE
  • 文本节点(text):3,对应常量 Node.TEXT_NODE
  • 文档片断节点(DocumentFragment):11,对应常量 Node.DOCUMENT_FRAGMENT_NODE
  • 文档类型节点(DocumentType):10,对应常量 Node.DOCUMENT_TYPE_NODE
  • 注释节点(Comment):8,对应常量 Node.COMMENT_NODE

nodeName && nodeValue

nodeName会根据nodetype的值而不同,

不同节点的nodeName属性值如下。

  • 文档节点(document): #document
  • 元素节点(element):大写的标签名
  • 属性节点(attr):属性的名称
  • 文本节点(text): #text
  • 文档片断节点(DocumentFragment): #document-fragment
  • 文档类型节点(DocumentType):文档的类型
  • 注释节点(Comment): #comment

只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue可以返回结果,其他类型的节点一律返回null。同样的,也只有这三类节点可以设置nodeValue属性的值,其他类型的节点设置无效。

Node relations

JavaScript DOM Node Relationships

使用firstChild,parentNode,nextSibling等遍历查找节点.parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)

Node.prototype.parentElement

parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null

if (node.parentElement) {  node.parentElement.style.color = 'red';}

上面代码中,父元素节点的样式设定了红色。

由于父节点只可能是三种类型:元素节点、文档节点(document)和文档片段节点(documentfragment)。parentElement属性相当于把后两种父节点都排除了

Element与Node

An element is a node with a specific node type Node.ELEMENT_NODE, which is equal to 1.

查找元素

document.getElementById()

The document.getElementById() method returns an Element object that represents an HTML element with an id that matches a specified string.

document.getElementsByName()

The getElementsByName() accepts a name which is the value of the name attribute of elements and returns a live NodeList of elements.

document.getElementsByTagName()

The getElementsByTagName() method accepts a tag name and returns a live HTMLCollection of elements with the matching tag name in the order which they appear in the documen

getElementsByClassName

The getElementsByClassName() method returns an array-like of objects of the child elements with a specified class name.

document.getElementsByClassName("body-root")

  1. HTMLCollection [body.body-root.h-full.fixed.top-0.bottom-0.left-0.right-0.overflow-hidden.leading-[1.414].text-[14p…]

    1. 0: body.body-root.h-full.fixed.top-0.bottom-0.left-0.right-0.overflow-hidden.leading-[1.414].text-[14px].select-none.icon-s.chat-default
    2. length: 1
    3. [[Prototype]]: HTMLCollection

querySelector querySelectorAll

The querySelectorAll() method returns a static NodeList of elements that match the CSS selector. If no element matches, it returns an empty NodeList

注意Note that the NodeList is an array-like object, not an array object. However, in modern web browsers, you can use the forEach() method or the for...of loop.

. 注意To convert the NodeList to an array, you use the Array.from()

[attribute] 用于选取带有指定属性的元素。
[attribute=value] 用于选取带有指定属性和值的元素。
[attribute~=value] 用于选取属性值中包含指定词汇的元素。
[attribute|=value] 用于选取带有以指定值开头的属性值的元素,该值必须是整个单词。
[attribute^=value] 匹配属性值以指定值开头的每个元素。
[attribute$=value] 匹配属性值以指定值结尾的每个元素。
[attribute*=value] 匹配属性值中包含指定值的每个元素

可以用于获取伪元素(::)和伪类(:).

伪类是捕获的本身,比如a:visited a:nth-child

伪元素捕获的后面的p::first-letter

NodeList与HTML collectin

遍历元素

ParentNode

The parentNode is read-only.

The Document and DocumentFragment nodes do not have a parent. Therefore, the parentNode will always be null.

If you create a new node but haven’t attached it to the DOM tree, the parentNode of that node will also be null.

此外还有parentElement返回元素节点.

Get child element

let firstChild = parentElement.firstChild;

firstElementChild

firstChild可能会得到一个#text文本节点.

childNodes和Children

  • The firstChild and lastChild return the first and last child of a node, which can be any node type including text node, comment node, and element node.
  • The firstElementChild and lastElementChild return the first and last child Element node.
  • The childNodes returns a live NodeList of all child nodes of any node type of a specified node. The children return all child Element nodes of a specified node.

Get Siblings element

nextElementSibling

previousElementSibling

nextSibling

previousSibling

创建元素

document.createElement()

The document.createElement() accepts an HTML tag name and returns a new Node with the Element type.

通过div.innerHTML = '

CreateElement example

';像其中再添加html.

或者通过textContent或innerText修改文本内容

document.body.appendChild(div);

如果参数节点是 DOM 已经存在的节点,appendChild()方法会将其从原来的位置,移动到新位置

  • Element.append()允许追加 DOMString 对象,而 Node.appendChild() 只接受 Node 对象。
  • Element.append() 没有返回值,而 Node.appendChild() 返回追加的 Node 对象。
  • Element.append() 可以追加多个节点和字符串,而 Node.appendChild() 只能追加一个节点。
let div = document.createElement('div');
div.id = 'content';
div.className = 'note';
div.innerHTML = '<p>CreateElement example</p>';

document.body.appendChild(div);
创建文本元素
let text = document.createTextNode('CreateElement example');
div.appendChild(text);

textContent

the textContent property returns the concatenation of the textContent of every child node, excluding comments (and also processing instructions).

innerText

On the other hand, the innerText takes the CSS style into account and returns only human-readable text

the hidden text and comments are not returned.

由于innerText属性使用最新的CSS来计算文本,访问它将触发reflow,这在计算上是昂贵的。 当网页浏览器需要再次处理和绘制部分或全部网页时,就会发生reflow。

innerHTML

  • Use innerHTML property of an element to get or set HTML contained within the element.
  • The innerHTML property returns the current HTML source of the element, including any change that has been made since the page was loaded.
  • Do not use innerHTML to set new contents that you have no control to avoid a security risk
Using DocumentFragment for composing DOM Nodes
let div = document.querySelector('.container');

for (let i = 0; i < 1000; i++) {
   let p = document.createElement('p');
   p.textContent = `Paragraph ${i}`;
   div.appendChild(p);
}

This code results in recalculation of styles, painting, and layout every iteration. This is not very efficient.

所以使用DocumentFragment

let div = document.querySelector('.container');

// compose DOM nodes
let fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
   let p = document.createElement('p');
   p.textContent = `Paragraph ${i}`;
   fragment.appendChild(p);
}

// append the fragment to the DOM tree
div.appendChild(fragment);

In this example, we composed the DOM nodes by using the DocumentFragment object and append the fragment to the active DOM tree once at the end.

A document fragment does not link to the active DOM tree, therefore, it doesn’t incur any performance.

let fragment = new DocumentFragment();
-----
let fragment = document.createDocumentFragment();
JS DocumentFragment
JS DocumentFragment

This DocumentFragment inherits the methods of its parent, Node, and also implements those of the ParentNode interface such as querySelector() and querySelectorAll().

after

The after() is a method of the Element type. The element.after() method allows you to insert one or more nodes after the element

To insert multiple nodes after an element, you pass the nodes to the after() method as follows

`

The after() method also accepts one or more strings. In this case, the after() method treats the strings as Text nodes

Element.after(node1, node2, ... nodeN)
append
Differencesappend()appendChild()
Return valueundefinedThe appended Node object
InputMultiple Node ObjectsA single Node object
Parameter TypesAccept Node and DOMStringOnly Node
  • Use the parentNode.append() method to append a set of Node objects or DOMString objects after the last child node of the parentNode.
parentNode.append(...nodes);
parentNode.append(...DOMStrings);

prepend
parentNode.prepend(...nodes);
parentNode.prepend(...DOMStrings);

The prepend() method inserts a set of Node objects or DOMString objects before the first child of a parent node

InsertAdjacentHTML

The insertAdjacentHTML() method parses a piece of HTML text and inserts the resulting nodes into the DOM tree at a specified position.

比较全面的插入方法

insertAdjacentHTML() 方法将指定的文本解析为 Element 元素,并将结果节点插入到 DOM 树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接使用 innerHTML 操作更快。

insertAdjacentText() 方法将一个给定的文本节点插入在相对于被调用的元素给定的位置

The positionName is a string that represents the position relative to the element. The positionName accepts one of the following four values:

  • 'beforebegin': before the element
  • 'afterbegin': before its first child of the element.
  • 'beforeend': after the last child of the element
  • 'afterend': after the element

Like the innerHTML, if you use the user input to pass into the insertAdjacentHTML() method, you should always escape it to avoid security risk.

  • Use the insertAdjacentHTML() method to insert a text as Nodes into the DOM tree at a specified position.
  • Always escape the user input text that you pass into the insertAdjacentHTML() method to avoid security risk.

replaceChild

In this method, the newChild is the new node to replace the oldChild node which is the old child node to be replaced

Use Node.replaceChild() to replace a child element of a node by a new element.

Element.replaceChildren() 方法将一个 Node 的后代替换为指定的后代集合。这些新的后代可以为 DOMStringNode 对象

cloneNode

The cloneNode() is a method of the Node interface that allows you to clone an element:

let clonedNode = originalNode.cloneNode(deep);

克隆一个节点,会拷贝该节点的所有属性,但是会丧失addEventListener方法和on-属性(即node.onclick = fn),添加在这个节点上的事件回调函数。

该方法返回的节点不在文档之中,即没有任何父节点,必须使用诸如Node.appendChild这样的方法添加到文档之中

removeChild()

The removeChild() returns the removed child node from the DOM tree but keeps it in the memory, which can be used later.

The removeChild() returns the removed child node from the DOM tree but keeps it in the memory, which can be used later.Use parentNode.removeChild() to remove a child node of a parent node.

  • The parentNode.removeChild() throws an exception if the child node cannot be found in the parent node.

remove删除节点本身.

InsertBefore

To insert a node before another node as a child node of a parent node, you use the parentNode.insertBefore() method

The insertBefore() returns the inserted child node.

  • Use the parentNode.insertBefore() to insert a new node before an existing node as a child node of a parent node.

insertAfter() 本身没有这个函数

function insertAfter(newNode, existingNode{
    existingNode.parentNode.insertBefore(newNode, existingNode.nextSibling);
}
  • JavaScript DOM hasn’t supported the insertAfter() method yet.
  • Use the insertBefore() method and the nextSibling property to insert a new before an existing node as a child of a parent node.

如果要插入的节点是DocumentFragment类型,那么插入的将是DocumentFragment的所有子节点,而不是DocumentFragment节点本身。返回值将是一个空的DocumentFragment节点

Attributes

Note that element.attributes is a NamedNodeMap, not an Array, therefore, it has no Array’s methods.

如果是html本身有的属性,直接html.attr = ''即可.

  • Attributes are specified in HTML elements.
  • Properties are specified DOM objects.
  • Attributes are converted to properties respectively.
  • Use the element.attributes property to access standard and custom attributes of an element.
  • Use the element.dataset property to access the data-* attributes.
getAttribute
  • Get the value of an attribute of a specified element by calling the getAttribute() method on the element.
  • The getAttribute() returns null if the attribute does not exist.
setAttribute
  • Use the setAttribute() to set the value of an attribute on a specified element.
  • Setting the value of a Boolean attribute to whatever value, that value will be considered to be true.
removeAttribute
  • Use the removeAttribute() to remove an attribute from a specified element.
  • Setting the value of a Boolean attribute to false will not work; use the removeAttribute() method instead.
hasAttribute
  • Use the hasAttribute() method to check if an element contains a specified attribute.

参考资料

  1. https://www.javascripttutorial.net/
  2. The Modern JavaScript Tutorial
  3. DOM - Node 接口 - 《阮一峰 JavaScript 教程》 - 书栈网 · BookStack

相信我,上面的这三份文档已经够看的了.

本文由 mdnice 多平台发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

procoder338

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值