insertAdjacentHTML()真香!!!(附使用教程和打地鼠案例)

1,265 阅读4分钟

「Offer 驾到,掘友接招!我正在参与2022春招系列活动-经验复盘,点击查看 征文活动详情

一、insertAdjacentHTML()简介

insertAdjacentHTML() 方法是将文本解析为 element 元素,并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接使用innerHTML操作更快。

上面是MDN给到的解释

由于我对这个方法爱不释手,所以我大胆的 Think:

insertAdjacentHTML() 是Element的API中的一个方法,可以将字符串文本转化为你想要的节点(Node),并且插入到你想要插入的位置中。而且它并不会向innerHTML一样会替换掉已有的节点,而是会插入到指定位置。

二、使用

element.insertAdjacentHTML(position,text)

参数:position

position顾名思义,就是想要插入的位置,一共有4个固定的值

  • 'beforebegin':元素element自己的前面。
  • 'afterbegin':插入到元素element里面的第一个子节点之前(也就是总是会插入到最前面,例如我插入5个节点,顺序是1、2、3、4、5,那么我就需要以5、4、3、2、1的顺序插入,有一种栈结构先进后出的感觉)。
  • 'beforeend':插入元素element里面的最后一个子节点之后(这个比较容易理解,就是插入到最后一个节点后,例如我插入5个节点,顺序是1、2、3、4、5,那就正常的1、2、3、4、5就好啦,但是注意是在已有节点的后面哦)。
  • 'afterend':元素element自己的后面。

无标题.png

大家注意到没,position都是以两个单词两个部分结合在一起来指定位置的,可以这样来巧记(结合上面的位置图)

前面是before/after 在...前/在...后 灰色的线(盒子上下边界) 就可以作为一个分界,在分界前面就是before,在分界后就是after

后面是begin/end 开始/结束 在上面的,不管是内部节点上面,还是盒子上面那就是开始的地方begin。同理,在下面的,不管是内部节点下面,还是盒子下面那就是结束的地方end

有没有觉得稍微好记一点了呢

参数:text

第二个参数便是你想要插入的HTML语句,或者是XML形式也行,插入到DOM树中DOMString中 可以是字符串形式,也可以用ES6新增的模板字符串的形式

示例1

实现这样一个超级简单的效果 一个父盒子里面有3个子盒子,子盒子的编号顺序为1,2,3 image.png

方法炒鸡多,可以使用直接写结构和样式的方法,使用js创建div节点,再append/appendChild到父盒子里面的方法。

BUT NOW

尝试用insertAdjacentHTML()来实现,js代码如下

let root = document.querySelector(".root") // 获取父盒子
    let num = 1; //编号
    let str = ` <div class="box">${num}</div>`  //需要添加的HTML

    for (let i = 0; i < 3; i++) {
        root.insertAdjacentHTML("beforeend", ` <div class="box">${num}</div>`)
        num++; 
        
    }

我们来尝试一下将位置改成afterbegin,但是num编号依然是从1-3会是怎样

是的,它会变成3、2、1,就像上面讲的一样,会是先进的反而垫底的效果

image.png

“香”在哪儿

我常用这个方法代替一些需要使用append()或者appendChild()和innerHTML的地方。

append和appendChild的用法和区别

我们先来回忆一下append()和appendChild()的作用和区别

append()可以添加节点Node和DOMString(大部分是文本)到父元素的内部

appendChild()可以Node节点到父元素的内部,插入节点会报错

MDN阐述如下:

差距具体如下,取自MDN

具体的用法可以在社区参考别的掘友的文章

innerHTML

innerHTML也可以插入文本,但是它会替换掉已有的Html,所以常常需要+=,并且因为会经过序列化的步骤,效率也会稍微低一些

模板字符串 + insertAdjacentHTML()

真的不要太爽,不用再慢慢的创建节点和找父亲、加孩子了 这两个搭配还可以用于写Todolist、或者需要添加重复节点的功能中,以这个打地鼠的例子为示范:

var holes = document.querySelector('.holes')
    var str = `<div class="hole">
                  <img src="img/mouse.png" class="mouse">
                  <img src="img/boom.png" class="boom" alt="">
                  <img src="img/hole.png" alt="">
               </div>`
    for (var i = 0; i < 9; i++) {
       holes.insertAdjacentHTML("afterbegin", str)
      }

这样就可以快速的添加好每一个地洞啦,妈妈再也不用担心我会秃头啦

image.png

还有添加元素的 Element.insertAdjacentElement()

添加文本的Element.insertAdjacentText()

性能问题

注意尽量避免让用户输入文本或者HTML,这样会导致HTML编译器的转化,性能会低一点

小老鼠打地洞代码

附上打地鼠的完整代码

<!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>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .holes {
            width: 600px;
            height: 600px;
            margin: 10px auto;
            border: 1px solid #000;
            display: flex;
            flex-wrap: wrap;
        }
        
        .hole {
            width: 200px;
            height: 200px;
            outline: 1px solid red;
            position: relative;
        }
        
        .hole>img {
            width: 200px;
            height: 200px;
            position: absolute;
        }
        
        .hole>img.mouse {
            width: 150px;
            height: 150px;
            z-index: 2;
            top: 15px;
            left: 25px;
            display: none;
        }
        
        .hole>img.boom {
            z-index: 2;
            display: none;
        }
        
        .holes:hover {
            cursor: url('img/hammer.ico'), auto;
        }
        
        .holes:active {
            cursor: url('img/hammerdown.ico'), auto;
        }
    </style>
</head>

<body>
    <div class="holes">

    </div>
    <script>
        window.onload = function() {
            var holes = document.querySelector('.holes')
            var str = `  <div class="hole">
            <img src="img/mouse.png" class="mouse">
            <img src="img/boom.png" class="boom" alt="">
            <img src="img/hole.png" alt="">
        </div>`
            for (var i = 0; i < 9; i++) {
                holes.insertAdjacentHTML("afterbegin", str)
            }

            var hole = document.querySelectorAll('.hole')
            var mouse = document.querySelectorAll('.mouse')
            console.log(holes);

            function displayMouse() {
                var siteNum = Math.floor(Math.random() * 9)
                    //console.log(siteNum, hole[siteNum]);
                hole[siteNum].querySelector('.mouse').style.display = 'block'
            }
            //  setInterval(displayMouse, 1000)

            // 给小老鼠绑定事件 只有显示的小老鼠才能绑定事件
            for (var i = 0; i < mouse.length; i++) {
                mouse[i].addEventListener('click', function() {
                    var that = this
                    that.style.display = 'none'
                    that.nextElementSibling.style.display = 'block'
                    setTimeout(function() {
                        that.nextElementSibling.style.display = 'none'
                    }, 1000)
                })
            }
        }
    </script>
</body>

</html>

QQ截图20211222183041.png

小白日常学习记录,欢迎各路神仙指点