2

I have a JavaScript assignment, and part of that assignment is having a two-column table with embedded JavaScript that loops through 50 temperatures in both Celsius and Fahrenheit.

I checked W3's HTML validator and it tells me so far I have 2 errors... The one I can never seem to get rid of is "Element script not allowed as child of element tbody in this context".

And this is my code:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<style type="text/css">
body { background-image:url('background.png'); text-align:center; font-family:verdana; color:white; }

ul
{
list-style-type:none;
margin:0;
padding:0;
padding-top:6px;
padding-bottom:6px;
}
li
{
display:inline;
}

a:link,a:visited
{
opacity:0.75;
filter:alpha(opacity=75);
font-weight:bold;
color:#FFFFFF;
background-color:#999999;
text-align:center;
padding:5px;
text-decoration:none;
text-transform:uppercase;
border: 1px solid white;
font-weight:bold;
}

a:hover,a:active
{
opacity:1;
filter:alpha(opacity=100);
background-color:#999999;
border: 1px solid white;
font-weight:bold;
}

h1 { font-size: 25px; }
h2 { font-size: 12px; }
h3 { font-size: 10px; position:fixed; bottom: 5px; left:0%; right:0%; font-weight:normal; }
h4 { font-size: 25px; text-transform:uppercase; }

navigationtext { font-weight:bold; text-transform:uppercase; }

</style>
<head>
<title>Untitled Document</title>
</head>
<body>
<table>
<tr><td>Celsius</td><td>Fahrenheit</td></tr>
<script type="text/javascript" src="temperatures.js"></script>
</table>
</body>
</html>

And here is the external JavaScript file:

var celsius = 0;
for (celsius = 0; celsius <= 50; celsius) {
    document.write("<tr><td>"+celsius+"</td><td>"+((celsius*9/5)+32)+"</td</tr>");
    celsius++;
}
Tim
  • 33,823
  • 10
  • 86
  • 115
Apocalypsing
  • 23
  • 1
  • 3
  • 1
    The solution for this would be to put the script after the table and use proper DOM manipulation methods, not `document.write`. This may help: http://dev.opera.com/articles/view/creating-and-modifying-html/. – Felix Kling Sep 05 '12 at 08:36
  • I'd use `innerHTML` for this. `tbody`'s innerHTML is read-only in IE though. I'd just not use tables too. – Fabrício Matté Sep 05 '12 at 08:43
  • Decided to use proper DOM manipulation in my answer, since this is tagged with `homework`, it's better to show best practices. – Fabrício Matté Sep 05 '12 at 09:52

3 Answers3

1

First off, get that script to the bottom of the body, right before the </body>. Putting it anywhere else will block page loading. Adapt your HTML for proper DOM manipulation by giving IDs to the elements you're going to manipulate:

<table>
    <thead>
        <tr><th>Celsius</th><th>Fahrenheit</th></tr>
    </thead>
    <tbody id="temperatureTableTbody"></tbody>
</table>
<script type="text/javascript" src="temperatures.js"></script>
</body>

Also make a closure to don't pollute the global scope with unnecessary variables. I modified your code slightly to use proper DOM manipulation, should work on any browser released in the last decade.

(function() { //creates a closure, so vars don't leak in the global scope
    //stores a reference to the tbody DOM element which we will append rows to
    var tbody = document.getElementById('temperatureTableTbody');
    //iterates celsius from 0 to 50
    for (var celsius = 0; celsius <= 50; celsius++) {
        //creates elements
        var tr = document.createElement('tr'),
            tdcelsius = document.createElement('td'),
            tdfahr = document.createElement('td');
        //append textNodes to the td elements
        tdcelsius.appendChild(document.createTextNode(celsius));
        tdfahr.appendChild(document.createTextNode((celsius*9/5)+32));
        //appends the tds to the tr
        tr.appendChild(tdcelsius);
        tr.appendChild(tdfahr);
        //append the finished row to the tbody
        tbody.appendChild(tr);
        //repeat loop while condition is true
    }
}());​ //closes the Immediately Invoked Function Expression

Fiddle

And please, don't use document.write.

Some reference: Why is document.write considered a 'bad practice'?

Community
  • 1
  • 1
Fabrício Matté
  • 65,581
  • 23
  • 120
  • 159
0

Try like this.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Document</title>
</head>
<body>
<table>
<tr>
    <td>Celsius</td>
    <td>Fahrenheit</td>
</tr>
<script type="text/javascript" > //<![CDATA[
    for (var celsius = 0; celsius <= 50; celsius++) {
        document.write("<tr><td>"+ celsius +"</td>");
        document.write("<td>"+ ((celsius*9/5)+32) +"</td></tr>");
}
//]]></script>
</table>
</body>
</html>
swemon
  • 5,474
  • 4
  • 29
  • 53
  • Thanks for the help guys. And yeah, I know I shouldn't be using document.write, but this is for introductory javaScript. – Apocalypsing Sep 12 '12 at 04:35
0

You should call a javascript function when document has been loaded:

if (document.readyState === "complete") { loadTemperatures(); }

Your loadTemperatures function will append rows to your table. Have a look here to learn how to do that: http://viralpatel.net/blogs/dynamically-add-remove-rows-in-html-table-using-javascript/

Element script not allowed as child of element tbody in this context

Put the <script> balise between <head> and </head> to correct that.

Here is a jsFiddle to show you the goal: http://jsfiddle.net/dfTz6/2/

GeoffreyB
  • 1,621
  • 2
  • 19
  • 34