公告栏

此网站主题为本人手写主题, 主题待开源···

音乐盒

站点信息

文章总数目: 308
已运行时间: 1187
目录
  1. 节点概述
  • 父节点
    1. node.parentNode
  • 子节点
    1. parentNode.childNodes
    2. parentNode.children
    3. parent.firstChild
    4. parent.lastChild
    5. parent.firstElementChild
    6. parent.lastElementChild
    7. 首末节点兼容方案
  • 兄弟节点
  • 创建结点
    1. document.createElement()
    2. node.cloneNode()
    3. Demo:动态生成表格
    4. 创建元素的三种方式对比
  • 插入结点
    1. node.appendChild()
    2. node.insertBefore()
    3. Demo:简单版发布留言
  • 删除节点
    1. node.removeChild()
    2. Demo:删除留言
  • 尼采般地抒情

    尼采般地抒情

    尼采般地抒情

    公告栏

    此网站主题为本人手写主题, 主题待开源···

    站点信息

    文章总数目: 308
    已运行时间: 1187

    节点概述

    网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。

    一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

    节点层级:利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系

    父节点

    node.parentNode

    • 返回某节点的父节点,最近的一个父节点
    • 如果没有父节点,则返回null

    子节点

    parentNode.childNodes

    • 返回指定节点的子节点的集合,会即时更新
    • 会返回所有的节点(包含元素节点、文本节点等)

    parentNode.children

    • 只读属性
    • 只返回元素节点
    • 非标准,但是各个浏览器都支持

    parent.firstChild

    • 返回第一个子节点,找不到返回null,包含所有节点

    parent.lastChild

    • 返回最后一个子节点,找不到返回null,包含所有节点

    parent.firstElementChild

    • 返回第一个子元素节点,找不到返回null
    • IE9以上支持

    parent.lastElementChild

    • 返回最后一个子元素节点,找不到返回null
    • IE9以上支持

    首末节点兼容方案

    实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

    兄弟节点

    下一个兄弟节点

    上一个兄弟节点

    <div>我是div</div>
        <span>我是span</span>
        <script>
            var div = document.querySelector('div');
            // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
            console.log(div.nextSibling);
            console.log(div.previousSibling);
            // 2. nextElementSibling 得到下一个兄弟元素节点
            console.log(div.nextElementSibling);
            console.log(div.previousElementSibling);
        </script>
    

    下一个兄弟元素节点(有兼容性问题)

    上一个兄弟元素节点(有兼容性问题)

    function getNextElementSibling(element) {
          var el = element;
          while (el = el.nextSibling) {
            if (el.nodeType === 1) {
                return el;
            }
          }
          return null;
        }
    

    创建结点

    document.createElement()

    • document.createElement('tagName')
    • 动态创建元素节点

    node.cloneNode()

    <ul>
            <li>1111</li>
            <li>2</li>
            <li>3</li>
        </ul>
        <script>
            var ul = document.querySelector('ul');
            // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
            // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
            var lili = ul.children[0].cloneNode(true);
            ul.appendChild(lili);
        </script>
    

    Demo:动态生成表格

    <script>
            // 1.先去准备好学生的数据
            var datas = [{
                name: '魏璎珞',
                subject: 'JavaScript',
                score: 100
            }, {
                name: '弘历',
                subject: 'JavaScript',
                score: 98
            }, {
                name: '傅恒',
                subject: 'JavaScript',
                score: 99
            }, {
                name: '明玉',
                subject: 'JavaScript',
                score: 88
            }, {
                name: '大猪蹄子',
                subject: 'JavaScript',
                score: 0
            }];
            // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
            var tbody = document.querySelector('tbody');
            // 遍历数组
            for (var i = 0; i < datas.length; i++) { 
                // 1. 创建 tr行
                var tr = document.createElement('tr');
                tbody.appendChild(tr);
                // 2. 行里面创建单元格td 单元格的数量取决于每个对象里面的属性个数  
                // 使用for in遍历学生对象
                for (var k in datas[i]) { 
                    // 创建单元格 
                    var td = document.createElement('td');
                    // 把对象里面的属性值 datas[i][k] 给 td  
                    td.innerHTML = datas[i][k];
                    tr.appendChild(td);
                }
                // 3. 创建有删除2个字的单元格 
                var td = document.createElement('td');
                td.innerHTML = '<a href="javascript:;">删除 </a>';
                tr.appendChild(td);
            }
            // 4. 删除操作 开始 
            var as = document.querySelectorAll('a');
            for (var i = 0; i < as.length; i++) {
                as[i].onclick = function() {
                    // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸)  node.removeChild(child)  
                    tbody.removeChild(this.parentNode.parentNode)
                }
            }
        </script>
    

    创建元素的三种方式对比

    <script>
            // 三种创建元素方式区别 
            // 1. document.write() 创建元素  如果页面文档流加载完毕,再调用这句话会导致页面重绘
             var btn = document.querySelector('button');
             btn.onclick = function() {
                 document.write('<div>123</div>');
             }
            // 2. innerHTML 创建元素
            var inner = document.querySelector('.inner');
             for (var i = 0; i <= 100; i++) {
                 inner.innerHTML += '<a href="#">百度</a>'
             }
            var arr = [];
            for (var i = 0; i <= 100; i++) {
                arr.push('<a href="#">百度</a>');
            }
            inner.innerHTML = arr.join('');
            // 3. document.createElement() 创建元素
            var create = document.querySelector('.create');
            for (var i = 0; i <= 100; i++) {
                var a = document.createElement('a');
                create.appendChild(a);
            }
        </script>
    

    innerTHML和createElement效率对比

    innerHTML字符串拼接方式(效率低)

    <script>
        function fn() {
            var d1 = +new Date();
            var str = '';
            for (var i = 0; i < 1000; i++) {
                document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
            }
            var d2 = +new Date();
            console.log(d2 - d1);
        }
        fn();
    </script>
    

    createElement方式(效率一般)

    <script>
        function fn() {
            var d1 = +new Date();
            for (var i = 0; i < 1000; i++) {
                var div = document.createElement('div');
                div.style.width = '100px';
                div.style.height = '2px';
                div.style.border = '1px solid red';
                document.body.appendChild(div);
            }
            var d2 = +new Date();
            console.log(d2 - d1);
        }
        fn();
    </script>
    

    innerHTML数组方式(效率高)

    <script>
        function fn() {
            var d1 = +new Date();
            var array = [];
            for (var i = 0; i < 1000; i++) {
                array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
            }
            document.body.innerHTML = array.join('');
            var d2 = +new Date();
            console.log(d2 - d1);
        }
        fn();
    </script>
    

    插入结点

    node.appendChild()

    • node.appendChild(child)
    • 添加到父节点的子节点列表末尾

    node.insertBefore()

    • node.insertBefore(child,指定元素)
    • 将一个节点添加到父节点的指定子节点前面

    Demo:简单版发布留言

    <body>
        <textarea name="" id=""></textarea>
        <button>发布</button>
        <ul>
        </ul>
        <script>
            // 1. 获取元素
            var btn = document.querySelector('button');
            var text = document.querySelector('textarea');
            var ul = document.querySelector('ul');
            // 2. 注册事件
            btn.onclick = function() {
                if (text.value == '') {
                    alert('您没有输入内容');
                    return false;
                } else {
                    // console.log(text.value);
                    // (1) 创建元素
                    var li = document.createElement('li');
                    // 先有li 才能赋值
                    li.innerHTML = text.value;
                    // (2) 添加元素
                    // ul.appendChild(li);
                    ul.insertBefore(li, ul.children[0]);
                }
            }
        </script>
    </body>
    

    删除节点

    node.removeChild()

    • node.removeChild() 方法从 node节点中删除一个子节点,返回删除的节点。

    Demo:删除留言

    <textarea name="" id=""></textarea>
        <button>发布</button>
        <ul>
        </ul>
        <script>
            // 1. 获取元素
            var btn = document.querySelector('button');
            var text = document.querySelector('textarea');
            var ul = document.querySelector('ul');
            // 2. 注册事件
            btn.onclick = function() {
                if (text.value == '') {
                    alert('您没有输入内容');
                    return false;
                } else {
                    // console.log(text.value);
                    // (1) 创建元素
                    var li = document.createElement('li');
                    // 先有li 才能赋值
                    li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
                    // (2) 添加元素
                    // ul.appendChild(li);
                    ul.insertBefore(li, ul.children[0]);
                    // (3) 删除元素 删除的是当前链接的li  它的父亲
                    var as = document.querySelectorAll('a');
                    for (var i = 0; i < as.length; i++) {
                        as[i].onclick = function() {
                            // 删除的是 li 当前a所在的li  this.parentNode;
                            ul.removeChild(this.parentNode);
                        }
                    }
                }
            }
        </script>
    


    评论区

    Twikoo giscus