0
点赞
收藏
分享

微信扫一扫

JavaScript DOM编程

若如初梘 2022-04-14 阅读 67

目录

    说明

节点

节点的类型

节点的层级

nodeName

nodeValue

节点的关系

childNodes

parentNode

 previousSibling 和 nextSibling

firstChild 和 lastChild

 hasChildNodes ()

ownerDocument

操作节点

appendChild ()

insertBefore ()

replaceChild ()

removeChild ()

cloneNode ()

normalize ()


    说明

  1. DOM:文档对象模型 Document Object Model
  2. 通过 DOM 我们可以添加、删除、修改页面的各个部分,实现交互效果。
  3. 任何 HTML 页面都可以用 DOM 表达为一个由节点构成的层级结构。
  4. 在 HTML 页面中 Document 节点就是所有节点的根节点。
  5. 而 <html> 元素则是 Document 节点的唯一子节点,我们将 <html> 元素称为文档元素。
  6. 文档元素是文档最外层的元素,其它元素都在该元素之内,在HTML页面中文档元素就是<html> 元素。

节点

  1. html 文件当中的所有内容都可以称之为是节点包括:注释、文本、标签、换行符、属性等。
  2. 在 JavaScript 中所有节点类型都继承自 Node 类型,所以所有节点类型都共享相同的基本属性和方法。
  3. 节点的类型由 JavaScript 定义在 Node 类型上的12个数值表示。

节点的类型

常量nodeType 值描述状态
Node.ELEMENT_NODE1标签节点,例如:<p> <span>
Node.ATTRIBUTE_NODE2元素属性已弃用
Node.TEXT_NODE3元素或属性中的文本内容
Node.CDATA_SECTION_NODE4XML 中的 文档中的 CDATA 部分
Node.ENTITY_REFERENCE_NODE5XML 中的 实体引用已弃用
Node.ENTITY_NODE6XML 中的 实体已弃用
Node.PROCESSING_INSTRUCTION_NODE7XML 中的 处理指令
Node.COMMENT_NODE8 注释
Node.DOCUMENT_NODE9表示整个文档 Document 也就是 DOM 树的根节点
Node.DOCUMENT_TYPE_NODE10XML中的 表示文档型网页的节点
Node.DOCUMENT_FRAGMENT_NODE11表示一个节点,但它不是 DOM 树的一部分,只相当于一个储存其它节点的变量,所以它的变化不会触发 DOM 树的重新渲染,可以通过调用 appendChild 方法来将该节点添加到 DOM 树中。
Node.NOTATION_NODE12XML 中的 代表 DTD 中声明的符号已弃用

 

节点的层级

<html>
<head>
<title>Sample Page</title>
</head>
<body>
<h1>have a good time oneself!</h1>
</body>
</html>
  • 在DOM中HTML文档可以表示为一个由节点构成的层级结构,比如上面这段代码:
    • <head> 元素是 <html> 元素的子元素
    • <html> 元素是 <head> 元素的父元素
    • <head> 元素和 <body> 元素则是兄弟元素他们有共同的父元素 <html>

  nodeType

  • 每个节点都有 nodeType 属性,表示该节点的类型。节点类型由定义在 Node 类型上的 12 个数值常量表示。
  •   <div id="box">
    <ul id="list">
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    </ul>
    </div>
    <script>
    const list = document.getElementById('list')
    console.log(list.nodeType)
    // 1
    </script>

nodeName

  • 每个节点都有 nodeName 属性,该属性表示节点的名称。
    • 元素节点的 nodeName,将返回标签名称。
    • 属性节点的 nodeName,将返回属性名称。
    • 文本节点的 nodeName,将返回 #text。
    • 文档节点的 nodeName,将返回 #document。
    • 对于其它节点类型,则会返回不同的名称。
  •   <div id="box">
    <ul id="list">
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    </ul>
    </div>
    <script>
    const list = document.getElementById('list')
    console.log(list.nodeName)
    // UL
    </script>

nodeValue

  • 文本节点的 nodeValue 属性包含文本,对于属性节点的 nodeValue 属性包含属性值。
  • 文档节点和标签节点的 nodeValue 属性是不可用的。
  • <div id="box">
    <ul id="list">
    <li id="content">aaaaa</li>
    </ul>
    </div>
    <script>
    const content = document.getElementById('content')
    console.log(content.nodeValue)
    // undefined
    console.log(content.childNodes[0].nodeValue)
    // aaaaa
    // childNodes 可以获取该标签的子元素数组从而来获得其中的 aaaaa 文本
    </script>

节点的关系

childNodes

  • 每个节点都有一个 childNodes 属性,其中包含一个 NodeList 类数组对象。
  • NodeList 用于有序的,存储该节点的子节点。其拥有 length 属性,length 属性的值可以用来表示当前 NodeList 中的节点数量。
  • 当 DOM 结构发生变化时 NodeList 也发生相对的变化。
  • <div id="box">
    <ul id="list">
    <li id="content">aaaaa</li>
    <li>aaaaa</li>
    </ul>
    </div>
    <script>
    const list = document.getElementById('list')
    const content = document.getElementById('content')

    console.log(list.childNodes)

    // NodeList(5)
    // 0: text
    // 1: li#content
    // 2: text
    // 3: li
    // 4: text
    // length: 5
    // [[Prototype]]: NodeList

    console.log(content.childNodes)

    // NodeList(1)
    // 0: text
    // length: 1
    // [[Prototype]]: NodeList

    console.log(content.childNodes[0].nodeValue)

    // aaaaa

    </script>

parentNode

  • 每个节点都有一个 parentNode 属性,指向他 DOM 树中的父元素。
  • childNodes 中的所有节点都拥有同一个父元素,所以他们的 parentNode 属性指向同一个元素
  • <div id="box">
    <ul id="list">
    <li id="content">aaaaa</li>
    <li id="details">aaaaa</li>
    </ul>
    </div>
    <script>
    const content = document.getElementById('content')
    const details = document.getElementById('details')

    console.log(content.parentNode)

    // <ul id="list"></ul>

    console.log(details.parentNode)

    // <ul id="list"></ul>

    </script>

 previousSibling 和 nextSibling

  • childNodes 列表中的每个节点,都是同一列表中,其它节点的同胞节点。
  • previousSibling 属性是当前节点在同一列表中的上一个节点。
  • nextSibling 属性是当前节点在同一列表中的下一个节点。
  • 所以 childNodes 列表中,第一个节点的 previousSibing 属性是 null,最后一个节点的 nextSibling 属性是 null。
  • 如果 childNodes 列表中只有一个节点,那么该节点的 previousSibling 属性和 nextSibling 属性都是 null。
  • <div id="box"><ul id="list"><li id="content">aaaaa</li><li id="details">aaaaa</li><li id="matter">aaaaa</li></ul></div>
    <!-- 之所以将代码写成一行是因为换行符也是节点 -->
    <script>
    const content = document.getElementById('content')

    console.log(content.previousSibling)
    // null
    console.log(content.nextSibling)
    // <li id="details">aaaaa</li>

    const details = document.getElementById('details')

    console.log(details.previousSibling)
    // <li id="content">aaaaa</li>
    console.log(details.nextSibling)
    // <li id="matter">aaaaa</li>

    const matter = document.getElementById('matter')

    console.log(matter.previousSibling)
    // <li id="details">aaaaa</li>
    console.log(matter.nextSibling)
    // null

    const list = document.getElementById('list')

    console.log(list.previousSibling)
    // null
    console.log(list.nextSibling)
    // null

    </script>

firstChild 和 lastChild

  • 如果想要获取父节点的第一个子节点或,最后一个子节点可以使用专门的属性:
    • firstChild 指向 childNodes 中的第一个子节点。
    • lastChild 指向 childNodes 中的最后一个子节点。
  • 如果该父节点只有一个子节点,那么 firstChild 和 lastChild 指向同一个节点。
  • 如果该父节点没有子节点,那么 firstChild 和 lastChild 都是 null。

 hasChildNodes ()

  • 由上文可知我们可以通过判断节点 childNodes 属性的 length ,来判断该节点是否有子节点。
  • 但是还有一个更加便利的方法:hasChildNodes 方法,如果该方法返回 true 则说明该节点有一个或多个子节点,如果返回 false 则说明该节点没有子节点。
  • <body>
    <div id="a">
    <div id="b">Hello World</div>
    <div id="c"></div>
    </div>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const b = $('b')
    const c = $('c')
    console.log(a.childNodes.length)
    // 5
    console.log(b.childNodes.length)
    // 1
    console.log(c.childNodes.length)
    // 0
    console.log(a.hasChildNodes())
    // true
    console.log(b.hasChildNodes())
    // true
    console.log(c.hasChildNodes())
    // false
    </script>

ownerDocument

  • ownerDocument 属性,该属性会以 Document 对象的形式返回节点的 owner document。
  • 在 HTML 中元素的 ownerDocument 属性始终是 HTML 文档本身

操作节点

  • 上述所有的属性、方法都是只读的,DOM 另外提供了专门操作节点的方法。

appendChild ()

  • appendChild 方法用于在 childNodes 列表的末尾处添加节点。添加的节点会更新相关的关系。
  • 如果操作的节点是与存在的节点,那么这个节点会从之前的位置被转移到新的位置,一个节点不会再文档中同时出现两个或多个地方。
  • 如果
  • <body>
    <span id="c"> World </span>
    <div id="a"><span id="b"> Hello </span></div>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const b = $('b')
    const c = $('c')
    a.appendChild(c)

    console.log(a.lastChild)
    // <span id="c"> World </span>

    </script>

insertBefore ()

  • 如果想把节点放到特定的位置可以使用 insertBefore 方法,该方法接收两个参数:需要插入的节点和参照节点。
  • 调用该方法后需要插入的节点,会插入到参照节点的前面。成为参照节点的前一个同胞节点。
  • <body>
    <span id="d"> d </span>
    <div id="a"><span id="b"> b </span><span id="c"> c </span></div>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const b = $('b')
    const c = $('c')
    const d = $('d')

    a.insertBefore(d, null)
    console.log(a.lastChild)
    // <span id="d"> d </span>

    a.insertBefore(d, a.firstChild)
    console.log(a.firstChild)
    // <span id="d"> d </span>

    a.insertBefore(d, a.lastChild)
    console.log(a.childNodes[a.childNodes.length - 2])
    // <span id="d"> d </span>

    </script>

replaceChild ()

  • 前两种方法并不会删除任何已有节点,而 replaceChild 方法会用插入的节点,替换并返回目标节点。
  • replaceChild 方法接收两个参数:需要插入的节点和被替换的节点。使用该方法插入一个节点后,目标节点的所有关系指针都会被替换的节点复制过来。虽然被替换节点仍被同一文档拥有,文档中已经没有了他的位置。
  • <body>
    <span id="flower"> flower </span>
    <div id="a"><span id="life"> life </span><span id="love"> love </span></div>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const life = $('life')
    const flower = $('flower')
    const love = $('love')

    const d1 = a.replaceChild(flower, a.firstChild)
    console.log(a.firstChild)
    // <span id="flower"> flower </span>
    console.log(d1)
    // <span id="life"> life </span>

    a.replaceChild(d1, a.firstChild)
    const d2 = a.replaceChild(flower, a.lastChild)
    console.log(a.lastChild)
    // <span id="flower"> flower </span>
    console.log(d2)
    // <span id="love"> love </span>

    </script>

removeChild ()

  • 当我们想移除节点而不是替换节点的时候可以使用 removeChild 方法。该方法只接收一个参数:需要移除的节点。移除节点的同时也会返回被移除节点。
  • 和上面的 replaceChild 方法一样,通过 removeChild 方法移除的节点,仍被当前文档所拥有,但是文档中已经没了改节点的位置。
  • <body>
    <div id="a"><span id="life"> life </span><span id="flower"> flower </span><span id="love"> love </span></div>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const life = $('life')
    const flower = $('flower')
    const love = $('love')

    const d1 = a.removeChild(a.firstChild)
    console.log(a.firstChild)
    // <span id="flower"> flower </span>
    console.log(d1)
    // <span id="life"> life </span>

    a.insertBefore(d1, a.firstChild)
    const d2 = a.removeChild(a.lastChild)
    console.log(a.lastChild)
    // <span id="flower"> flower </span>
    console.log(d2)
    // <span id="love"> love </span>

    </script>

cloneNode ()

  • cloneNode 方法会返回与调用该方法节点,一模一样的节点。
  • cloneNode 方法接收一个参数为布尔值,表示是否开启深复制。当传入 true 时会进行深度复制,即复制节点及其整个子DOM树。如果传入的是 false,那么只会复制调用该方法的节点。
  • 复制到的节点属于当前文档,但是并未指定父节点,所以可以称之为孤儿节点。可以使用上述的 appendChild 、insertBefore 、replaceChild 方法将孤儿节点添加到文档当中去。
  • <body>
    <ul id="a">
    <li>a</li>
    <li>b</li>
    <li>c</li>
    </ul>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const b = a.cloneNode(true)
    console.log(b)
    //<ul id="a">
    // <li>a</li>
    // <li>b</li>
    // <li>c</li>
    //</ul>
    const c = a.cloneNode(false)
    console.log(c)
    // <ul id="a"></ul>

    </script>

normalize ()

  • 该方法会将当前节点和他的后代节点规范化。规范化后的 DOM 树中将不会出现空的文本节点。如有两个文本节点相邻那么会被合并为一个文本节点。 
  • <body>
    <span id="a"> hello world </span>
    </body>
    <script>
    const $ = (e) => document.getElementById(e)
    const a = $('a')
    const b = a.childNodes[0].cloneNode()
    a.insertBefore(b, a.childNodes[0])
    console.log(a.childNodes)
    // NodeList(2) [text, text]
    a.normalize()
    console.log(a.childNodes)
    // NodeList [text]
    </script>

举报

相关推荐

0 条评论