2010-07-25 3 views
2

Je possède ce code:setTimeout et problème mouseout

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" /> 

Mais Firebug me donne une erreur: beforemouseout n'est pas définie. Pourquoi? Je l'ai essayé sur jsfiddle.net et il ne donne pas une erreur, mais le résultat n'est pas ce que je m'attendais.Je m'attendais quand je clique sur #hour pour cacher le texte et quand onmouseout est déclenché pour attendre 5 secondes puis - pour effectuer les vérifications

+2

Est-ce vraiment exactement ce que votre code ressemble? Parce que si c'est le cas, je ne pense pas que vous auriez cette erreur. Exactement quelle ligne de code Firebug dit que l'erreur se produit? – Pointy

+0

Vous pouvez réécrire 'setTimeout ('beforemouseout()', 3000)' à 'setTimeout (beforemouseout, 3000)', ce qui est plus efficace, car aucune évaluation au moment de l'exécution ne doit être effectuée. – Eric

+0

Je l'ai essayé sur jsfiddle.net et il ne donne pas une erreur, mais le résultat n'est pas ce que je m'attendais.J'attendais quand je clique sur #hour pour cacher le texte et quand onmouseout est déclenché pour attendre 5 secondes puis - faire les vérifications – lam3r4370

Répondre

3

Changez votre setTimeout comme ceci:

setTimeout(beforemouseout ,3000); 

Sinon, il cherche beforemouseout dans un contexte global , et si votre code n'est pas là-dedans (il est à l'intérieur/scope à une autre fermeture de n'importe quel genre), il ne le trouvera pas. Je devine ici que c'est dans un gestionnaire ready parce que vous publiez HTML juste à côté, ce qui signifie que vous prenez des extraits. D'un point de vue général, ne jamais passer une chaîne à setTimeout() ou setInterval() si vous pouvez l'éviter, il en résulte de nombreux effets secondaires indésirables ... comme celui-ci. Au lieu de cela, passer une référence directe comme je l'ai ci-dessus, pour être tout à fait explicite et bien ... le faire fonctionner :)


Modifier (pour les commentaires de question): il semble que vous êtes réellement après encore un peu différent de ce qu'il est écrit. D'après ce que je comprends vous voulez retarder avant de restaurer la valeur par défaut à la <input>. Il y a plusieurs façons de le faire, voici une:

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.

+1

Ah oui, c'est probablement ça. – Pointy

+0

Je crois que la valeur de 'this' dans' beforemouseout' sera incorrecte si elle est appelée depuis 'setTimeout()'. – user113716

+0

@patrick - C'est ce que ['$ .proxy()'] (http://api.jquery.com/jQuery.proxy/) est pour;) Donner la démo un essai pour le voir fonctionner –

1

Oui, ne passez pas la chaîne comme paramètre de la fonction setTimeout, espérons que vous aurez terminé. Par ailleurs, je pense que setTimeout n'est pas requis ici. Vous remplissez le champ avec 'title' s'il est vide à chaque fois que la souris est en train de sortir. si vous utilisez setTimeout et mouseout ensemble, cela vous permettra d'augmenter vos appels de manière exponentielle. Je pense que vous comprenez mon point de vue.
Merci

+0

Je ne pense pas que ce soit correct du tout. La façon dont le code est écrit, cette fonction devrait être visible à tout ce qui est référençant. Ce serait vrai si le code était dans un document.gestionnaire prêt ou si c'était simplement du code dans la portée globale. – Pointy

0

changement $(".other").mouseout(beforemouseout); à ceci:

$(".other").mouseout(function(){ 
    beforemouseout(); 
}); 
+0

Cela ne va pas aider, il va réellement faire mal en cassant la référence 'this', qui pointerait sur' window' au lieu de l'élément dans votre réponse :) 'beforemouseout.apply (this);' fonctionnerait ... mais c'est un moyen très long et plus coûteux d'écrire ce qui fonctionne déjà :) –

+0

@Nick: Gardez .other et ajoutez simplement l'extrait de fonction alors. – Marwelln

+0

Je ne vous suis pas ... de toute façon, il est préférable de corriger votre réponse avec du code, puisque d'autres le trouveront plus tard :) –