zoukankan      html  css  js  c++  java
  • 认清 Node.appendChild()

    Node.appendChild() 方法用于将一个节点添加到指定父节点的子节点列表的末尾,但在具体使用时还有其他一些需要我们关注的细节,以及对应的应用场景。

    常规操作

    大家都清楚 appendChild 可以把创建好的元素插入到另一个元素内容的最后面,常规操作如下:

    // 创建元素
    var oDiv = document.createElement('div');
    // 给创建好的元素加点内容
    oDiv.innerHTML = 'hello world';
    // 添加到 body 里面
    document.body.appendChild(oDiv);

    需要注意

    上面代码必然没有任何问题,但这里还有一点需要大家注意的是,appendChild 在插入已存在元素的时候其实是做了两件事的:

    1. 先把原来已存在的元素删除
    2. 再进行后续的添加操作

    具体是什么意思呢?大家看下面的例子就清楚了。需求:每次点击按钮把上面 ul 中的第一个元素移动到下面的 ul 中:

    <ul id="ul1">
        <li>aaa</li>
        <li>bbb</li>
        <li>ccc</li>
        <li>ddd</li>
    </ul>
    <button id="btn">插入下面</button>
    <ul id="ul2"></ul>
    <script>
    // 选择元素
    var oUl1 = document.querySelector('#ul1');
    var oBtn = document.querySelector('#btn');
    var oUl2 = document.querySelector('#ul2');
    oBtn.onclick = function() {
        var oLi = oUl1.children[0];
        // 每次点击按钮确实在 oUl2 中添加了一个新的元素,但同时 oUl1 中也相应少了这个元素
        // 所以 appendChild 时相当于偷偷帮我们做了这么一步操作:oUl1.removeChild(oLi);
        oUl2.appendChild(oLi);
    };
    </script>

    实际应用

    清楚了当用 appendChild 插入已存在元素时会先删除之前再进行插入,那明白这个特性有什么实际的用处吗?答案是肯定的。例如下面一个需求,点击按钮,根据元素中的数字大小对这组元素进行排序:

    <!-- HTML 结构 -->
    <ul id="ul1">
        <li>5</li>
        <li>2</li>
        <li>3</li>
        <li>1</li>
        <li>4</li>
    </ul>
    <button id="btn">点击</button>
    // 选择元素
    var oUl1 = document.querySelector('#ul1');
    var aLi = oUl1.querySelectorAll('li');
    var oBtn = document.querySelector('#btn');
    
    // 把伪数组 aLi 中的每一项都放到数组里面,目的是为了进行排序
    var arr = [];
    for(var i = 0; i < aLi.length; i ++) {
        arr.push(aLi[i]);
    }
    
    oBtn.onclick = function () {
        // 这就是我们熟悉的冒泡排序,你还记得吗
        for (var i = 0; i < arr.length - 1; i++) { // 需要走 arr.length - 1 轮
            for (var j = 0; j < arr.length - i - 1; j++) { // 每轮比较 arr.length - i - 1 次
                var prevNum = parseFloat(arr[j].innerText);
                var nextNum = parseFloat(arr[j + 1].innerText);
                if (prevNum > nextNum) {
                    // 不能对伪数组中其中一些直接赋值,例如:aLi[j] = aLi[j+1],所以需要把伪数组转换成数组后再进行排序
                    var temp = null;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        // 此时 arr 中装的已经是排好序的一堆 li 元素了
        for(var i = 0; i < arr.length; i ++) {
            // 分别把排好序的数组中的每个元素插入到 oUl1 内容的最后
            // 注意每次插入的同时也会把 oUl1 中那个相同的元素先给干掉,所以 oUl1 中也就不会存在重复元素的问题
            oUl1.appendChild(arr[i]);
        }
    };

    优化代码

    const oUl1 = document.querySelector('#ul1');
    const aLi = oUl1.querySelectorAll('li');
    const oBtn = document.querySelector('#btn');
    
    oBtn.addEventListener('click', () => {
        // Array.from 可以把伪数组转成数组,sort 的原理就是上面写的冒泡排序
        Array.from(aLi).sort((li1, li2) => {
            return parseFloat(li1.innerText) - parseFloat(li2.innerText);
        }).forEach(li => {
            oUl1.appendChild(li);
        })
    });
  • 相关阅读:
    C语言丨二维数组常用的4种表示方法
    据说程序员最怕命名!这个 6300 Star 的手册能帮上忙
    C语言基础丨(六)程序结构——分支(选择)结构【2】
    系统管理员应该知道的 20 条 Linux 命令!越早学会越好!
    憋不住了!这8 个 MySQL 陷阱,我不得不说一下...
    记录一次@Around使用不正确造成的StackOverflowError
    【java基础】为何e1==(e1=e2)为false
    《Java程序性能优化》subString()方法的内存泄露
    【爬虫】花瓣采集下载器
    SpringMVC容器加载流程总结
  • 原文地址:https://www.cnblogs.com/yadi001/p/13560720.html
Copyright © 2011-2022 走看看