views:

49

answers:

3

I have the following HTML page (page is simplified here as it is a sample of the real one):

<html>
<head>
<script type="text/javascript" src="JavaScript/Painting.js"></script>
</head>
<body>
<div id="center-wrapper">
    <div id="side-menu">
        <ul>
            <li><a onclick="Paint()">About</a></li>
            <li><a onclick="Paint()">Contents</a></li>
            <li><a onclick="Paint()">Visual</a></li>
            <li><a onclick="Paint()">CSS</a></li>
            <li><a onclick="Paint()">Javascript</a></li>
        </ul>
    </div>
</div>
</body>
</html>

And I have the Painting.js file (again, a bit simplified):

function Paint()
{

    var e = window.event;

    var sender;
    if (e.target)
    {
        sender = e.target;
    }   
    else
    {
        if (e.srcElement)
        {
            sender = e.srcElement;
        }
    }

    for (element in sender.parentNode.parentNode.getElementsByTagName("a"))
    {
        element.style.color = 'blue';
        element.style.backgroundColor = '#FFFFFF';
    }

    sender.style.color = '#FFFFFF';
    sender.style.backgroundColor = '#000000';

}

The basic idea is:

  1. Find a HTML element that caused the event.
  2. Go up until you reach the <ul> element.
  3. Loop through the list items; find the <a> tags and change their color and background
  4. Upon exiting the loop, change the color and the background of the HTML element that caused the event.

Now, I can't seem to get to the part located in the for loop. I think I am making a mistake by calling GetElementsByTagName() method. Could you help me out? Thanks.

+1  A: 

You should call getElementsByTagName() only once, caching the result.

Then iterate over the collection like this (instead of using for/in).

var a_elements = sender.parentNode.parentNode.getElementsByTagName("a");

for (var i = 0, len = a_elements.length; i < len; i++ ) {
    a_elements[ i ].style.color = 'blue';
    a_elements[ i ].style.backgroundColor = '#FFFFFF';
}
sender.style.color = '#FFFFFF';
sender.style.backgroundColor = '#000000';

To get the target, you can pass it as the parameter in the inline onclick:

   <ul>
        <li><a onclick="Paint(this)">About</a></li>
        <li><a onclick="Paint(this)">Contents</a></li>
        <li><a onclick="Paint(this)">Visual</a></li>
        <li><a onclick="Paint(this)">CSS</a></li>
        <li><a onclick="Paint(this)">Javascript</a></li>
    </ul>

Then your javascript can look like this:

function Paint( sender ) {

    var a_elements = sender.parentNode.parentNode.getElementsByTagName("a");

    for (var i = 0, len = a_elements.length; i < len; i++ ) {
        a_elements[ i ].style.color = 'blue';
        a_elements[ i ].style.backgroundColor = '#FFFFFF';
    }
    sender.style.color = '#FFFFFF';
    sender.style.backgroundColor = '#000000';
}

Example: http://jsbin.com/aroda3/

patrick dw
Thank you for your answer. However, it still doesn't work. The script brakes after the: `var a_elements = sender.parentNode.parentNode.getElementsByTagName("a");`
Boris
@Boris - I made a mistake. I'll update in a second. EDIT: Updated. The target is now being passed as an argument in the inline `onclick`, and is accessed in the function as the `sender` parameter. Here's a live example: http://jsbin.com/aroda3/
patrick dw
@Patrick Thank you. I got it to work somehow, though I could swear on my life that my code was identical to yours. Maybe the browser (Chrome) was showing me some cached stuff? To hell with it, it works and you're the man.
Boris
@Boris - You're welcome. :o)
patrick dw
A: 

Basically: 1. In order to find the element which caused the event you have to add an identifier to the a or li element and then use it as a parameter to your function. For example:

<li id='id_li1'><a onclick="Paint(id_li1)">About</a></li>
  1. You can also use the ul id as parameter for your function, so you can know which is the ul that you need. I supposed that you generate your ul dinamically: <a onclick="Paint(id_li1, id_ul)">About</a>
  2. Then you have the reference for the ul and you can implement a function to iterate on the list items and give to the function the ul node using the id_ul. For example:

    function processUL(ul) {

    if (!ul.childNodes || ul.childNodes.length == 0) return;
    
    
    // Iterate LIs
    
    
    for (var itemi=0;itemi<ul.childNodes.length;itemi++) {
    
    
    
    var item = ul.childNodes[itemi];
    
    
    if (item.nodeName == "LI") {
    
    
        // Iterate things in this LI in the case that you need it put your code here to get the a element and change the color and background
          .....
    }
    
    }

}

Nervo Verdezoto
Thank you for your answer.
Boris
A: 

I know you can't use jQuery for this, but I thought I'd supply a solution for others that may be able to:

$(function(){
    $("li a").click(function(){
        $(this).parent().siblings().each(function(){
            $(this).find("a").css({'color':'blue','background-color':'white'});    
        });
        $(this).css({'color':'white','background-color':'black'});    
        return false;
    });
});
Hollister
OK, I hope it solves the problem for some! Thanks for the reply.
Boris