views:

35

answers:

2

Hi all,

I'm fairly new to JQuery and Javascript in general. I don't think I'm trying to do anything too tricky, but this has me stumped.

I have a series of links on my page which trigger a certain behaviour within the page when clicked. Once they are clicked again, they are supposed to jump to another page, but, using my current code, they don't do anything.

I'm guessing there's a really simple workaround to this problem, but I can't figure it.

I've put up a bare-bones example (displaying the same problems) here: http://jsbin.com/egaji3/edit. Code is also pasted below.

JS:

$('a.dummy').click(function(){
  var myquery = $(this).attr('title');
  $('p#output').text('You clicked on the ' + myquery + '. Click again to Google it.');
  $('a').addClass('dummy');
  $('a').attr('href', '#'); 
  $(this).removeClass('dummy');
  $(this).attr('href', 'http://www.google.com.au/#q=' + myquery); 
  return false;
});
​

HTML:

<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;
<meta charset=utf-8 />
<title>JS Bin</title>
<style>
  a { color: #00f; background: #ff0; }
  a.dummy { color: #999; background: none; }
</style>
</head>
<body>
  The things: 
  <a class="dummy" href="#" title="first thing">First Thing</a>
  <a class="dummy" href="#" title="second thing">Second Thing</a>
  <a class="dummy" href="#" title="third thing">Third Thing</a>  
  <p id="output">You haven't clicked anything yet!</p>
</body>
</html>

A: 

You have further explained that you want the first click to set the link and the second to navigate to it.

Your problem then is that when you bind the event handler, it stays bound even though you've removed the dummy class. Simplest solution is simply to use live() instead:

$("a.dummy").live("click", function() {
  var myquery = $(this).attr('title');
  $('p#output').text('You clicked on the ' + myquery + '. Click again to Google it.');
  $('a').addClass('dummy');
  $('a').attr('href', '#'); 
  $(this).removeClass('dummy');
  $(this).attr('href', 'http://www.google.com.au/#q=' + myquery); 
  return false;
});

bind() (as implicitly called from click() is a static binding. live() updates so once you remove the dummy class, the event handler will no longer be called.

An alternative approach is to use one(), which is called but once:

$("a.dummy").one("click", function() {
  var myquery = $(this).attr('title');
  $('p#output').text('You clicked on the ' + myquery + '. Click again to Google it.');
  $('a').addClass('dummy');
  $('a').attr('href', '#'); 
  $(this).removeClass('dummy');
  $(this).attr('href', 'http://www.google.com.au/#q=' + myquery); 
  return false;
});
cletus
Maybe I should have explained it better: on the first click I don't want the user navigated to the off-site link – only the action on the page to be performed. On the second click (after `class="dummy"` has been removed), I want the link to be navigated to.
poisontofu
@poisontofu see update
cletus
Thanks. `live()` does the trick (allowing the user to cycle through the links several times before navigating to one). I didn't know about the concept of binding in JS.
poisontofu
+1  A: 

After you change the href the click handler is still attached. Since you're returning false it stops the link navigation. If you just remove the handler with unbind('click') after the first click it will work.

takteek
Indeed, so use the jQuery "one" function to bind your click event so it only fires once. See here: http://api.jquery.com/one/
Ryley
But once `class="dummy"` is removed, shouldn't the links function as normal since they would no longer selected by `$('a.dummy').click(function(){` ?
poisontofu
Oops, I forgot about one(). It would be much cleaner to use that instead of unbind.
takteek
@poisontofu The selector is only relevant when you first bind the handler. The handler will remain even if the criteria you used to initially bind it are no longer valid.
takteek
@Ryley - Write an answer and I'll vote for it.
Gert G
one() works if a user clicks an option then immediately clicks it again, but not if they cycle through all three links then go back to the first. Is there a way around this?
poisontofu