views:

749

answers:

4

Using JavaScript, how can I dynamically change one of the list-items below from this:

<ul class="tabbernav">
<li class="tabberactive"><a title="All">All</a></li>
<li class=""><a title="One">One</a></li>
<li class=""><a title="Two">Two</a></li>
<li class=""><a title="Three">Three</a></li>
</ul>

to

<ul class="tabbernav">
<li class="tabberactive"><a title="All">All</a></li>
<li class=""><a title="One">One</a></li>
<li class=""><a title="Two">-----------NEW LIST ITEM CHANGED---------</a></li>
<li class=""><a title="Three">Three</a></li>
</ul>
A: 

Look into using a Javascript library such as JQuery. That will make your life a lot easier. Then you can do something like this:

$('li a[title=Two]').text('Changed Text Goes Here');

You'll need to check my syntax (not sure about the text() function), but it's easy enough to look up in JQuery's api docs.

Marc W
How would I do this without JQuery?
A: 

How do you identify which <li> is the one you want to modify?

If you're doing it by index you could do something like this I think:

var list = document.getElementById("listid");
list.childNodes[2].innerHtml = "<a title='Two'>-----------NEW LIST ITEM CHANGED---------</a>";
Kevin Tighe
I'm not sure about childNodes here, but I know that browsers don't guarantee an order of certain DOM arrays. For example, using IE8 in IE7 rendering mode (I believe) messes up some of the array ordering you might expect. Either way, the location of a node in a DOM array isn't guaranteed to be the same order as defined in the HTML.
Marc W
@Marc W - no kidding! Thanks for the tip :).
Kevin Tighe
iirc childNodes won't be x-browser safe because in !IE browsers textnodes are included
annakata
+4  A: 

I guess you could use getElementsByTagName inside of the ul to get all your list items inside an array. Then you can just edit the third element in your array, with index number 2.

var lItems = document.getElementsByTagName("ul").getElementsByTagName("li");
lItems[2].innerHTML = "<a title='Two'>----NEW LIST ITEM CHANGED-----</a>";

That will ofcourse get all ul elements on the page, and might lead to some strange results if you have more than two uls in your document. But you get the idea, right? Just ask some more if you don't understand what I'm trying to say.

Okay, the above code doesn't really work properly. I've modified my code a bit, but that also included a change in your HTML, as i presume you'll only have one ul "tabbernav", thus I changed it from class="tabbernav" to id="tabbernav". This is the code to do what you want.

var ul = document.getElementById("tabbernav");
var liArray = ul.getElementsByTagName("li");

for (var i = 0; i < liArray.length; i++) {
    if(liArray[i].childNodes[0].title == "Two") {
        liArray[i].innerHTML = "Your desired output";
    }
}

Hope that helps you some more :)

Jesper Karsrud
See my comment about DOM array ordering on Kevin's post. I'm not sure this is safe for cross-browser use.
Marc W
Yeah, I just saw it after posting. I guess you could loop through the array looking for child nodes where title="Two" to avoid that problem.
Jesper Karsrud
I think getelements is actually x-safe, but I'm not 100% on chrome. If it isn't it would be better to invoke xpath selection for !IE.
annakata
@Jesper - easier to start at firstChild and loop nextSibling N times
annakata
So is the code about correct or not?
The code in this answer is fine, but it's probably not cross-browser compatible. See Jesper's comment after mine, though, about looping through the array looking for child nodes with title="Two". That's more like what you should do.
Marc W
@Marc W - what would that code looping through look like?
@TeddyK12: I just edited my answer, see if that helps you along some more :)
Jesper Karsrud
+2  A: 

I also suggest using jQuery, which makes selections like this trivial. In your case, you can use the :eq psuedo-selector to get the second line element:

$('.tabbernav li:eq(1)')

This selects the DOM element which is the second li (indexes start at 0) in an element with the class tabbernav. It returns a jQuery object which you can chain other methods to. Changing the inner HTML is done with .html('Your html here').

Ryan