js 旧 IE 中的 innerHTML

时间:2024-01-24 20:00:16

在所有现代浏览器中,通过 innerHTML 插入的<script>标签是不会执行的。而在 IE8 及之前的版 本中,只要这样插入的<script>元素指定了 defer 属性,且<script>之前是“受控元素”(scoped element),那就是可以执行的。<script>元素与<style>或注释一样,都是“非受控元素”(NoScope element),也就是在页面上看不到它们。IE 会把 innerHTML 中从非受控元素开始的内容都删掉,也就 是说下面的例子是行不通的:

```js

// 以下都可行

div.innerHTML = "_<script defer>console.log('hi');<\/script>";

div.innerHTML = "<div>&nbsp;</div><script defer>console.log('hi');<\/script>"; div.innerHTML = "<input type=\"hidden\"><script defer>console. log('hi');<\/script>";

```


第一行会在<script>元素前面插入一个文本节点。为了不影响页面排版,可能稍后需要删掉这个 文本节点。第二行与之类似,使用了包含空格的<div>元素。空<div>是不行的,必须包含一点内容, 以强制创建一个文本节点。同样,这个<div>元素可能也需要事后删除,以免影响页面外观。第三行使 用了一个隐藏的<input>字段来达成同样的目的。因为这个字段不影响页面布局,所以应该是最理想的 方案。

在 IE 中,通过 innerHTML 插入<style>也会有类似的问题。多数浏览器支持使用 innerHTML 插 入<style>元素:

```js

div.innerHTML = "<style type=\"text/css\">body {background-color: red; }</style>"; 但在 IE8 及之前的版本中,<style>也被认为是非受控元素,所以必须前置一个受控元素:

```

 


```js

div.innerHTML = "_<style type=\"text/css\">body {background-color: red; }</style>";

   div.removeChild(div.firstChild);

```

## 3. outerHTML 属性

读取 outerHTML 属性时,会返回调用它的元素(及所有后代元素)的 HTML 字符串。在写入 outerHTML 属性时,调用它的元素会被传入的 HTML 字符串经解释之后生成的 DOM 子树取代。比如 下面的 HTML 代码:

```js

<div id="content">

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

       <li>Item 1</li>

       <li>Item 2</li>

       <li>Item 3</li>

</ul> </div>

```

在这个<div>元素上调用 outerHTML 会返回相同的字符串,包括<div>本身。注意,浏览器因解 析和解释 HTML 代码的机制不同,返回的字符串也可能不同。(跟 innerHTML 的情况是一样的。)

如果使用 outerHTML 设置 HTML,比如:

```js

div.outerHTML = "<p>This is a paragraph.</p>";

```

则会得到与执行以下脚本相同的结果:

```js

let p = document.createElement("p"); p.appendChild(document.createTextNode("This is a paragraph.")); div.parentNode.replaceChild(p, div);

```

新的<p>元素会取代 DOM 树中原来的<div>元素。

## 4. insertAdjacentHTML()与 insertAdjacentText()

关于插入标签的最后两个新增方法是 insertAdjacentHTML()和 insertAdjacentText()。这两 个方法最早源自 IE,它们都接收两个参数:要插入标记的位置和要插入的 HTML 或文本。第一个参数 必须是下列值中的一个:

 "beforebegin",插入当前元素前面,作为前一个同胞节点;

 "afterbegin",插入当前元素内部,作为新的子节点或放在第一个子节点前面;

 "beforeend",插入当前元素内部,作为新的子节点或放在最后一个子节点后面;

 "afterend",插入当前元素后面,作为下一个同胞节点。 注意这几个值是不区分大小写的。第二个参数会作为 HTML 字符串解析(与 innerHTML 和

outerHTML 相同)或者作为纯文本解析(与 innerText 和 outerText 相同)。如果是 HTML,则会 在解析出错时抛出错误。下面展示了基本用法1 假设当前元素是<p>Hello world!</p>,则"beforebegin"和"afterbegin"中的"begin"指开始标签<p>;而 "afterend"和"beforeend"中的"end"指结束标签</p>。

   注意 Firefox在内容类型为application/xhtml+xml的XHTML文档中对innerHTML 更加严格。在 XHTML 文档中使用 innerHTML,必须使用格式良好的 XHTML 代码。否 则,在 Firefox 中会静默失败。


```js

 // 作为前一个同胞节点插入

element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>"); element.insertAdjacentText("beforebegin", "Hello world!");

// 作为第一个子节点插入

element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>"); element.insertAdjacentText("afterbegin", "Hello world!");

// 作为最后一个子节点插入

element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>"); element.insertAdjacentText("beforeend", "Hello world!");

// 作为下一个同胞节点插入

element.insertAdjacentHTML("afterend", "<p>Hello world!</p>"); element. insertAdjacentText("afterend", "Hello world!");

```