Dom节点的小知识

138 阅读5分钟

网页渲染

1、script、link标签默认加载过程中是一个同步过程
2、将所有HTML标签构建完成,产生一个HTML树,DOM树
3、所有CSS加载完成,CSS样式合并, 产生一个CSS树
4、CSS树和DOM树合并,DOM渲染树   
5、DOMContentLoader  DOM 内容的加载
6、网页显示完成

如果需要修改一个样式时

先把DOM渲染树拆开为DOM树和CSS树,会根据修改样式的影响分为两种情况:1、回流 2、重绘
重绘,指修改的样式不会影响到其他元素布局大小等内容,只会将当前这个元素DOM属性和样式更新
回流,当修改的样式影响到了其他元素的布局大小时,就会回流,
                                回流将当前元素及后面的所有元素内容属性、样式全部更新
然后重新CSS和DOM树合并,重新完成DOM渲染树,最后重新渲染页面

DOM 节点

     *      DOM 节点一般指的是标签, 也有一个细的分类
     * 
     *          元素节点 (标签)     一般就是我们所说的 标签
     *          文本节点            标签内部的文本就是我们的文本节点
     *          属性节点            标签上上写的属性就是属性节点
    */
     /**

获取节点 子级

     * 
     *      1. childNodes
     *          获取标签的所有子级节点 就是获取所有(元素,文本,属性节点)
     * 
     *      2. children
     *          获取标签的所有子级元素节点
     * 
     *      3. firstChild
     *          获取标签内第一个子级节点
     * 
     *      4. lastChild
     *          获取标签内最后一个子级节点
     * 
     *      5. firstElementChild
     *          获取标签内第一个子级元素节点
     * 
     *      6. lastElementChild
     *          获取标签内最后一个子级元素节点
     
     
     *   var box = document.querySelector('.box')
            console.log(box.firstElementChild)
            console.log(box.lastElementChild)
     */
     /**

获取节点 兄弟级

     *      ......
     * 
     *      7. nextSibling
     *          获取下一个兄弟节点
     * 
     *      8. previousSibling
     *          获取上一个兄弟节点
     * 
     *      9. nextElementSibling
     *          获取下一个兄弟元素节点
     * 
     *      10. previousElementSibling
     *          获取上一个兄弟元素节点
     * 
 
    */
    /**

获取节点 其他

     *      ......
     *
     *      11. parentNode
     *          获取到当前标签的父级
     *
     *      12. attributes
     *          获取到当前标签的所有属性节点,是个为数组
    */
     /**

节点属性

     <ul a="周一来了, 离过年就不远了">
    <li>国庆快乐</li>
     </ul>
    var box = document.querySelector('ul')

    // 1. 元素节点
    var elNode = box.firstElementChild
    // 2. 文本节点
    var textNode = box.firstChild
    // 3. 属性节点
    // var attrNode = box.attributes    // 当前写法是获取到元素的所有属性组成的一个伪数组, 然后存储到变量中
    var attrNode = box.attributes[0]    // 获取到元素的所有属性组成的伪数组中 下标[0] 的项, 此时获取到的实际的值是一个属性节点

    // console.log(elNode, textNode, attrNode)


    // 获取节点类型
    console.log('元素节点: ', elNode.nodeType)      // 1
    console.log('文本节点: ', textNode.nodeType)    // 3
    console.log('属性节点: ', attrNode.nodeType)    // 2

    // 获取节点名称
    console.log('元素节点: ', elNode.nodeName)      // LI  一个大写的标签名
    console.log('文本节点: ', textNode.nodeName)    // #text,表示空格缩进,因为li前面有空格缩进
    console.log('属性节点: ', attrNode.nodeName)    // 属性名

    // 获取节点的值
    console.log('元素节点: ', elNode.nodeValue)      // null
    console.log('文本节点: ', textNode.nodeValue)    // 文本的内容,如果是空白代表有空格,缩进等。
    console.log('属性节点: ', attrNode.nodeValue)    // 属性值
 /**

操作 DOM

 document.createElement(标签名) 表示创建一个这个标签名的标签
    父元素.appendChild(元素) 将元素插入在父元素的最尾部
    document.createDocumentFragment() 创建碎片容器
    元素.textContent="内容" 给元素里面放入文本内容 innerText 的更新版本
    父元素.insertBefore(要插入的新元素,插入在谁的前面);
    document.createTextNode(文本内容) 创建文本节点
    元素.cloneNode(是否深复制); 复制元素或者复制节点 深复制表示将元素,
    包括其子元素都复值,浅复制只复制元素,不复制子元素
    父元素.removeChild(子元素) 父元素删除子元素
    子元素.remove() 子元素自身删除
    父元素.replaceChild(新的元素,被替换的元素); 父元素替换子元素
    被替换的元素.replaceWith(新元素) 新元素替换原来的元素

添加 DOM

                        // 1. 创建一个 DOM      此时页面中没有当前标签
                        var myDiv = document.createElement('div')
                        // console.log(myDiv)

                        // 1.5 向刚才创建出来的 DOM 上 添加一些标识
                        myDiv.className = 'box_2'
                        myDiv.dataset.id = 'QF001'
                        myDiv.innerText = '我是通过 JS 创建的一个标签'

                        // 2. 将 DOM 添加到页面中去     第二步完成后,
                                                            标签就添加到页面中去了
                        var box = document.querySelector('.box')
                        // console.log(box)

                        //  添加到指定元素的 末尾
                        box.appendChild(myDiv)
                        

指定元素插入位置

                  <ul>
                    <li class="target">1</li>
                    <li>2</li>
                    <li>3</li>
                </ul>
                <script>
                    var myUl = document.querySelector('ul')
                    var target = document.querySelector('.target')

                    // 1. 创建一个 DOM
                    var myLi = document.createElement('li')
                    myLi.innerText = '我是通过 JS 创建的一个 li 标签'

                    // 2. 将 li 添加到页面中
                    // myUl.appendChild(myLi)

                    // myUl.insertBefore('要添加的 DOM', '要放在那个标签的前边')
                     myUl.insertBefore(myLi, target)


                    // myUl.insertBefore('要添加的 DOM', '如果 传递的是 null 
                    那么会放在父元素标签的末尾')
                    myUl.insertBefore(myLi, null)
      
      

碎片容器

    // 碎片容器就像胶囊,一使用就是消失,要想再次使用必须重新设置,他是用来减少回流的。
    var elem=document.createDocumentFragment();
    for(var i=0;i<10;i++){
        var div=document.createElement("div");
        elem.appendChild(div);
    }
    document.body.appendChild(elem);
    
    

创建文本节点

    var div1=document.querySelector(".div1");
    var text=document.createTextNode("aaa");
    div1.insertBefore(text,div1.firstChild);//将文本节点插入第一个标签之前

移动元素

    var div1=document.querySelector(".div1");
    var div2=document.querySelector(".div2");

    将已有的元素插入在别的元素中,就是移动元素
    div2.appendChild(div1);

删除与修改元素

            <div>
                <p>我是一个普通的 P 标签</p>
            </div>
            <script>
                /**
                 *  删除与修改元素
                */
                var myDiv = document.querySelector(div)
                var myP = document.getElementsByTagName('p')[0]




                // 2. 修改(替换)
                var mySp = document.createElement('span')
                mySp.innerText = '我是通过 JS 创建出来的一个 span 标签'

                // myDiv.replaceChild('新的节点', '要被替换的节点')
                myDiv.replaceChild(mySp, myP)
                 mySp.replaceWith(myp);
                // 1. 删除
                 myDiv.remove()   // 直接删除 指定元素
                 myDiv.removeChild(myP)  // 删除指定元素的子级, 不会删除自己

克隆Dom

             <ul>
                <li class="box"><span>你好~</span></li>
            </ul>
            <ol>

            </ol>
            <script>
                var myLi = document.querySelector('.box')
                var myOl = document.querySelector('ol')

                // 1. 基于 myLi 复制(克隆) 一个一模一样的新标签
                // var cloneLi = document.cloneNode()
                // var cloneLi = document.body.cloneNode()


                /**
                 *  cloneNode 接收一个参数, 默认为 false
                 * 
                 *      true: 克隆所有的后代节点
                 *      false: 不克隆
                */


                 var cloneLi = myLi.cloneNode()
                 console.log(cloneLi)    // <li class="box"></li>

                var cloneLi = myLi.cloneNode(true)
                 console.log(cloneLi)    // <li class="box"><span>你好~</span></li>

                // 2. 将新标签放在 myOl 中
                myOl.appendChild(cloneLi)