views:

47

answers:

3

I have this code:

function beforemouseout() {
  if ($(this).val() == '') {
    $(this).val($(this).attr('title'));

  } 
  else {

  }
  setTimeout('beforemouseout()',3000); 
}
$(".other").click(function() {
  $(this).val('');  
  $(".other").mouseout(beforemouseout);
});
<input id="hour" type="text" class="other" autocomplete="off" value="hour" title="hour" />
<input id="hour" type="text" class="other" autocomplete="off" value="minutes" title="minutes" />

But Firebug gives me an error: beforemouseout is not defined. Why? I tried it on jsfiddle.net and it doesn't give an error , but the result is not what I expected.I expected when i click on #hour to hide the text and when onmouseout is triggered to wait 5 second and then - to do the checks

+2  A: 

Yes don't pass string as parameter of setTimeout function hope you ll be done. By the way I think setTimeout is not required here. You are filling the field with 'title' if it is empty everytime while mouse is being out. if you use setTimeout and mouseout both together that will increase you function calling exponentially.I think you understand my point of view.
Thanks

Muhit
I don't think this is correct at all. The way the code is written, that function should be visible to whatever is referencing it. That would be true if the code were in a document.ready handler or if it was simply code in the global scope.
Pointy
+3  A: 

Change your setTimeout like this:

setTimeout(beforemouseout ,3000); 

Otherwise it's looking for beforemouseout in a global context, and if your code isn't in there (it's inside/scoped to another closure of any kind), it won't find it. I'm guessing here that it's in a ready handler because you're posting HTML right beside it, meaning you're taking snippets.

From an overall standpoint, never pass a string to setTimeout() or setInterval() if you can avoid it, it results in many unwanted side-effects...like this one. Instead, pass a direct reference like I have above, to be entirely explicit and well...make it work :)


Edit (for question comments): it seems what you're actually after it still a bit different than it's written. From what I gather you want to delay before restoring the default value to the <input>. There are several ways to do this, here's one:

function beforemouseout() {
  if ($(this).val() == '') {
    $(this).val($(this).attr('title'));
  }
}
$(".other").click(function() {
  $(this).val('').mouseout(function() {
    setTimeout($.proxy(beforemouseout, this), 3000);
  });
});

You can give it a try here. ​

Nick Craver
Ah yes, that's probably it.
Pointy
I believe the value of `this` in the `beforemouseout` will be incorrect when called from the `setTimeout()`.
patrick dw
@patrick - That's what [`$.proxy()`](http://api.jquery.com/jQuery.proxy/) is for ;) Give the demo a try to see it working
Nick Craver
Thank You very much!
lam3r4370
@lam3r4370 - Welcome :)
Nick Craver
Sorry Nick - I didn't refresh the browser before commenting. :o)
patrick dw
A: 

Change $(".other").mouseout(beforemouseout); to this:

$(".other").mouseout(function(){ 
  beforemouseout();
});
Marwelln
This won't help, it'll actually hurt by breaking the `this` reference, which would point to `window` instead of the element in your answer :) `beforemouseout.apply(this);` would work...but that's a really long and more expensive way to write what already works :)
Nick Craver
@Nick: Keep .other and just add the function snippet then.
Marwelln
@Marwelln - I don't follow you...anyway, it's best to correct your answer with code, since others will find this later on :)
Nick Craver