Question

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.

Was it helpful?

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.

OTHER TIPS

Okay, so I figured out the answer to the problem myself.

Apparently, in some way, the line

elem.parentNode.replaceChild(ourTable, elem);

got run more times than it should, and therefore it replaced the newly made pre-element with an empty table, since the newly made pre-element did not have the class='code' property set.

Putting that single line INTO the

if (elem.className.toLowerCase() == 'code') {

and not outside it, fixed my problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top