• 认清 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);
        })
    });
  • 相关阅读:
    安全检测点的一些梳理——待长期整理
    Tor真的匿名和安全吗?——如果是http数据,则在出口节点容易被嗅探明文流量,这就是根本问题
    prefixspan是挖掘频繁子序列,子序列不一定是连续的,当心!!!
    spark mllib prefixspan demo
    spark 2.4 java8 hello world
    有效的括号序列——算法面试刷题4(for google),考察stack
    相似的RGB颜色——算法面试刷题3(for google),考察二分
    回文的范围——算法面试刷题2(for google),考察前缀和
    最长绝对文件路径——算法面试刷题1(google),字符串处理,使用tree遍历dfs类似思路
    比较全面的gdb调试命令
  • 原文地址:https://www.cnblogs.com/yadi001/p/13560720.html
Copyright © 2020-2023  润新知