Search code examples
javascripthtmldom-traversal

DOM traversal of table: Can't find anchors on rows


I have an html table like this:

<!doctype html>
</head>
<body>

<table id="tableA">
    <a name="local1"><tr>
                <td>Cell 1</td>
                <td>Cell 2</td>
    </tr></a>
    <a name="local2"><tr>
                <td>Cell 3</td>
                <td>Cell 4</td>
    </tr></a>
</table>   

</body>
</html>

Anchors wrap the table rows because there is no telling which cell contains more lines of text content, and one of them has that content centered horizontally. So using the anchors must take the page to the top of the row, not the top of the content in one particular cell, or else some work has to be done in js to determine how much to adjust the scroll by after the jump.

This works, but now I need to dynamically index those anchors using javascript, and I notice even traversing the entire table like this:

window.onload = function() {
    traverse(document.getElementById('tableA'));
}

function traverse (node) {
    var kids = node.children;
    if (!kids) return;
    var len = kids.length;
    for (var i = 0; i < len; i++) {
        traverse(kids[i]);
        alert(node.tagName+" "+kids[i].tagName);
    }
}

I never find the anchor, yet doing the same thing with a simple paragraph:

<p><a name="local3">blah blah</a>

The anchor is the first child of the paragraph. What can I do?


Solution

  • As Claies indicates in the first comment, the problem here is this isn't valid HTML to start with. The W3C Recommendation describing HTML 5 give the following content model ("a normative description of what content must be included as children and descendants of the element") for tables:

    In this order: optionally a caption element, followed by zero or more colgroup elements, followed optionally by a thead element, followed optionally by a tfoot element, followed by either zero or more tbody elements or one or more tr elements, followed optionally by a tfoot element (but there can only be one tfoot element child in total), optionally intermixed with one or more script-supporting elements.

    There's no where prior to the <tr> element to legally open the <a>.

    Fortunately, it isn't necessary to use actual anchor tags to make a local link work:

    <table id="tableA">
        <tr id="local1">
             <td>Cell 1</td>
             <td>Cell 2</td>
        </tr>
    

    #local1 works as it did before, and the index can be generated from the <tr> element.