I have a simple table, and this table contains thead, tbody and tfoot sections. In JavaScript, I want to be able to access each of these parts to set some attributes.
I try to get the the parts with table.tHead
, table.tBody
and table.tFoot
respectively.
This works for tHead and tFoot just fine, but tBody always returns undefined.
Looking inside the table object with the browser debugger, I can see that table.childNoes and table.children shows all the table parts, including tbody.
Strangely, if I access the tbody section using its ID with document.getElementById("TB") it works just fine.
Can anyone explain this to me? Here’s the source HTML with JavaScript:
let table1 = document.getElementById("TBL1");
if (typeof(table1) != "undefined") {
console.log(" - table element 'TBL1' acquired");
let thead = table1.tHead;
if (typeof(thead) != "undefined") {
console.log(" - table element table1.tHead acquired,");
thead.style.color = "#ffff50";
console.log(" thead color changed to " + thead.style.color);
} else
console.log(" OOPS - could not access table table1.tHead");
let tbody = table1.tBody;
if (typeof(tbody) != "undefined") {
console.log(" - table element table1.tBody acquired,");
tbody.style.color = "#504020";
console.log(" tbody color changed to " + tbody.style.color);
} else
console.log(" OOPS - could not access table table1.tBody");
let tfoot = table1.tFoot;
if (typeof(tfoot) != "undefined") {
console.log(" - table element table1.tFoot acquired,");
tfoot.style.color = "#ffff50";
console.log(" tfoot color changed to " + tfoot.style.color);
} else
console.log(" OOPS - could not access table table1.tFoot");
} else
console.log("OOP - Couldn't acquire TBL1 table");
if (typeof(tbody) == "undefined") {
tbody = document.getElementById("TB");
if (typeof(tbody) != "undefined")
console.log(" - table element table1.tBody acquired using getElementById('TB'),");
tbody.style.color = "#504020";
console.log(" tbody color changed to " + tbody.style.color);
}
console.log(" - Done with table element access test");
thead,
tfoot {
background-color: #3f87a6;
color: #ffff;
}
tbody {
background-color: #64d0c0;
color: #ffff;
}
caption {
padding: 10px;
caption-side: bottom;
}
table {
border-collapse: collapse;
border: 2px solid rgb(120, 120, 120);
letter-spacing: 1px;
font-family: sans-serif;
font-size: 0.8rem;
}
td,
th {
border: 1px solid rgb(120, 120, 120);
padding: 5px 10px;
}
td {
text-align: center;
}
<body>
<script>
document.body.style.backgroundColor = "#A0C0C0";
console.log("Testing table element access -");
</script>
<div ID="DIV1">
<table ID="TBL1" style="margin-left: 100px; margin-top: 100px;">
<caption>
Council budget (in £) 2018
</caption>
<thead ID="TH">
<tr ID="HROW">
<td>Items</td>
<td scope="col">Expenditure</td>
</tr>
</thead>
<tbody ID="TB">
<tr ID="BROW1">
<td scope="row">Donuts</td>
<td>3,000</td>
</tr>
<tr ID="BROW2">
<td scope="row">Stationery</td>
<td>18,000</td>
</tr>
</tbody>
<tfoot ID="TF">
<tr ID="FROW">
<td scope="row">Totals</td>
<td>21,000</td>
</tr>
</tfoot>
</table>
</body>
3
Answers
There is no
tBody
property on a HTMLTableElement. There can be multipletbody
elements within a single table, so there’s atBodies
collection which returns a NodeList of them all.In your example, as you know there is only a single
tbody
instance, you can access the 0th element by index:If there will ever be multiple
tbody
elements within your table, then you could implement a loop to iterate through them all.Also, as an aside, note that it’s generally good practice to keep attributes in your HTML in lowercase, and to avoid using inline
style
attributes. Use external stylesheets for all styling.A table can have more than one body, and hence there is no single
tBody
property on anHTMLTableElement
but instead atBodies
array1.Therefore, you can access your table body using
table1.tBodies[0]
(returning the first and only body your table has).It’s always good to verify in the docs first whether some property you are trying to use even exists, and if it doesn’t, what other properties there are which may do what you want!
1: Technically, it’s a
NodeList
and not an array.For completeness sake, here is the same using querySelector