user2198320
user2198320

Reputation: 71

Can't get getElementsByTagName to work correctly

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

Answers (4)

Rohan Kumar
Rohan Kumar

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

Felix Kling
Felix Kling

Reputation: 816364

There are two kinds of DOM methods:

  1. Methods which return a reference to a single node. For example getElementById and querySelector.

  2. 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 NodeLists 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:

  1. Use querySelectorAll to select all rows:

    var rows = document.querySelectorAll('table.' + myTable + '  tr');
    
  2. 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

dtech
dtech

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

Anhayt Ananun
Anhayt Ananun

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

Related Questions