插入标记

79 阅读3分钟

这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战

前言

DOM 虽然已经为操纵节点提供了很多 API ,但向文档中一次性插人大量 HTML 时还是比较麻怖相比先创建一堆节点,再把它们以正确的顺序连接起来,直接插人一个 HTML 学符串要简单(快谏)得多。HTML5已经通过以下 DOM 扩展将这种能力标准化了。今天我们来讲一讲插入标记。

插入标记

 DOM 虽然已经为操纵节点提供了很多 API ,但向文档中一次性插人大量 HTML 时还是比较麻怖相比先创建一堆节点,再把它们以正确的顺序连接起来,直接插人一个 HTML 学符串要简单(快谏)得多。HTML5已经通过以下 DOM 扩展将这种能力标准化了。
1.innerНТ ML 属性
在读取 innerHTML 属性时,会返回元素所有后代的 HTML 字符串,包括元素、注释和文本节点。而在写人 innerHTML 时,则会根据提供的字符串值以新的 DOM 子树替代元素中原来包含的所有节点。比如下面的 HTML 代码:

< divid =" content ">
< p > This is a < strong > paragraph </ strong > with a list following it .</ p >
< li >Item1</ li >< li > Item 2</ li >< li > Item 3</ li ></ ul >
</ div >

对于这里的< div >元素而言,其 innerHTML 属性会返回以下字符串:

< p > This is a < strong > paragraph </ strong > with a list following it .</ p >

<1i> Item 1</1i>< li > Item 2</1i>< li > Item 3</1i></ ul >\

实际返回的文本内容会因浏览器而不同。 IE 和 Opera 会把所有元素标签转换为大写,而 Safari 、 rome 和 Firefox 则会按照文档源代码的格式返回,包含空格和缩进。因此不要指望不同浏览器的 nerHTML 会返回完全一样的值。
在写人模式下,赋给 innerHTML 属性的值会被解析为 DOM 于树,并替代元素之前的所有节点。为所赋的值默认为 HTML ,所以其中的所有标签都会以浏览器处理 HTML 的方式转换为元素(同样,结果也会因浏览器不同而不同)。如果赋值中不包含任何 HTML 标签,则直接生成一个文本节点,如下所示:
div . innerHTML =" Hello world !";

因为浏览器会解析设置的值,所以给 innerHTML 设置包含 HTML 的字符串时,结果会大不一样。来看下面的例子:
div . innerHTML =" Hello & welcome ,< b >\" reader \"!</ b >;

这个操作的结果相当于:
< div id =" content "> Hello & amp ; welcome ,< b >& quot ; reader & quot ;!</ b ></ div > 设置完 innerHTML ,马上就可以像访问其他节点一样访问这些新节点。 注意设置 innerHTML 会导致浏览器将 HTML 字符串解析为相应的 DOM 树。这意味着设置 innerHTML 属性后马上再读出来会得到不同的字符串。这是因为返回的字符串是将原始字符串对应的 DOM 子树序列化之后的结果。

内存与性能问题

庙用本节介绍的方法替换子节点可能在浏览器(特别是 IE )中导致内存问题。比如,如果被移除的树元素中之前有关联的事件处理程序或其他 JavaScript 对象(作为元素的属性),那它们之间的绑定关滞留在内存中。如果这种替换操作频紧发生,页面的内存占用就会持续攀升。在使 用 innerHTML 、 auterHTML 和 insertAdjacentHTML ()之前,最好手动删除要被替换的元素上关联的事件处理程序和 JavaScript 对象。
使用这些属性当然有其方便之处,特别是 innerHTML 。一般来讲,插人大量的新 HTML 使用 imerHTML 比使用多次 DOM 操作创建节点再插人来得更便捷。这是因为 HTML 解析器会解析设置给 innerHTML (或 outerHTML )的值。解析器在浏览器中是底层代码(通常是 C ++代码),比 JavaScript 快得多。不过, HTML 解析器的构建与解构也不是没有代价,因此最好限制使用 innerHTML 和 outerHTML 的次数。