您当前的位置:首页 > 网站建设笔记 >

javascript innerHTML属性

来源:JavaScript高级程序设计0

虽然DOM为操作节点提供了细致入微的控制手段,但在需要给文档插入大量新HTML标记的情况下,通过DOM操作仍然非常麻烦,因为不仅要创建一系列DOM节点,而且还要小心地按照正确的顺序把它们连接起来。相对而言,使用插入标记的技术,直接插入HTML字符串不仅更简单,速度也更快。以下与插入标记相关的DOM扩展已经纳入了HTML5规范。

1. innerHTML属性

在读模式下,innerHTML属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的HTML标记。在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点。下面是一个例子:

对于上面的ID为biji的div元素来说,它的innerHTML属性在不同浏览器中会返回不同的字符串。

在写模式下,innerHTML的值会被解析为DOM子树,替换调用元素原来的所有子节点。因为它的值被认为是HTML,所以其中的所有标签都会按照浏览器处理HTML的标准方式转换为元素(同样,这里的转换结果也因浏览器而异)。如果设置的值仅是文本而没有HTML标签,那么结果就是设置纯文本。为innerHTML设置的包含HTML的字符串值与解析后innerHTML的值大不相同。设置了innerHTML之后,可以像访问文档中的其他节点一样访问新创建的节点。

使用innerHTML属性也有一些限制。比如,在大多数浏览器中,通过innerHTML插入<script>元素并不会执行其中的脚本。IE8及更早版本是唯一能在这种情况下执行脚本的浏览器,但必须满足一些条件。一是必须为<script>元素指定defer属性,二是<script>元素必须位于(微软所谓的)有作用域的元素(scoped element)之后。<script>元素被认为是无作用域的元素(NoScope element),也就是在页面中看不到的元素,与<style>元素或注释类似。如果通过innerHTML插入的字符串开头就是一个无作用域的元素,那么IE会在解析这个字符串前先删除该元素。换句话说,以下代码达不到目的:

div.innerHTML="<script defer>alert('你好');<\/script>";	//无效

此时,innerHTML字符串一开始(而且整个)就是一个无作用域的元素,所以这个字符串会变成空字符串。如果想插入这段脚本,必须在前面添加一个有作用域的元素,可以是一个文本节点,也可以是一个没有结束标签的元素如<input>。例如下面这几行代码都可以正常执行:

div.innerHTML="_<script defer>alert('你好');<\/script>";
div.innerHTML="<div>&nbsp;</div><script defer>alert('你好');<\/script>";
div.innerHTML="<input type=\"hidden\"><script defer>alert('你好');<\/script>";

第一行代码会在<script>元素前插入一个文本节点。事后,为了不影响页面显示,你可能需要移除这个文本节点。第二行代码采用的方法类似,只不过使用的是一个包含非换行空格的<div>元素。如果仅仅插入一个空的<div>元素,还是不行,必须要包含一点儿内容,浏览器才会创建文本节点。同样,为了不影响页面布局,恐怕还得移除这个节点。第三行代码使用的是一个隐藏的<input>域,也能达到相同的效果。不过,由于隐藏的<input>域不影响页面布局,因此这种方式在大多数情况下都是首选。

大多数浏览器都支持以直观的方式通过innerHTML插入<style>元素,例如:

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

但在IE8及更早版本中,<style>也是一个没有作用域的元素,因此必须像下面这样给它前置一个有作用域的元素:

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

并不是所有元素都支持innerHTML属性。不支持innerHTML的元素有:<col>、<colgroup>、<frameset>、<head>、<html>、<style>、<table>、<tbody>、<thead>、<tfoot>和<tr>。此外,在IE8及更早版本中,<title>元素也没有innerHTML属性。

Firefox对在内容类型为application/xhtml+xml的XHTML文档中设置innerHTML有严格的限制。在XHTML文档中使用innerHTML时,XHTML代码必须完全符合要求。如果代码格式不正确,设置innerHTML将会静默地失败。无论什么时候,只要使用innerHTML从外部插入HTML,都应该首先以可靠的方式处理HTML。IE8为此提供了window.toStaticHTML()方法,这个方法接收一个参数,即一个HTML字符串,返回一个经过无害处理后的版本——从源HTML中删除所有脚本节点和事件处理程序属性。下面就是一个例子:

var text="<a href=\"#\" onclick=\"alert('hi')\">Click Me</a>";
var sanitized=window.toStaticHTML(text);	//Internet Explorer 8 only
alert(sanitized);	//<a href=\"#\">Click Me</a>

这个例子将一个HTML链接字符串传给了toStaticHTML()方法,得到的无害版本中去掉了onclick属性。虽然目前只有IE8原生支持这个方法,但我们还是建议读者在通过innerHTML插入代码之前,尽可能先手工检查一下其中的文本内容。

顶部中部底部