【问题标题】:JavaScript - Traversing the HTML DOM using childNodes causes errors in Non IE browsersJavaScript - 使用 childNodes 遍历 HTML DOM 会导致非 IE 浏览器中的错误
【发布时间】:2009-05-28 11:49:49
【问题描述】:

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

<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>

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

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

现在 tblAnswer 应该是一个对象,其表的 ID 为“answer-1”

在 IE 中,我明白了。但在 Mozilla 和其他浏览器中,我将其视为未定义。

如何解决?

【问题讨论】:

    标签: javascript html dom


    【解决方案1】:

    这是因为您使用的是childNodes,并且 DOM 中的空格被 Firefox 等视为文本节点。 al 但不是 IE

    请参阅this answer 了解说明

    我的建议

    1.设置一些忽略除 1 (ELEMENT_NODE) 之外的任何 nodeType 的包装函数来进行 DOM 遍历。类似的东西

    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;                
    }
    

    并像这样使用 - Working Demo - (答案底部的代码供参考)

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

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

    3.使用抽象出浏览器差异的 JavaScript 库(强烈推荐jQuery

    演示代码

    <!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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-28
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 2011-02-06
      相关资源
      最近更新 更多