捕捉childNodes在不同瀏覽器中的差異

 
       這幾天開始嘗試用AJAX做點小程序,在用responseXML從XML文件裏取值時發現在IE與MF(Mozilla Firefox)中childNodes的表現有很大的不同。具體表現如下:
首先,我寫個了個XML文件(member.xml):
<?xml version="1.0" encoding="UTF-8"?>
<St_Member>
<MemId>10002</MemId>
<MemNickName>Siuery</MemNickName>
<St_Mem_Ishow>
<Photo>8.2</Photo>
<Design>7.8</Design>
<Text>6.7</Text>
<Visage>6.6</Visage>
<Stature>6.2</Stature>
<Grace>6.1</Grace>
</St_Mem_Ishow>
</St_Member>
現在要取節點St_Mem_Ishow下六個子節點(Photo、Design、Text、Visage、Stature、Grace)裏的數據,我寫了個getScore()函數來完成取節點操作,如下:
function getScore()
   
{
      
var voteItemStr="Photo|Design|Text|Visage|Stature|Grace"
;
      
var voteItem=voteItemStr.split("|"
);

      
if (http_request.readyState ==
 READY_STATE_COMPLETE)
      
{
         
if (http_request.status == 200
)
         
{
            
var xmlDoc=
http_request.responseXML;
            
var getIshow=xmlDoc.getElementsByTagName("St_Mem_Ishow"
);
            
            
if
(getIshow)
            
{
              
for(var i=0;i<6;i++
)
              
{
                $(voteItem[i]).innerHTML
=getIshow[0
].childNodes[i].firstChild.data;
              }

            }

          }

          
else
          
{
            
if($("f1")){$("f1").innerHTML="fail to call back!";}

          }

       }

       
else
       
{
         
for(i=0;i<6;i++
)
         
{
           $(voteItem[i]).innerHTML
="..."
;
         }

       }

    }
正如所料,IE裏取值表現良好,如圖:
但在MF裏卻另一番景象:
再打開MF裏的JavaScript控制檯一看,有一個錯誤如下:
getIshow[0].childNodes[i].firstChild沒有屬性,意思也就是firstChild根本沒找到!這是怎麼回事呢?後來上網查查資料,一篇標題爲《Mozilla Firefox與IE瀏覽器的javascript兼容性問題》的文章提示了我,文章裏這樣提到:
childNodes的下標的含義在IE和MF中不同,MF使用DOM規範,childNodes中會插入空白文本節點。一般可以通過node.getElementsByTagName()來回避這個問題。
在IE裏,當取節點的值時,我一般習慣性地認爲:當我們用getElementsByTagName(“markNode”)定位到markNode節點(如下XML模型)時,它的第一個子節點childNode1可以用getElementsByTagName(“markNode”).childNodes[0]來定位找到,而childNode1中的數據data1,我們則可以用getElementsByTagName(“markNode”).childNodes[0].firstChild.data來定位取到。
<markNode>
<childNode1>data1</childNode1>
<childNode2>data2</childNode2>
</markNode>
(肯定有兄弟會問:爲什麼不是用getElementsByTagName(“markNode”).childNodes[0].data來取值呢?道理很簡單,我們得把data1也當作childNode1下第一個子節點裏得數據,而且肯定只有這樣理解,我們才能取到data1的數據,否則照getElementsByTagName(“markNode”).childNodes[0].data取值,IE會顯示“undefined”,也就意味着data在childNodes[0]根本未定義。)
在MF中getElementsByTagName(“markNode”).childNodes[0].firstChild.data未定位到“data1”,這究竟是什麼緣故呢,仔細回味《Mozilla Firefox與IE瀏覽器的javascript兼容性問題》中那句話:“childNodes中會插入空白文本節點”,我打算嘗試確定一下空白文本節點到底指的是什麼,在什麼地方出現。還是拿member.xml來試試,我把getScore()函數改了下,使它能alert出六個節點的類型。代碼如下:
function getScore()
   
{
      …

      
if (http_request.readyState ==
 READY_STATE_COMPLETE)
      
{
         
if (http_request.status == 200
)
         
{

            
            
if
(getIshow)
            
{
              
for(var i=0;i<6;i++
)
              
{
                alert(getIshow[
0
].childNodes[i]);
              }

            }

          }

          
else
          
{
            …
          }

       }

       
else
       
{

       }

    }

IE裏沒有問題,六個object正好代表了Photo、Design、Text、Visage、Stature、Grace六個節點的類型是object型:

MF裏卻先後間隔出現了object text和object element兩種類型,這也就表示childNodes[0]、childNodes[2]和childNodes[4]這三個節點都是object text類型的節點,而childNodes[1]、childNodes[3]、childNodes[5]都是object element類型的節點,問題似乎一點點明晰起來:因爲Photo、Design、Text、Visage、Stature、Grace這六個節點肯定是同類型的節點,而通過alert得到的類型卻是兩種不同類型,這也就很清楚地表明object text類型或者object element類型中有一種就是《Mozilla Firefox與IE瀏覽器的javascript兼容性問題》裏提到的“空白文本節點”!(雖然心裏已經猜到object text就是空白文本節點的類型,但還是抱着謹慎的態度繼續驗證一下)
下面的測試變得異常簡單,我再次修改了getScore()函數,如下:
function getScore()
   
{
      …

      
if (http_request.readyState ==
 READY_STATE_COMPLETE)
      
{
         
if (http_request.status == 200
)
         
{

            
            
if
(getIshow)
            
{
              
for(var i=0;i<6;i++
)
              
{
                
//alert(getIshow[0].childNodes[0].firstChild.data);

                alert(getIshow[0].childNodes[1].firstChild.data);
              }

            }

          }

          
else
          
{
            …
          }

       }

       
else
       
{

       }

    }

在MF中,依次逐個alert出getIshow[0].childNodes[i].firstChild.data(i=0,1,2,3,4,5),結果當i=1,3,5時分別顯示8.2、7.8、6.7,恰好是Photo、Design、Text節點的數值;而當i=0,2,4時,MF無法顯示。這也就驗證了Photo、Design、Text節點是object element類型的,同時也說明了:在MF裏, <Photo></Photo>這樣的object element類型節點前都會插入一個空白文本節點,而這個空白文本節點的類型是object text類型的!所得假設模型如下:
<[object Text] />
<[object Element]>Data</[object Element]>
<[object Text] />
<[object Element]>Data</[object Element]>
<[object Text] />
<[object Element]>Data</[object Element]>
到目前爲止,關於IE和MF中捕捉childNodes差異的測試就結束了,如何在MF中也能正常獲取XML節點的數值呢,我想這對兄弟們應該就不是什麼問題了吧,反正我是這樣做的,還是getScore()函數,代碼如下:
 
function getScore()
   
{
      …

      
if (http_request.readyState ==
 READY_STATE_COMPLETE)
      
{
         
if (http_request.status == 200
)
         
{

            
            
if
(getIshow)
            
{
              
if(agentType=="IE"
)
//agentType=( window.navigator.userAgent.indexOf('MSIE')<1)?'MF':'IE'

              {
                
for(var i=0;i<6;i++
)
                
{
                  $(voteItem[i]).innerHTML
=getIshow[0
].childNodes[i].firstChild.data;
                }

              }

              
else //FF capability...
              {
                
for(var i=0;i<6;i++
)
                
{
                  j
=(i+1)*2-1
;
                  $(voteItem[i]).innerHTML
=getIshow[0
].childNodes[j].firstChild.data;
                }

              }

            }

          }

          
else
          
{
            …
          }

       }

       
else
       
{

       }

    }

好了,文章寫到這會也就差不多了,不知道大家是否和我一樣對DOM有了一點更深的理解呢?這僅僅是心晴的一點小心得,一點小體會而已,寫得不好還望大家多多指正,多多包涵!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章