【JavaScript】8.DOM的节点操作

news2024/9/19 10:48:02

DOM的节点操作

获取元素通常使用两种方式:

  1. 利用 DOM 提供的方法获取元素
  2. 利用节点层级关系获取元素
  • 利用 DOM 提供的方法获取元素
    • document.getElementById()
    • document.getElementsByTagName()
    • document.querySelector 等
    • 逻辑性不强、繁琐
  • 利用节点层级关系获取元素
    • 利用父子兄节点关系获取元素
    • 逻辑性强, 但是兼容性稍差

1. 节点概述

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。

HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除

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

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>节点概述</title>
</head>

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <div class="box">
        <span class="erweima">×</span>
    </div>
    <script>
        var box = document.querySelector('.box');
        console.dir(box);
    </script>
</body>

</html>

2. 节点层级

2.1 父节点操作

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

node.parentNode
  • parentNode 属性可返回某节点的父节点,注意是最近的一个父节点
  • 如果指定的节点没有父节点则返回 null
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ul>
    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
        // 1. 父节点 parentNode
        var erweima = document.querySelector('.erweima');
        // var box = document.querySelector('.box'); // 有点繁琐
        // 得到的是离元素最近的父级节点 如果找不到父节点就返回为 null
        console.log(erweima.parentNode);
    </script>
</body>

</html>

在这里插入图片描述

2.2 子节点操作

parentNode.childNodes(标准)

parentNode.childNodes

parentNode.childNodes 返回包含指定节点的子节点的集合,该集合为即时更新的集合。

**注意:**返回值里面包含了所有的子节点,包括元素节点,文本节点等。

如果只想要获得里面的元素节点,则需要专门处理。 所以我们一般不提倡使用childNodes

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>子节点操作</title>
</head>

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>

    </ul>
    <ol>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ol>

    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
        // DOM 提供的方法(API)获取
        var ul = document.querySelector('ul');
        var lis = ul.querySelectorAll('li');
        // 1. 子节点  childNodes 所有的子节点 包含 元素节点 文本节点等等
        console.log(ul.childNodes);
        console.log(ul.childNodes[0].nodeType); // 文本元素是 3
        console.log(ul.childNodes[1].nodeType); // li元素是 1
        var ul = document.querySelector('ul');
        for (var i = 0; i < ul.childNodes.length; i++) {
            if (ul.childNodes[i].nodeType == 1) { // ul.childNodes[i] 是元素节点,等于 1 就是 li 元素
                console.log(ul.childNodes[i]);
            }
        }

    </script>
</body>

</html>

在这里插入图片描述

parentNode.children(非标准)

parentNode.children

parentNode.children 是一个只读属性,返回所有的子元素节点

它只返回子元素节点,其余节点不返回

虽然children 是一个非标准,但是得到了各个浏览器的支持

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <!-- 节点的优点 -->
    <div>我是div</div>
    <span>我是span</span>
    <ul>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>

    </ul>
    <ol>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
        <li>我是li</li>
    </ol>

    <div class="demo">
        <div class="box">
            <span class="erweima">×</span>
        </div>
    </div>

    <script>
        // DOM 提供的方法(API)获取
        var ul = document.querySelector('ul');
        // children 获取所有的子元素节点 也是我们实际开发常用的
        console.log(ul.children);
    </script>
</body>

</html>

在这里插入图片描述

2.3 子节点-第一个子元素和最后一个子元素

parentNode.firstElementChild
// firstElementChild 返回第一个子元素节点,找不到则返回nul

parentNode.lastElementChild
// lastElementChild 返回最后一个子元素节点,找不到则返回null

注意:这两个方法有兼容性问题,IE9 以上才支持

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>子节点-第一个子元素和最后一个子元素</title>
</head>

<body>
    <ol>
        <li>我是li1</li>
        <li>我是li2</li>
        <li>我是li3</li>
        <li>我是li4</li>
        <li>我是li5</li>
    </ol>
    <ul></ul>
    <script>
        var ol = document.querySelector('ol');
        var ul = document.querySelector('ul');

        // firstChild 第一个子节点 不管是文本节点还是元素节点
        console.log(ol.firstChild); // #text
        console.log(ol.lastChild); // #text
        console.log(ul.firstChild); // null
        console.log(ul.lastChild); // null
        
        // firstElementChild 返回第一个子元素节点 firstElementChild 有兼容性问题 ie9才支持
        console.log(ol.firstElementChild);
        console.log(ol.lastElementChild);
        console.log(ul.firstElementChild); // null
        console.log(ul.lastElementChild); // null
        
        // 实际开发的写法  既没有兼容性问题又返回第一个子元素
        console.log(ol.children[0]);
        console.log(ol.children[ol.children.length - 1]);
    </script>
</body>

</html>

2.4 新浪下拉菜单案例

① 导航栏里面的 li 都要有鼠标经过效果,所以需要循环注册鼠标事件
② 核心原理: 当鼠标经过 li 里面的 第二个孩子 ul 显示, 当鼠标离开,则 ul 隐藏

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>新浪下拉菜单</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style-type: none;
        }

        a {
            text-decoration: none;
            font-size: 14px;
        }

        .nav {
            margin: 100px;
        }

        .nav>li {
            position: relative;
            float: left;
            width: 80px;
            height: 41px;
            text-align: center;
        }

        .nav li a {
            display: block;
            width: 100%;
            height: 100%;
            line-height: 41px;
            color: #333;
        }

        .nav>li>a:hover {
            background-color: #eee;
        }

        .nav ul {
            display: none;
            position: absolute;
            top: 41px;
            left: 0;
            width: 100%;
            border-left: 1px solid #FECC5B;
            border-right: 1px solid #FECC5B;
        }

        .nav ul li {
            border-bottom: 1px solid #FECC5B;
        }

        .nav ul li a:hover {
            background-color: #FFF5DA;
        }
    </style>
</head>

<body>
    <ul class="nav">
        <li>
            <a href="#">微博</a>
            <ul>
                <li>
                    <a href="">私信</a>
                </li>
                <li>
                    <a href="">评论</a>
                </li>
                <li>
                    <a href="">@我</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">博客</a>
            <ul>
                <li>
                    <a href="">博客评论</a>
                </li>
                <li>
                    <a href="">未读提醒</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">邮箱</a>
            <ul>
                <li>
                    <a href="">免费邮箱</a>
                </li>
                <li>
                    <a href="">VIP邮箱</a>
                </li>
                <li>
                    <a href="">企业邮箱</a>
                </li>
            </ul>
        </li>
        <li>
            <a href="#">网友</a>
            <ul>
                <li>
                    <a href="">私信</a>
                </li>
                <li>
                    <a href="">评论</a>
                </li>
                <li>
                    <a href="">@我</a>
                </li>
            </ul>
        </li>
    </ul>
    <script>
        var nav = document.querySelector('.nav');
        var lis = nav.children; // 得到4个小li
        for (var i = 0; i < lis.length; i++) {
            lis[i].onmouseover = function () {
                this.children[1].style.display = 'block';
            }
            lis[i].onmouseout = function () {
                this.children[1].style.display = 'none';
            }
        }
    </script>
</body>

</html>

在这里插入图片描述

2.5 兄弟节点

node.nextSibling
// nextSibling 返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点

node.previousSibling
// previousSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点

node.nextElementSibling
// nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null

node.previousElementSibling
// previousElementSibling 返回当前元素上一个兄弟节点,找不到则返回null

注意:这两个方法有兼容性问题, IE9 以上才支持
如何解决兼容性问题 ? – 封装一个兼容性的函数

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>兄弟节点</title>
</head>

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

        // nextElementSibling 得到下一个兄弟元素节点
        console.log(div.nextElementSibling);
        console.log(div.previousElementSibling);

        // 方法有兼容性问题, IE9 以上才支持
        // 解决兼容性问题 - 封装一个兼容性的函数
        function getNextElementSibling(element) {
            var el = element;
            while (el = el.nextSibling) {
                if (el.nodeType === 1) {
                    return el;
                }
            }
            return null;
        }
        console.log(getNextElementSibling(div));
    </script>
</body>

</html>

3. 创建和添加节点

创建节点

document.createElement() 方法创建由 tagName 指定的 HTML 元素

因为这些元素原先不存在,是根据需求动态生成的,所以也称为动态创建元素节点

添加节点

  • node.appendChild(child)
    node.appendChild() 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素

  • node.insertBefore(child, 指定元素)
    node.insertBefore() 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before
    伪元素

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>创建和添加节点</title>
</head>
<body>
    <ul></ul>
    <ol>
        <li>123</li>
    </ol>
    <script>
        // 创建节点元素节点
        var li = document.createElement('li');
        
        // 添加节点 node.appendChild(child)  node 父级  child 是子级 
        // 将一个节点添加到指定父节点的子节点列表末尾
        var ul = document.querySelector('ul');
        ul.appendChild(li);
        // 后面追加元素  类似于数组中的push
        var ol = document.querySelector('ol');
        var li1 = document.createElement('li');
        ol.appendChild(li1); 

        // 添加节点 node.insertBefore(child, 指定元素);
        // 将一个节点添加到父节点的指定子节点前面
        var li2 = document.createElement('li');
        ol.insertBefore(li2,ol.children[0]); // 在 <li>123</li> 添加 li 元素
    </script>
</body>
</html>

3.1 简单版发布留言案例

  1. 核心思路: 点击按钮之后,就动态创建一个li,添加到ul 里面
  2. 创建 li 的同时,把文本域里面的值通过 li.innerHTML 赋值给 li
  3. 如果想要新的留言后面显示就用 appendChild 如果想要前面显示就用 insertBefore
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单版发布留言案例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            padding: 100px;
        }

        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }

        ul {
            margin-top: 50px;
        }

        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
</head>

<body>
    <textarea name="" id=""></textarea>
    <button>提交</button>
    <ul></ul>
    <script>
        var textarea = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        btn.onclick = function () {
            if (textarea == '') {
                alert('输入的内容为空!');
            } else {
                var li = document.createElement('li');
                li.innerHTML = textarea.value;
                ul.insertBefore(li, ul.children[0]);
            }
        } 
    </script>
</body>

</html>

在这里插入图片描述

4. 删除节点

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

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>删除节点</title>
</head>

<body>
    <ol>
        <li>li1</li>
        <li>li2</li>
        <li>li3</li>
    </ol>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        // 删除元素  node.removeChild(child)
        var ol = document.querySelector('ol');
        ol.removeChild(ol.children[0]);

        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
    
        // 点击按钮依次删除里面的孩子
        btn.onclick = function () {
            if (ul.children.length == 0) {
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>

</html>

4.1 删除留言案例

  1. 当把文本域里面的值赋值给 li 的时候,多添加一个删除的链接
  2. 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前链接所在的li
  3. 阻止链接跳转需要添加 javascript:void(0); 或者 javascript:;
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>删除留言案例</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            padding: 100px;
        }

        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid pink;
            outline: none;
            resize: none;
        }

        ul {
            margin-top: 50px;
        }

        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(245, 209, 243);
            color: red;
            font-size: 14px;
            margin: 15px 0;
        }

        li a {
            float: right;
        }
    </style>
</head>

<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>

    </ul>
    <script>
        var textarea = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var ul = document.querySelector('ul');
        btn.onclick = function () {
            if (textarea == '') {
                alert('输入的内容为空!');
            } else {
                var li = document.createElement('li');
                li.innerHTML = textarea.value + "<a href='javascript:;'>删除</a>";
                ul.insertBefore(li, ul.children[0]);
                var as = document.querySelectorAll('a');

                // 删除元素 删除的是当前链接的li  它的父亲
                for (var i = 0; i < as.length; i++) {
                    as[i].onclick = function () {
                        // // node.removeChild(child); 删除的是 li 当前a所在的li  this.parentNode;
                        ul.removeChild(this.parentNode);
                    }
                }
            }
        }
    </script>
</body>

</html>

在这里插入图片描述

5. (复制节点)克隆节点

node.cloneNode()
node.cloneNode() 方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点

注意:

  1. 如果括号参数为空或者为 false ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
  2. 如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>克隆节点</title>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <ol>
        <li>123</li>
        <li>2</li>
        <li>3</li>
    </ol>
    <script>
        var ul = document.querySelector('ul');
        var ol = document.querySelector('ol');

        // node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
        var li1 = ul.children[0].cloneNode();
        ul.appendChild(li1);

        // node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
        var li2 = ol.children[0].cloneNode(true);
        ol.appendChild(li2);
    </script>
</body>
</html>

6. 动态生成表格案例

  1. 因为里面的学生数据都是动态的,需要js 动态生成。 这里模拟数据,定义好数据。 数据采取对象形式存储
  2. 所有的数据都是放到 tbody 里面的行里面
  3. 因为行很多,需要循环创建多个行(对应多少人)
  4. 每个行里面又有很多单元格(对应里面的数据),还继续使用循环创建多个单元格,并且把数据存入里面(双重for循环)
  5. 最后一列单元格是删除,需要单独创建单元格
  6. 最后添加删除操作,单击删除,可以删除当前行
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动态生成表格案例</title>
    <style>
        table {
            width: 500px;
            margin: 100px auto;
            border-collapse: collapse;
            text-align: center;
        }

        td,
        th {
            border: 1px solid #333;
        }

        thead tr {
            height: 40px;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            
        </tbody>
    </table>
    <script>
        // 学生数据
        var datas = [
            { name: 'ich', subject: 'javaScript', score: 100 },
            { name: 'du', subject: 'javaScript', score: 99 },
            { name: 'icebear', subject: 'javaScript', score: 88 },
            { name: 'panda', subject: 'javaScript', score: 77 }
        ];

        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) {
            // 创建 tr 行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);

            // 行里面创建单元格(跟数据有关系的3个单元格) 
            // td 单元格的数量取决于每个对象里面的属性个数  
            // for循环遍历对象 datas[i]
            for (var k in datas[i]) { // 里面的for循环创建 td
                // 创建单元格
                var td = document.createElement('td');
                // 把对象里面的属性值 datas[i][k] 给 td  
                // console.log(datas[i][k]);
                td.innerHTML = datas[i][k];
                tr.appendChild(td);
            }

            // 创建有删除2个字的单元格
            var td = document.createElement('td');
            td.innerHTML = '<a href="javaScript:;">删除</a>';
            tr.appendChild(td);
        }

        // 删除操作
        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>
</body>

</html>

在这里插入图片描述

7. 三种创建元素方式区别

  • document.write()
  • element.innerHTML
  • document.createElement()

区别

  1. document.write 是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
  2. innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
  3. innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
  4. createElement() 创建多个元素效率稍低一点点,但是结构更清晰
    总结:不同浏览器下,innerHTML 效率要比 creatElement 高
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>三种创建元素方式区别</title>
</head>

<body>
    <button>点击</button>
    <script>
        // window.onload = function () {
        //     document.write('<div>123</div>');
        // }

        // 三种创建元素方式区别
        // document.write() 创建元素 
        // 如果页面文档流加载完毕,再调用这句话会导致页面重绘
        var btn = document.querySelector('button');
        btn.onclick = function () {
            document.write('<div>123</div>');
        }
    </script>
</body>

</html>

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>三种创建元素方式区别</title>
</head>

<body>
    <button>点击</button>
    <div class="inner"></div>
    <div class="create"></div>
    <script>
        // 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('');

        // document.createElement() 创建元素
        var create = document.querySelector('.create');
        for (var i = 0; i <= 100; i++) {
            var a = document.createElement('a');
            create.appendChild(a);
        }
    </script>
</body>

</html>

在这里插入图片描述

7.1 innerHTML拼接效率测试

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>innerHTML拼接效率测试</title>
</head>

<body>
</body>
<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>

</html>

在这里插入图片描述

7.2 innerHTML数组效率测试

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>innerHTML数组效率测试</title>

</head>

<body>

</body>

<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>

</html>

在这里插入图片描述

7.3 createElement效率测试

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>createElement效率测试</title>

</head>

<body>

</body>

<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>

</html>

在这里插入图片描述

GitHub代码
gitee代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/466878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vite中使用html2canvas 将img、svg和div转canvas

目录 div转canvas svg转canvas img转canvas div转canvas 使用 html2canvas 插件&#xff0c;其官网&#xff1a;html2canvas - Screenshots with JavaScripthttp://html2canvas.hertzen.com/ 安装html2canvas&#xff1a; npm i -S html2canvas 引入&#xff1a; import h…

zotero文献管理软件应用

文章目录 基础教学快速安装与入门第二部分&#xff0c;比较详细的教学与补充文献管理工具比较浏览器插件获取文献与文献pdfZotero 界面添加文件的其他方式管理题录在论文中插入引文文献同步插件与常见问题茉莉花PDFTranslator常见问题1.CNKI页面批量抓取题录失败2.文献类型标识…

Python入门教程+项目实战-11.4节: 元组与列表的区别

目录 11.4.1 不可变数据类型 11.4.2 可变数据类型 11.4.3 元组与列表的区别 11.4.4 知识要点 11.4.5 系统学习python 11.4.1 不可变数据类型 不可变数据类型是指不可以对该数据类型进行修改&#xff0c;即只读的数据类型。迄今为止学过的不可变数据类型有字符串&#xff…

leetcode 494. 目标和 (01 背包

。。最近背包问题做得好崩溃 这题的解法和 分割子集、石头 差不多 分成两个集合 &#xff08;注意这里计算的时候是不带上符号的&#xff0c;只是单纯的数字 a. 正号 的数字集合 P b. 负号 的数字集合 N 所以就有以下公式 sum&#xff08;P&#xff09; sum&#xff08;N&…

XGBoost学习总结

XGBoost有两种实现&#xff0c;原生版本和Sklearn版本 &#xff0c;我选的是sklearn的主要是都用sklearn方便 参数 参数表 class xgboost.XGBRegressor ( max_depth3, learning_rate0.1, n_estimators100, silentTrue, objectivereg:linear, boostergbtree, n_jobs1, nthre…

超简单有趣的模拟算法:元胞自动机(CA)原理简介与 matlab 代码实现

很久之前就就听说了元胞自动机&#xff08;cellular automata&#xff0c;CA&#xff09;&#xff0c;但是一直没有尝试。得知2023年美赛春季赛只有两道赛题的时候&#xff0c;怕考到这个&#xff0c;所以出一篇元胞自动机的博客&#xff0c;权且当一篇学习笔记。 尝试过后才发…

亚科转债,鹿山转债上市价格预测

亚科转债 基本信息 转债名称&#xff1a;亚科转债&#xff0c;评级&#xff1a;AA&#xff0c;发行规模&#xff1a;11.59亿元。 正股名称&#xff1a;亚太科技&#xff0c;今日收盘价&#xff1a;5.58元&#xff0c;转股价格&#xff1a;6.46元。 当前转股价值 转债面值 / 转…

SpringBoot搭建的方便易用、多租户、高颜值的教学管理平台

一、开源项目简介 硕果云&#xff0c;基于 Spring Boot 搭建的方便易用、高颜值的教学管理平台&#xff0c;提供多租户、权限管理、考试、练习、在线学习等功能。 主要功能为在线考试、练习、刷题&#xff0c;在线学习 课程内容支持图文、视频&#xff0c;考试类型支持考试、练…

vue可视化大屏

为什么要用 mapbox ? 各位可以自行搜索上面提到的或者其他的webGIS框架或者集成服务商&#xff0c;可以很轻松的比较出mapbox的优势&#xff1a; 支持3D地形、3D模型支持多种坐标系投影mapbox studio 在线编辑地图样式&#xff0c;使用时只需一个链接&#xff0c;更新时链接…

【一篇文章学会使用从暴力法=>记忆化搜索=>动态规划以及栈的多种方法来实现LeetCode 32题最长有效括号问题】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

数字IC入门教程

第一节课 linux命令 文件命令 man 查询指令的作用 如 man cd ls 列出当前文件和文件夹的名字&#xff08;list the directory and files&#xff09; ls -a 把隐藏的文件和文件夹也显示出来 &#xff08;list all&#xff09; ls -l 把文件的属性&#xff08;读写&…

如何设置ddns动态域名实现内网发布外网

在本地搭建好服务器&#xff0c;部署好web网站或其他应用后&#xff0c;需要设置动态域名服务ddns&#xff0c;将主机的内网IP端口映射到外网访问&#xff0c;才能实现在外网访问内网。今天小编就和大家分享一下内网发布外网方案&#xff0c;即如何设置ddns动态域名服务实现外网…

Docker compose 制作 LNMP 镜像

目录 第一章.Nginx镜像 1.1安装环境部署 1.2.nginx镜像容器的配置 第二章.php镜像的安装部署 2.1.文件配置 第三章.mysql镜像的安装部署 3.1.文件配置 第四章.配置网页 4.1.进入容器mysql 4.2.浏览器访问&#xff1a; 第一章.Nginx镜像 1.1安装环境部署 systemctl s…

十四、51单片机之AD转换

1、AD相关简介 1.1、什么是AD转换&#xff1f; (1)A是指analog、模拟的&#xff1b;D是指digital、数字的。 (2)现实世界是模拟的&#xff0c;连续分布的&#xff0c;无法被分成有限份&#xff1b;计算机世界是数字的&#xff0c;离散分布的&#xff0c;是可以被分成有限份的…

Springboot +Flowable,详细解释啥叫流程实例(二)

一.简介 上一篇中学习了Flowable 中的流程模板&#xff08;流程定义&#xff09;的部署问题&#xff0c;这一篇来学习什么叫流程实例。 部署之后的流程模板&#xff0c;还不能直接运行&#xff0c;例如我们部署了一个请假流程&#xff0c;现在 张三想要请假&#xff0c;他就需…

交叉小波变换(cross wavelet transform)是什么?

小波变换可以很好的在时频域中分析单个信号的瞬态和突变等时变特性&#xff0c;交叉小波变换是在小波变换的基础上提出的&#xff0c; 主要用来处理两个信号之间的相关程度。传统的互相关分析方法&#xff0c; 是通过傅里叶变换将信号从时域上转换到频域上&#xff0c;然后在频…

JavaScript实现输入数值求运算符的值

以下为a&#xff0c;a--&#xff0c;--a&#xff0c;a等运算符实现结果的代码 目录 前言 一、运算符&#xff08;x&#xff09; 2.1运行流程及思想 2.2代码段 2.3运行截图 二、运算符&#xff08;--x&#xff09; 3.1运行流程及思想 3.2代码段 3.3运行截图 三、输入数…

论文阅读 (88):Adversarial Examples for Semantic Segmentation and Object Detection

文章目录 1. 概述2 算法2.1 稠密对抗生成2.2 选择用于检测的输入提案 1. 概述 题目&#xff1a;用于语义分割和目标检测的对抗样本 核心点&#xff1a;将对抗性样本的概念扩展到语义分割和对象检测&#xff0c;并提出稠密对抗生成算法 (Dense adversary generation, DAG)。 引…

Python每日一练(20230427)

目录 1. 三数之和 &#x1f31f;&#x1f31f; 2. 编辑距离 &#x1f31f;&#x1f31f;&#x1f31f; 3. 翻转字符串里的单词 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏…

无人机监控交通流量实时传输路况智慧交通系统说明

项目介绍&#xff1a; “现在五星花园环岛通行状况良好&#xff0c;涪江路双向的通行状况也未出现拥堵&#xff0c;接送考生的车辆可以畅通行驶……”昨日上午 8 点 20 分&#xff0c;FM91.5南充交通音乐广播首次启用遥控无人飞行器服务考生。对市区易堵路段&#xff0c;特别是…