JavaScript - 使用childNodes遍历HTML DOM会导致非IE浏览器中的错误 [英] JavaScript - Traversing the HTML DOM using childNodes causes errors in Non IE browsers

查看:101
本文介绍了JavaScript - 使用childNodes遍历HTML DOM会导致非IE浏览器中的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的浏览器中正在呈现下表。它是从服务器端生成的。

 < table id =tblQuestionsclass =tblQuestionsContainerborder =0> ; 
< tr>
< td id =1class =tdQuestion>你是印度公民吗?< / td>
< / tr>< tr>
< td>< table id =answer-1border =0>
< tr>
< td>< input id =answer-1_0type =radioname =answer-1value =1/>< label for =answer-1_0>是< / label>< / td>< td>< /输入id =answer-1_1type =radioname =answer-1value =0/>< label for =回答-1_1\" >否LT; /标签>< / TD>
< / tr>
< / table>< / td>
< / tr>< tr>
< td id =2class =tdQuestion>你有护照吗?< / td>
< / tr>< tr>
< td>< table id =answer-2border =0>
< tr>
< td>< input id =answer-2_0type =radioname =answer-2value =1/>< label for =answer-2_0>是< / label>< / td>< td>< input id =answer-2_1type =radioname =answer-2value =0/>< label for =回答-2_1\" >否LT; /标签>< / TD>
< / tr>
< / table>< / td>
< / tr>
< / table>

现在我在JavaScript中使用以下代码验证单选按钮的检查状态。 >

  var tblQuestionBoard = document.getElementById(tblQuestions); 
tblAnswer = tblQuestionBoard.rows [1] .childNodes [0] .childNodes [0]

现在tblAnswer应该是一个对象,具有id为answer-1的表



在IE中,我得到它。但是在Mozilla和其他浏览器中,我将其定义为未定义。



如何解决?

解决方案

这是因为您正在使用 childNodes ,并且DOM等人的空格被认为是Firefox等文本节点。但不是IE



请参阅这个答案解释



我的建议



1.Set一些封装功能,忽略任何 nodeType 除了1( ELEMENT_NODE )做DOM遍历。像

  function child(elem,index){
//如果没有提供索引,默认值为1
//你可能会更喜欢这个基于0的
//,在这种情况下,我将初始赋值值更改为0
index = index || 1;
//获取elem
elem的第一个子元素节点(elem.firstChild&& elem.firstChild.nodeType!= 1)?
next(elem.firstChild):
elem.firstChild;
//使用索引移动到第n个子元素节点
for(var i = 1; i< index; i ++){
(function(){
return elem = next(elem);
})();
}
return elem;
}

function next(elem){
do {
elem = elem.nextSibling;
} while(elem&& elem.nodeType!= 1);
return elem;
}

并使用如此 - 工作演示 - (答案底部的代码供参考)

 < table id =myTable> 
< thead>
...
< / thead>
< tbody>
...
< / tbody>
< / table>

< script type =text / javascript>
子(document.getElementById('myTable'),2); //将获取tbody
< / script>

2.使用 getElementbyId() getElementsByTagName() getElementsByName()而不是依赖于DOM中的位置



3.使用一个JavaScript库来提取浏览器的差异(强烈推荐 jQuery ) p>

演示代码

 <! DOCTYPE html PUBLIC -  // W3C // DTD XHTML 1.0 Transitional // EN
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
< html xmlns =http://www.w3.org/1999/xhtmlxml:lang =enlang =en>
< head>
< script type =text / javascript>
window.onload = function(){
document.getElementById('getCellContents')。onclick = getCellContents;
}

函数子(elem,index){
index = index || 1;
elem =(elem.firstChild&& elem.firstChild.nodeType!= 1)?
next(elem.firstChild):
elem.firstChild; $($ i $)$ {
(function(){
return elem = next(elem);
})();
for(var i = 1; i< index; i ++)
}
return elem;
}

function next(elem){
do {
elem = elem.nextSibling;
} while(elem&& elem.nodeType!= 1);
return elem;
}

函数getCellContents(){
var row = parseInt(document.getElementById('row')。value,10);
var column = parseInt(document.getElementById('column')。value,10);
var result;
var color;
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for(var i = 0; i< cells.length; i ++){
(function(){
cells [i] .bgColor ='#ffffff';
})();
}

if(row&& column){
var tbody = child(table,2);
var selectedRow =(row< = tbody.getElementsByTagName(tr)。length)? child(tbody,row):null;
var selectedCell =(selectedRow&& column< = selectedRow.getElementsByTagName(td)。length)? child(selectedRow,column):null;

if(selectedRow&& selectedCell){
selectedCell.bgColor ='#00ff00';
result = selectedCell.innerHTML;
color ='#b7b7b7';
}
else {
result ='单元格不存在';
color ='#ff0000';
}
}
else {
result ='您必须为Row和Column Number提供数字参数;
color ='#ff0000';
}
var results = document.getElementById('results');
results.innerHTML = result;
results.style.color = color;
}


< / script>
< title> DOM遍历< / title>
< meta http-equiv =Content-typecontent =text / html; charset = utf-8/>
< style type =text / css>
body {
font-family:Verdana,Helvetica,Arial;
font-size:0.8em;
}
h2 {
text-align:center;
}
表{
border:1px solid#000;
border-collapse:collapse;
}
th,td {
border:1px solid#000;
padding:2px;
}
fieldset {
border:0;
}
label {
display:block;
width:120px;
text-align:right;
float:left;
padding-right:10px;
margin:5px 0;
}
input {
margin:5px 0;
}

input.text {
padding:0 0 0 3px;
width:172px;
}

input.button {
margin:15px 0 0 130px;
}
span {
font-weight:bold;
颜色:#b7b7b7;
}
< / style>
< / head>
< body>

< h2>示例演示使用JavaScript DOM遍历包装函数< / h2>
< div style =margin:0 auto; width:600px;>
< fieldset>
< label for =row>行号:< / label>< input id =rowclass =texttype =text/>< br />
< label for =column>列号:< / label>< input id =columnclass =texttype =text/>< br />
< input id =getCellContentstype =buttonclass =buttonvalue =获取单元格内容/>
< / fieldset>

< p>结果:< span id =results>< / span>< / p>

< table id =table>
< thead>
< tr>
< th>列1< / th>
< th>列2< / th>
< th>列3< / th>
< th>列4 /
< th>列5<
< / tr>
< / thead>
< tbody>
< tr>
< td>香蕉< / td>
< td> Apple< / td>
< td>橙色< / td>
< td>菠萝< / td>
< td>蔓越莓< / td>
< / tr>
< tr>
< td> Monkey< / td>
< td>长颈鹿< / td>
< td> Elephant< / td>
< td> Tiger< / td>
< td> Snake< / td>
< / tr>
< tr>
< td> C#< / td>
< td> Java< / td>
< td> Python< / td>
< td> Ruby< / td>
< td> Haskell< / td>
< / tr>
< tr>
< td>法国< / td>
< td>西班牙< / td>
< td>意大利< / td>
< td>德国< / td>
< td>荷兰< / td>
< / tr>
< / tbody>
< / table>
< p style =font-weight:bold;>代码:
< pre>< code>
& lt; script type =text / javascript& gt
window.onload = function(){
document.getElementById('getCellContents')。onclick = getCellContents;
}

函数子(elem,index){
index = index || 1;
elem =(elem.firstChild&& elem.firstChild.nodeType!= 1)?
next(elem.firstChild):
elem.firstChild;
for(var i = 1; i< index; i ++){
(function(){
if(elem)
return elem = next(elem);
})();
}
return elem;
}

function next(elem){
do {
elem = elem.nextSibling;
} while(elem&& elem.nodeType!= 1);
return elem;
}

函数getCellContents(){
var row = parseInt(document.getElementById('row')。value,10);
var column = parseInt(document.getElementById('column')。value,10);
var result;
var color;
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for(var i = 0; i< cells.length; i ++){
(function(){
cells [i] .bgColor ='#ffffff';
})();
}

if(row&& column){
var tbody = child(table,2);
var selectedRow =(row< = tbody.getElementsByTagName(tr)。length)?
子(tbody,row):null;
var selectedCell =(selectedRow&& column< = selectedRow.getElementsByTagName(td)。length)?
child(selectedRow,column):null;

if(selectedRow&& selectedCell){
selectedCell.bgColor ='#00ff00';
result = selectedCell.innerHTML;
color ='#b7b7b7';
}
else {
result ='单元格不存在';
color ='#ff0000';
}
}
else {
result ='您必须为Row和Column Number提供数字参数;
color ='#ff0000';
}
var results = document.getElementById('results');
results.innerHTML = result;
results.style.color = color;
}
& lt / / script& gt
< / code>
< / pre>
< / p>
< / div>
< / body>
< / html>


I have the following table being rendered in my browser. It's generated from the server side.

<table id="tblQuestions" class="tblQuestionsContainer" border="0">
    <tr>
        <td id="1" class="tdQuestion">Are u an indian citizen ?</td>
    </tr><tr>
        <td><table id="answer-1" border="0">
            <tr>
                <td><input id="answer-1_0" type="radio" name="answer-1" value="1" /><label for="answer-1_0">Yes</label></td><td><input id="answer-1_1" type="radio" name="answer-1" value="0" /><label for="answer-1_1">No</label></td>
            </tr>
        </table></td>
    </tr><tr>
        <td id="2" class="tdQuestion">Do you have a passport ?</td>
    </tr><tr>
        <td><table id="answer-2" border="0">
            <tr>
                <td><input id="answer-2_0" type="radio" name="answer-2" value="1" /><label for="answer-2_0">Yes</label></td><td><input id="answer-2_1" type="radio" name="answer-2" value="0" /><label for="answer-2_1">No</label></td>
            </tr>
        </table></td>
    </tr>
</table>

Now I am using the following code in my JavaScript to validate the radio button's checked state.

 var tblQuestionBoard=document.getElementById("tblQuestions");
  tblAnswer = tblQuestionBoard.rows[1].childNodes[0].childNodes[0]

Now tblAnswer should be an object having the Table with id "answer-1"

In IE, I am getting it. But in Mozilla and rest of the browsers I am getting it as undefined.

How to solve this?

解决方案

It's because you're using childNodes and whitespaces in the DOM are considered to be text nodes by Firefox et. al but not IE

See this answer for an explanation

My suggestions

1.Set up some wrapper functions that ignore any nodeType other than 1 (ELEMENT_NODE) to do DOM traversing. Something like

function child(elem, index) {
    // if index is not supplied, default is 1 
    // you might be more comfortable making this 0-based
    // in which case change i initial assignment value to 0 too
    index = index || 1; 
    // get first child element node of elem
    elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
               next(elem.firstChild) :
               elem.firstChild; 
    // use the index to move to nth-child element node             
    for(var i=1; i < index;i++) {
        (function() {     
            return elem = next(elem);         
        })();        
    }
    return elem;
}

function next(elem) {
    do {
        elem = elem.nextSibling;
    } while (elem && elem.nodeType != 1);
return elem;                
}

and use like so - Working Demo - (Code at the bottom of the answer for reference)

<table id="myTable">
    <thead>
        ...
    </thead>
    <tbody>
        ...
    </tbody>
</table>

<script type="text/javascript">
    child(document.getElementById('myTable'), 2); // will get the tbody
</script>

2.Use getElementbyId(), getElementsByTagName() or getElementsByName() instead of relying on position in the DOM

3.Use a JavaScript library that abstracts away browser differences (jQuery comes highly recommended)

The Demo Code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
    window.onload = function() {    
       document.getElementById('getCellContents').onclick = getCellContents;    
    }

    function child(elem, index) {
        index = index || 1; 
        elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
                   next(elem.firstChild) :
                   elem.firstChild;            
        for(var i=1; i < index;i++) {
            (function() {    
                return elem = next(elem);         
            })();        
        }
        return elem;
    }

    function next(elem) {
        do {
            elem = elem.nextSibling;
        } while (elem && elem.nodeType != 1);
    return elem;                
    }

    function getCellContents() {
        var row = parseInt(document.getElementById('row').value, 10);
        var column = parseInt(document.getElementById('column').value, 10);
        var result;
        var color;
        var table = document.getElementById('table');
        var cells = table.getElementsByTagName('td');
        for (var i= 0; i < cells.length; i++) {
            (function() {
                cells[i].bgColor = '#ffffff';
            })();
        }

        if (row && column) {
            var tbody = child(table , 2);
            var selectedRow = (row <= tbody.getElementsByTagName("tr").length)? child(tbody, row): null;
            var selectedCell = (selectedRow && column <= selectedRow.getElementsByTagName("td").length)? child(selectedRow, column): null;  

            if (selectedRow && selectedCell) {
                selectedCell.bgColor = '#00ff00';
                result = selectedCell.innerHTML;
                color = '#b7b7b7';
            }
            else {
                result = 'Cell does not exist';
                color = '#ff0000';
            }                                           
        }
        else {
            result = 'You must provide numeric arguments for Row and Column Number';
            color = '#ff0000';
        }       
        var results = document.getElementById('results');
        results.innerHTML = result;
        results.style.color = color;
    }


</script>
<title>DOM Traversal</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
    font-family: Verdana, Helvetica, Arial;
    font-size: 0.8em;
}
h2 {
    text-align:center;
}
table { 
    border: 1px solid #000;
    border-collapse: collapse;
}   
th, td { 
    border: 1px solid #000; 
    padding: 2px; 
}
fieldset {
    border: 0;
}
label {
    display: block;
    width: 120px;
    text-align: right;
    float: left;
    padding-right: 10px;
    margin: 5px 0;
}
input {
    margin: 5px 0;
}

input.text {
    padding: 0 0 0 3px;
    width: 172px;
}

input.button {
    margin: 15px 0 0 130px;
}
span {
    font-weight: bold;
    color: #b7b7b7;
}
</style>
</head>
<body>

<h2>Example to demonstrate use of JavaScript DOM traversing wrapper functions</h2>
<div style="margin: 0 auto; width: 600px;">
<fieldset>
    <label for="row">Row Number:</label><input id="row" class="text" type="text" /><br/>
    <label for="column">Column Number:</label><input id="column" class="text" type="text" /><br/>
    <input id="getCellContents" type="button" class="button" value="Get Cell Contents" />
</fieldset> 

<p>Results: <span id="results"></span></p>

  <table id="table">
  <thead>
    <tr>
            <th>Column 1</th>
            <th>Column 2</th>   
        <th>Column 3</th>
        <th>Column 4</th>
        <th>Column 5</th>   
    </tr>   
  </thead>
  <tbody>
      <tr>
        <td>Banana</td>
        <td>Apple</td>
        <td>Orange</td>
        <td>Pineapple</td>
        <td>Cranberry</td>
      </tr>
      <tr>
        <td>Monkey</td>
        <td>Giraffe</td>
        <td>Elephant</td>
        <td>Tiger</td>
        <td>Snake</td>
      </tr>
      <tr>
        <td>C#</td>
        <td>Java</td>
        <td>Python</td>
        <td>Ruby</td>
        <td>Haskell</td>
      </tr>
      <tr>
        <td>France</td>
        <td>Spain</td>
        <td>Italy</td>
        <td>Germany</td>
        <td>Netherlands</td>
      </tr>
  </tbody>
  </table>
<p style="font-weight:bold;">The Code:
<pre><code>
&lt;script type="text/javascript"&gt;
window.onload = function() {    
   document.getElementById('getCellContents').onclick = getCellContents;    
}

function child(elem, index) {
    index = index || 1; 
    elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
               next(elem.firstChild) :
               elem.firstChild;                
    for(var i=1; i < index;i++) {
        (function() {   
            if(elem)  
            return elem = next(elem);         
        })();        
    }
    return elem;
}

function next(elem) {
    do {
        elem = elem.nextSibling;
    } while (elem && elem.nodeType != 1);
return elem;                
}

function getCellContents() {
    var row = parseInt(document.getElementById('row').value, 10);
    var column = parseInt(document.getElementById('column').value, 10);
    var result;
    var color;
    var table = document.getElementById('table');
    var cells = table.getElementsByTagName('td');
    for (var i= 0; i < cells.length; i++) {
        (function() {
            cells[i].bgColor = '#ffffff';
        })();
    }

    if (row && column) {
        var tbody = child(table , 2);
        var selectedRow = (row <= tbody.getElementsByTagName("tr").length)? 
                            child(tbody, row): null;
        var selectedCell = (selectedRow && column <= selectedRow.getElementsByTagName("td").length)? 
                                child(selectedRow, column): null;   

        if (selectedRow && selectedCell) {
            selectedCell.bgColor = '#00ff00';
            result = selectedCell.innerHTML;
            color = '#b7b7b7';
        }
        else {
            result = 'Cell does not exist';
            color = '#ff0000';
        }                                           
    }
    else {
        result = 'You must provide numeric arguments for Row and Column Number';
        color = '#ff0000';
    }       
    var results = document.getElementById('results');
    results.innerHTML = result;
    results.style.color = color;
}
&lt;/script&gt;
</code>
</pre>
</p>
  </div>
</body>
</html>

这篇关于JavaScript - 使用childNodes遍历HTML DOM会导致非IE浏览器中的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆