Search code examples
javascripthtmlhtml-tablecreateelementpre

Javascript CreateElement creates empty tables


I'm trying to use a pre html tag to contain some code that I am going to format. I take the code from a pre-existing pre tag, and make a table containing the code, which is then formatted. But every other time I make a td element, with some text in it, an empty table is created instead. My code is as following:

function init() {
    var pres = document.getElementsByTagName('pre');

    for (var i = 0; i < pres.length; i++) {
        var elem = pres[i];
        var ourTable = document.createElement('table');

        if (elem.className.toLowerCase() == 'code') {
            var lineCount = 1;
            var linesOfText = elem.innerHTML.split(/\r|\n/);

            for (var j = 0; j < linesOfText.length; j++) { 
                var ourRow = document.createElement('tr');
                var lineNumberTd = document.createElement('td');
                var lineNumberNode = document.createTextNode(lineCount);
                lineNumberTd.appendChild(lineNumberNode);

                ourRow.appendChild(lineNumberTd);

                var code = linesOfText[j];

                var codeTd = document.createElement('td');
                var ourPre = document.createElement('pre');
                ourPre.innerHTML = code;
                codeTd.appendChild(ourPre);
                ourRow.appendChild(codeTd);

                lineCount++;
                ourTable.appendChild(ourRow);
            }
        }

        elem.parentNode.replaceChild(ourTable, elem);
    }
}
window.onload = init;

And my HTML is as following:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <link rel="stylesheet" href="DefaultStyle.css" />
    <title>Autoformatter</title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <pre class="code">
                        while (!stop)
            {
                while (packetQueue.Count > 0)
                {
                    HandlePacket(packetQueue.Dequeue());
                }
            }
        </pre>
        </div>
    </form>
    <script type="text/javascript" src="PrimaryScript.js" ></script>
</body>
</html>

and this generates something like this:

result of the code

There are empty tables like the one on line 2 in line 4, 6 and 8 aswell.


Solution

  • The problem is that you are using a NodeList:

    var pres = document.getElementsByTagName('pre');
    
    for (var i = 0; i < pres.length; i++) {
    

    NodeLists are "live" collections, that is they change. At the beginning you have one pre tag so pres.length returns 1. But within the loop you add pre tags. So pres.length changes as well. Hence your loop runs again and again.