LinDaiDai/niubility-coding-js

⛽️第5期第4题:知道`insertAdjacentHTML`方法吗?

Opened this issue · 0 comments

知道insertAdjacentHTML方法吗?

这个方法是呆呆最近在看公司项目代码时了解到的,之前一直没有注意它。

首先对于它的用法:

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

其次它的作用对象是一个元素element,例如const container = document.getElementById('container')

语法上呢:

element.insertAdjacentHTML(position, text);
  • position:一个DOMString,也就是表示插入内容相对元素的位置,且必须是下面的字符串之一:
    • 'beforebegin':元素自身的前面。
    • 'afterbegin':插入元素内部的第一个子节点之前。
    • 'beforeend':插入元素内部的最后一个子节点之后。
    • 'afterend':元素自身的后面。
  • text:是要被解析为HTML或XML元素,并插入到DOM树中的 DOMString

案例

让我们来看看它的用法,例如🌰现在有一个HTML的结构为:

<div id="one">我是one</div>

JavaScript代码中加上这段话:

const one = document.getElementById('one');
one.insertAdjacentHTML('afterend', '<div id="two">我是two</div>');

现在最终的渲染结果就变成了这样:

<div id="one">我是one</div><div id="two">我是two</div>

工作上的用法

在项目中,主要可以应用于这样的场景:一个空的容器(你可以理解为一个div),开始需要一个loading的效果,在数据加载完毕之后,需要把loading取掉且清空容器内的元素并以其它方式重新渲染出容器的内容。

这里呆呆就以定时器来模拟一下数据加载的过程,实现代码如下:

<body>
	<div id="container"></div>
</body>
<script>
	const container = document.getElementById('container');
  const loading = '<div id="loading">loading</div>'; // loading可能是一个组件
  container.insertAdjacentHTML('beforeend', loading);
  setTimeout(() => {
    container.innerHTML = ''
  }, 2000)
</script>

(当然,我们不要为了刻意用而去用,适合自己的才是最好的)

安全问题

  • 使用 insertAdjacentHTML 插入用户输入的HTML内容的时候,需要转义之后才能使用。

    例如:

    const one = document.getElementById('one');
    // 由于 encodeURI('<div id="two">我是two</div>')会被转译为:
    // %3Cdiv%20id=%22two%22%3E%E6%88%91%E6%98%AFtwo%3C/div%3E
    // 因此最终会被当成 "%3Cdiv%20id=%22two%22%3E%E6%88%91%E6%98%AFtwo%3C/div%3E"字符串渲染
    one.insertAdjacentHTML('afterend', encodeURI('<div id="two">我是two</div>'));
  • 如果只是为了插入文本内容(而不是HTML节点),不建议使用这个方法,建议使用node.textContent 或者 node.insertAdjacentText()。因为这样不需要经过HTML解释器的转换,性能会好一点。(这里是引用的MDN-insertAdjacentHTML上的内容)