views:

59

answers:

3

Hello - Beginners Javascript question here.

I am trying to create a function that finds all the links in a given div and sets up an onclick event for each one. I can get the link hrefs correctly, but when I try using them in the onclick function, Javascript seems to only use the last value found:

I.E I have these links

#purpose

#future

#faq

When I use the onclick function, every link is reported as the #faq link.

Here's the code:

function prepareLinks () {
var nav = document.getElementById('navigation');
var links = nav.getElementsByTagName ('a');
for (var i = 0; i<links.length; i++) {  
    var linkRef = links[i].getAttribute('href').split("#")[1];
    links[i].onclick = function () {
        var popUp = "You clicked the " +linkRef +" link";
        alert (popUp);
    }
}

}

+6  A: 

Here you have a closure creation. External variable linkRef becomes saved in inner onclick function. Try this way:

clickFunction() {
    var popUp = "You clicked the " + this.href.split("#")[1] +" link";
    // this should mean current clicked element
    alert (popUp);
}

for (var i = 0; i<links.length; i++) {  
    links[i].onclick = clickFunction;
}
Is that inside the main function?
YsoL8
for-loop would be in the main function and clickFunction... couldn't say for sure. Try both in and out.If you'll use "in", this could be reffered to main function.
+1  A: 

This is a scoping problem. The expression "You clicked the " +linkRef +" link" is evaluated when the onclick event fires, but what is the value of linkRef at this point?

Mick Sharpe
A: 

You're trying to attach a separate onClick handler to each link, but you're accidentally attaching the same one.

You could generate a new function each time by using the new Function() constructor as

links[i].onclick = new Function("","alert('You clicked the '"+linkRef+"' link');");

See http://tadhg.com/wp/2006/12/12/using-new-function-in-javascript/ for more details.

But it's generally better to see if you can have a single handler. It's interesting that when you get to an event handler, the "this" keyword refers to the generator of the event. So you could have your original code refer to this.getAttribute("href"). Too many handlers will make your javascript event processing slow.

John