标签:
innerHTML在读模式下,返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的HTML标记。在写模式下,innerHTML会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先的所有子节点。
[注意]并不是所有元素都支持innerHTML属性,不支持innerHTML的属性有:<col>、<colgroup>、<frameset>、<head>、<html>、<style>、<table>、<tbody>、<thead>、<tfoot>、<tr>。在IE8-浏览器中<title>元素也没有该属性
<ul class="list" id="list"> <li class="in" >1</li> <li class="in ab" >2</li> <li class="in ab c">3</li> </ul> <script> //IE8-浏览器会将所有标签转换成大写形式,且不包含空白文本节点;而其他浏览器则原样返回 var oList = document.getElementById("list"); console.log(oList.innerHTML); </script>
[a]如果设置的值只是文本,则结果就是设置纯文本
<div class="box" id="box"></div> <script> var oBox = document.getElementById("box"); oBox.innerHTML = "hello world!";//页面显示hello world! </script>
[b]如果设置的值包含HTML标签,则浏览器会将这个字符串解析成相应的DOM树
<div class="box" id="box"></div> <script> var oBox = document.getElementById("box"); oBox.innerHTML = "Hello & welcome, <b>‘reader‘</b>";//页面显示Hello & welcome, ‘reader‘ </script>
无论什么时候,只要使用innerHTML从外部插入HTML,都应该首先以可靠的方式处理HTML。IE浏览器提供了window.toStaticHTML()方法,这个方法接收一个参数,即一个HTML字符串;返回一个经过无害处理后的版本——从源HTML中删除所有脚本节点和事件处理程序属性。
var text = "<a href=‘#‘ onclick = ‘alert(\"hi\");‘>Click Me</a>"; var sanitized = window.toStaticHTML(text); //只有IE支持 console.log(sanitized);//<a href="#">Click Me</a>
【限制】
【<script>】
大多数浏览器中,通过innerHTML插入<script>元素并不会执行其中的脚本。IE9-浏览器在满足一定条件下可以执行脚本,一是为<script>元素设置defer属性,二是<script>元素必须位于“有作用域的元素”之后。如果通过innerHTML插入的字符串开头就是一个“无作用域的元素”,那么IE会在解析这个字符串前先删除该元素。
<div class="box" id="box"></div> <script> var oBox = document.getElementById("box"); //innerHTML字符串一开始就是一个无作用域的元素,所以这个字符串会变成空字符串。 oBox.innerHTML = "<script defer>alert(‘hi‘);<\/script>"; </script> 如果想插入这段脚本,必须在前面添加一个有作用域的元素,可以是一个文本节点,也可以是一个没有结束标签的元素如<input>。以下这三种方法都可以让页面弹出"hi"; <div class="box" id="box"></div> <script> var oBox = document.getElementById("box"); oBox.innerHTML = " <script defer>alert(‘hi‘);<\/script>"; oBox.innerHTML = "<div> </div><script defer>alert(‘hi‘);<\/script>"; oBox.innerHTML = "<input type=‘hidden‘><script defer>alert(‘hi‘);<\/script>"; </script>
【<style>】
大多数浏览器都支持以直观的方式通过innerHTML插入<script>标签
<div class="box" id="box"></div> <script> var oBox = document.getElementById("box"); //IE8-浏览器无变化,其他浏览器背景变成红色 oBox.innerHTML = "<style type=‘text\/css‘>body{background-color: red;}</style>"; </script> 由于IE8-浏览器中,<style>是一个没有作用域的元素,所以必须设置一个前置的作用域元素 <div class="box" id="box"></div> <script> var oBox = document.getElementById("box"); oBox.innerHTML = "_<style type=‘text\/css‘>body{background-color: red;}</style>"; oBox.removeChild(oBox.firstChild); </script>
在读模式下outerHTML返回调用它的元素及所有子节点的HTML标签。在写模式下,outerHTML会根据指定的HTML字符串创建新的DOM子树,然后用这个DOM子树完全替换调用元素。
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul> <script> var oList = document.getElementById(‘list‘); /*返回 <ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul>*/ //IE8-浏览器会将所有标签转换成大写形式,且不包含空白文本节点 console.log(oList.outerHTML); </script>
写模式下新创建的元素将取代本身
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul> <script> var oList = document.getElementById(‘list‘); oList.outerHTML = "<div></div>"; console.log(document.getElementById(‘list‘));//null </script>
通过innerText属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过innerText读取值时,它会按照由浅入深地顺序,将子文档树中的所有文本拼接起来。在通过innerText写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点。(firefox不支持)
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul> <script> var oList = document.getElementById(‘list‘); console.log(oList.innerText);//除了firefox,其他浏览器都输出1 2 oList.innerText="hello & welcome <b>reader</b>";//页面上显示hello & welcome <b>reader</b> </script>
除了作用范围扩大到了包含调用它的节点之外,outerText与innerText基本上没有多大区别,在读取文本值时,outerText与innerText的结果完全一样,但在写模式下,outerText就完全不同了:outerText不只是替换调用它的元素的子节点,而是会替换整个元素。(firefox不支持)
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul> <script> var oList = document.getElementById(‘list‘); console.log(oList.outerText);//1 2 oList.outerText = "hello & welcome <b>reader</b>";//页面上显示hello & welcome <b>reader</b> console.log(document.getElementById(‘list‘));//null </script>
textContent属性与innerText属性类似。但实际上innerText与textContent返回的内容并不完全一样。innerText会忽略行内的样式和脚本,而textContent则会像返回其他文本一样,返回行内的样式和脚本。避免跨浏览器兼容的问题的最佳途径,就是从不包含行内样式或行内脚本的DOM子树副本或DOM片段中读取文本(IE8-浏览器不支持)
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul> <script> var oList = document.getElementById(‘list‘); console.log(oList.textContent);//除了IE8-浏览器,其他浏览器都输出1 2 oList.textContent="hello & welcome <b>reader</b>";//页面上显示hello & welcome <b>reader</b> </script>
所以,innerText与textContent的兼容写法为:
<ul class="list" id="list"> <li class="in">1</li> <li class="in">2</li> </ul> <script> var oList = document.getElementById(‘list‘); function getInnerText(element){ return (typeof element.textContent == "string") ? element.textContent : element.innerText; } function setInnerText(element,text){ if(typeof element.textContent == "string"){ element.textContent = text; }else{ element.innerText = text; } } console.log(getInnerText(oList));//1 2 setInnerText(oList,"hello & welcome <b>reader</b>")//页面上显示hello & welcome <b>reader</b> </script>
当某个元素有一个事件处理程序,在使用某个属性将该元素从文档树中删除后,元素与事件处理程序之间的绑定关系在内存中并没有一并删除,如果这种情况频繁出现,页面占用的内在数量就会明显增加。因此,使用innerHTML、outerHTML属性时,最好先手工删除要被替换元素的所有事件处理程序和JavaScript对象属性。
最好将设置innerHTML或outerHTML的次数控制在合理的范围内。
for(var i = 0; len = values.length; i < len; i++){ //要避免这种频繁操作 ul.innerHTML += "<li>" + values[i] + "</li>"; }
这种每次循环都设置一次innerHTML的做法效率很低,而且,每次循环还要从innerHTML中读取一次信息,就意味着每次循环要访问两次innerHTML。最好的做法是单独构建字符串,然后再一次性地将字符串赋值给innerHTML。
var itemsHtml = ""; for(var i = 0; len = values.length; i < len; i++){ itemsHtml += "<li>" + values[i] + "</li>"; } //这种效率要高得多,因为它只对innerHTML执行了一次赋值操作。 ul.innerHTML = itemsHtml;
标签:
原文地址:http://www.cnblogs.com/xiaohuochai/p/4841679.html