Reputation: 71
I'm trying to make a JavaScript that alternates the color of each row in multiple tables. The catch is that some tables aren't going to be altered at all. So, I'm trying to use this code to get the rows of the table:
function alternateRows(myTable)
var rows = document.getElementsByTagName("table").getElementsByClassName(myTable).getElementsByTagName("tr");
And, in the HTML:
<body onload="alternateRows('myTable')";>
<table class="myTable">
I can get it to work just fine if I use the id attribute and change the JavaScript to:
var rows = document.getElementById(myTable).getElementsByTagName("tr");
Any suggestions would be great. Thanks!
Upvotes: 2
Views: 8507
Reputation: 40639
Try this:
You can use only by getElementsByTagName
or by getElementsByClassName
Like:
var rows = document.getElementsByTagName("table")[0].getElementsByTagName("tr");
or
var rows = document.getElementsByClassName('myTable')[0].getElementsByTagName("tr");
or use querySelectorAll
Syntax:
var matches = document.querySelectorAll("div.note, div.alert");
In your example:
var rows = document.querySelectorAll("table."+myTable).getElementsByTagName("tr");
getElementsByTagName
gives array so you should use it with zero index
Same for getElementsByClassName
Read https://developer.mozilla.org/en-US/docs/DOM/element.getElementsByTagName And https://developer.mozilla.org/en-US/docs/DOM/document.getElementsByClassName
Upvotes: 0
Reputation: 816364
There are two kinds of DOM methods:
Methods which return a reference to a single node. For example getElementById
and querySelector
.
Methods which return a list of nodes. For example, getElementsByTagName
, getElementsByClassName
, querySelectorAll
.
Those methods which return a list of nodes usually return a NodeList
[MDN] object, which has a very limited interface. All you can do with it is access the single elements in the list, just like an array, it does not have the same interface as a DOM node (or element).
If you want to call further DOM methods or DOM properties on the elements in the list, you can either access a specific node directly with its index, or iterate over the list and do so for each element:
var elements = document.getElementsByTagName('div');
for(var i = 0, l = elements.length; i < l; i++) {
// do something with elements[i]
}
Note that NodeList
s are usually live, which means any changes to the DOM (e.g. removing a div
element) will update the list automatically.
In your particular situation, you have to options:
Use querySelectorAll
to select all rows:
var rows = document.querySelectorAll('table.' + myTable + ' tr');
or iterate over the selected elements:
var rows = [];
var tables = document.getElementsByTagName("table");
for (var i = 0, l = tables.length; i < l; i++) {
// check whether it is a table with class in the variable `myTable`
if ((' ' + tables[i].className + ' ').indexOf(' ' + myTable + ' ') > -1) {
rows = rows.concat(tables[i].getElementsByTagName('tr'));
}
}
Instead of selecting the elements by tag name and then test their class, you could directly use getElementsByClassName
instead, but it is not as widely supported as querySelectorAll
.
Upvotes: 2
Reputation: 14060
getElementsByTagName
returns a NodeList, thats why it called getElements not getElement. a NodeList does not have the "getElementsByClassName" method defined, that's the error you should see.
You'll need to use loops. Also know that you can use CSS selectors for this, all modern browsers support this except IE 8 and lower.
CSS for modern browsers (or IE8- with e.g. a helper library, like ie9.js)
table.mytable tr:nth-child(odd) {
background-color: black;
}
table.mytable tr:nth-child(even) {
background-color: white;
}
Upvotes: 2
Reputation: 896
If all of your tables must be modified in same way, you can use following code:
var tables = document.getElementByTagName("table");
for (var i in tables)
{
var rows = tables[i].getElementByTagName("tr");
//Alternating code here
}
Upvotes: 0