2

I am building a plugin which matches an element, finds a link within it and makes the parent element go to that location upon a click.

I have a loop in the main body:

    return this.each(function(options) 
{

    $to_link = $(this); //matched object
    link_href = $('a', $to_link).attr('href'); //link location
    $($to_link,$parent)
        .click(function(){alert(link_href); window.location = link_href; return false;})
        .attr('title','Jump to ' + link_href);
})

which I am running it against this HTML

<div id="a"><h2><a href="/products/">Products</a></h2><p>blah blah</p></div>
<div id="b"><h2><a href="/thinking/">Thinking</a></h2><p>liuhads</p></div>

The problem I have is that the click function always results in jumping to the value of the last matched div's link although the title of the element has the correct value.

To clarify, behavious should be:

  • div#a has a title of "Jump to /products/" and when clicked on goes to /products/

  • div#a has a title of "Jump to /thinking/" and when clicked on goes to /thinking/

instead, what happens is:

  • div#a has a title of "Jump to /products/" and when clicked on goes to /thinking/ (the alert says /thinking/ too)

  • div#a has a title of "Jump to /thinking/" and when clicked on goes to /thinking/

ie div#a ends up with the wrong behaviour. Im guessing this is some kind of scope issue but for the life of me I cannot see it, help!

2 Answers 2

4

You are forgetting the var in your assignments, so you're sharing one global variable and getting them mixed up.

$to_link = $(this); //matched object
link_href = $('a', $to_link).attr('href'); //link location

should be

var $to_link = $(this); //matched object
var link_href = $('a', $to_link).attr('href'); //link location

Otherwise, link_href will retain the last value, and that is the value the click handler will see when its called.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! Obvious and totally missable when you're bogged down in things.
@Sqoo I wouldn't touch the stuff
saw you were a Python developer :D
4

There is a fuller answer to the general case here

http://www.foliotek.com/devblog/keep-variable-state-between-event-binding-and-execution/

answer #2 is to use a closure to force a new level of scope :)

3 Comments

Shortly after this, I learned how closures really work, after that I learned exactly what JS is really capable of by reading Crockford!
So the real answer is use closures to force new scope.
answer #2 is awesome ! Solved my problem :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.