innerTEXT與innerHTML的區別:
跨瀏覽器的設置innerHTML方法
2006年11月06日 星期一 09:37 A.M.
From:http://www.ajaxwing.com/index.php?c=DOM
Author:kenxu
很多人都可能遇到過這種情況:設置 innerHTML 的時候,插入的 HTML 代碼中包含腳本,但這些腳本卻不生效,或者在 IE
上生效在其它瀏覽器上就不生效。原因很簡單:不同瀏覽器對插入 innerHTML 中的腳本有不同的處理方法。經過實踐,歸納如下:
對於IE,首先 script 標籤必須帶 defer 屬性,其次在插入時刻,innerHTML 的所屬節點必須在 DOM 樹中;對於
Firefox 和 Opera,在插入時刻,innerHTML 的所屬節點不可以在 DOM 樹中。
根據上面結論,給出通用的設置 innerHTML 方法:
/*
* 描述:跨瀏覽器的設置 innerHTML 方法
* 允許插入的 HTML 代碼中包含 script 和 style
* 作者:kenxu <ken@ajaxwing.com>
* 日期:2006-03-23
* 參數:
* el: 合法的 DOM 樹中的節點
* htmlCode: 合法的 HTML 代碼
* 經測試的瀏覽器:ie5+, firefox1.5+, opera8.5+
*/
var setInnerHTML = function (el, htmlCode) {
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('msie') >= 0 &&
ua.indexOf('opera') < 0) {
htmlCode = '<div style="display:none">for
IE</div>' + htmlCode;
htmlCode =
htmlCode.replace(/<script([^>]*)>/gi,
'<script$1 defer="true">');
el.innerHTML = htmlCode;
el.removeChild(el.firstChild);
}
else {
var el_next = el.nextSibling;
var el_parent = el.parentNode;
el_parent.removeChild(el);
el.innerHTML = htmlCode;
if (el_next) {
el_parent.insertBefore(el, el_next)
} else {
el_parent.appendChild(el);
}
}
}
還有某些情況,我們事先不清楚要插入到 innerHTML 的 HTML 代碼包含什麼,如果包含 document.write
語句,那麼就會破壞整個頁面。對於這種情況,可以通過重新定義 document.write 來避免。代碼如下:
/*
* 描述:通過重定義 document.write 函數,避免在使用 setInnerHTML 時,
* 插入的 HTML 代碼中包含 document.write ,導致原頁面受到破壞的情況。
*/
document.write = function() {
var body = document.getElementsByTagName('body')[0];
for (var i = 0; i < arguments.length; i++) {
argument = arguments[i];
if (typeof argument == 'string') {
var el = body.appendChild(document.createElement('div'));
setInnerHTML(el, argument)
}
}
}
在這篇文章編寫之前,已經有一個比較完善的解決方法《讓插入到 innerHTML 中的 script
跑起來》。比較起來,《讓》給出的方法考慮得更細緻,但處理起來比較繁瑣,效率不高。而這裡給出的方法則更簡單,並且充分利用了瀏覽器的特性。
小心使用innerHTML
最近在做AJAX,想用javascript實現DataList功能,遇到一個棘手的問題,由於要生成的HTML很長,所以我寫成如下的形式:
list.innerHTML="<table><tr>";
list.innerHTML+="<td>"
......
但是這樣生成的innerHTML始終不對,研究了半天,原來是innerHTML搞得鬼.innerHTML自帶了語法檢查功能,他會自動把不完整的
HTML代碼補充完整.運行如下的一個測試代碼就可以發現了.
document.getElementById("AlbumList").innerHTML="<table><tr>";
alert(document.getElementById("AlbumList").innerHTML);
他會自動把我的代碼裡面添加了<tbody>和</tr><
/table>等標記.神奇!!!
那麼不讓他自動填寫的一個辦法就是用一個中間變量:
var html="<table><tr>";
html+="<td>";
......
list.innerHTML=html;
就這樣就可以解決問題了.
innerHTMl和確認提示的使用
今天開發中涉及到對一個層的信息控制,就是控制一個層中顯示什麼信息,查找資料才知道使用innerHTML屬性來控制層的值,這個innerHTML跟
表單裡面的value屬性有點類似,能夠控制層的顯示值。
比如說我一個div層裡本來沒有值,我處罰一個事件後要顯示值,那麼就能夠使用innerHTML屬性了,其實innerHTML屬性除了能控制層以外,
還能控制窗口內容的所有元素,但是我沒有測試過。
(1)對div標籤的控制
div標籤跟span標籤是不一樣的,div是一個層的塊,span是一行,我們下面看演示就知道區別了。先來看一段控制div的代碼。
<script language="javascript">
function chageDiv(number)
{
if (number == 1) {
document.getElementById("div1").innerHTML = "值為1";
}
if (number == 2) {
document.getElementById("div1").innerHTML = "值為2";
}
}
</script>
DIV塊測試:<div id="div1">默認值</div>
<a href="#" onClick="chageDiv(1)">改變值為1</a>
<a href="#" onClick="chageDiv(2)">改變值為2</a>
運行的時候,點擊「改變值為1」那麼「默認值」這個內容將會被改變為「值為1」,但是注意其中的界面,就是會發現「DIV測試:」和「默認值」是兩行顯示
的,因為DIV是按塊來顯示的。
(2)對span的控制
與div類似,但是它是按照行來顯示的,看下面的代碼:
function chageSpan(number)
{
if (number == 1) {
document.getElementById("span1").innerHTML = "值為1";
}
if (number == 2) {
document.getElementById("span1").innerHTML = "值為2";
}
}
</script>
Span行測試:
<span
id="span1">默認值</span><br>
<a href="#" onClick="chageSpan(1)">改變值為1</a>
<a href="#" onClick="chageSpan(2)">改變值為2</a>
當點擊「改變值為1」的時候,「默認值」將變為「值為1」,但是「Span行測試」和「默認值」是在同一行顯示的,跟DIV不一樣。
另外一個值得注意的就是,不管是div還是span,後面的名字都是以為id來定義的,不是象表單一樣是使用name來定義的。
(3)confirm確認提示框的製作
當我們要執行一個危險操作的時候,比如刪除某個內容等,那麼就應該給用戶相應的提示來用戶不容易犯錯誤。一般提示都是使用confirm()函數來處理
的,給它提交一個參數作為顯示的信息提示,那麼訪問的時候將彈出對話框,如果點擊了「確定」那麼將改函數返回true,點擊了「取消」將放回
false,我們針對這個特點來使用兩種方法來控制用戶是否執行某個操作。
看代碼:
<script language="javascript">
function accessNeteasy()
{
if(confirm('你真的要訪問網易新聞 ?')) {
location='http://calendar.eyou.eyou';
}
}
function accessSina()
{
if (confirm('你確定要訪問新浪新聞 ?')) {
return true;
} else {
return false;
}
}
</script>
訪問方式一:
<a href="#"
onClick="accessNeteasy()">網易新聞</a><br&
gt;
訪問方式二:
<a href="http://news.sina.com.cn" onClick="return
accessSina()">新浪新聞</a>
我們這裡建立了兩個函數,一個accessNeteay,一個accessSina,就是訪問網易和新浪,我們使用不同的方法,第一種就是當點了鏈接以
後,判斷如果是true的話,那麼就location到指定鏈接,這種方法比較不具有通用型,只能針對單個的鏈接。第二種方法是使用返回值的形式,當確定
要訪問的時候返回true,不確定的時候返回false,那麼這個可以針對任何鏈接來做,寫成一個通用的信息提示,方便頁面中的調用。
以上代碼都經過測試通過,可以自己再這個基礎上進行擴展,寫出自己需要的JavaScript代碼。