2008-10-06 5 views
12

J'ai une zone de texte lightbox affichée à l'aide d'un appel AJAX provenant d'un UpdatePanel ASP.NET. Lorsque la lightbox est affichée, j'utilise la méthode focus() d'une zone de texte qui se trouve dans la lightbox pour mettre immédiatement la zone de texte au point.Vérification de la mise au point d'un élément DOM

Dans Firefox, la zone de texte est mise au point sans problème. Dans IE, la zone de texte ne gagne pas le focus à moins d'utiliser

setTimeout(function(){txtBx.focus()}, 500); 

pour faire un peu plus tard le feu la méthode de mise au point, après l'élément DOM a été chargé je suppose. Le problème est, immédiatement au-dessus de cette ligne, je vérifie déjà si l'élément est null/indéfini, donc l'objet devrait déjà exister s'il touche cette ligne, il ne se permettra pas de gagner le focus tout de suite pour une raison quelconque. Il est évident que le fait de régler un temporisateur pour "résoudre" ce problème n'est pas la meilleure ou la manière la plus élégante pour résoudre ce problème. Je voudrais être en mesure de faire quelque chose comme ce qui suit:

var txtBx = document.getElementById('txtBx'); 

if (txtPassword != null) { 
    txtPassword.focus(); 
    while (txtPassword.focus === false) { 
     txtPassword.focus(); 
    } 
} 

Est-il possible de dire qu'une zone de texte a le focus pour que je puisse faire quelque chose comme ci-dessus? Ou est-ce que je regarde ça dans le mauvais sens?

Modifier
Pour clarifier les choses, je ne suis pas d'appeler le code de la charge de page. Le script est en haut de la page, mais il se trouve à l'intérieur d'une fonction appelée lorsque la publication asynchrone d'ASP.NET est terminée, et non lors du chargement de la page. Comme il est affiché après une mise à jour Ajax, le DOM doit déjà être chargé, donc je suppose que l'événement $(document).ready() de jQuery ne sera pas utile ici.

+0

La méthode fonctionne-t-elle si vous définissezTimeout() avec un délai de 0? – Aintaer

+0

Se pourrait-il que le script soit en cours d'exécution avant le rendu de la lightbox + textbox? Comment ouvrez-vous la visionneuse? Peut-être poster un code. –

+0

C'est certainement possible, je ne suis pas sûr de savoir quoi faire pour contourner cela. –

Répondre

1

Essayez de placer le javascript qui définit le focus à la fin de la page au lieu du début ou de l'activer après l'événement de chargement de la page. Cela aidera à s'assurer que le DOM est complètement chargé avant de régler le focus. J'ai utilisé FastInit pour cela. JQuery $ (document) .ready() fonctionnerait également.

1

vous pourriez essayer quelque chose comme [IE Specific]. (Non testé)

theAjaxCreatedElement.onreadystatechange = function() { 
    if (this.readyState != "complete") 
     return; 
    this.focus(); 
}; 

Une autre façon peut-être de changer la couleur de fond de l'élément avec onfocus, puis le récupérer avec un chèque js si elle est ce qu'elle devrait être, sinon: recentrer l'élément.

+0

J'ai essayé ça. Le readyState est déjà "complet", ce qui me dérange vraiment. IE dit que l'élément DOM est prêt, mais vous ne pouvez pas faire de choses spécifiques jusqu'à ce qu'il soit "vraiment prêt", je suppose que c'est la meilleure façon de le décrire. –

1

Vous pouvez essayer ceci:

  1. Utilisez l'événement endRequest du PageRequestManager. Cet événement se déclenche une fois qu'une mise à jour Ajax est terminée.
  2. concentrer la zone de texte dans le gestionnaire d'événements

Voici quelques exemples de code:

<script type="text/javascript"> 
    function onRequestEnd() 
    { 
    var txtBx = $get('txtBx'); 
    txtBx.focus(); 
    } 
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onRequestEnd); 
</script> 

Pour concentrer la zone de texte, vous pouvez d'abord utiliser la fonction pageLoad (raccourci à l'événement load du client Application -side objet):

<script type="text/javascript"> 
function pageLoad() 
{ 
    var txtBx = $get('txtBx'); 
    txtBx.focus(); 
} 
</script> 
+0

C'est exactement ce que j'utilise en ce moment. La méthode focus() de l'élément est appelée dans la méthode onRequestEnd(). –

1

Il y a plusieurs choses dans IE, ça fait l'affaire:

  1. Si l'élément de mise au point a différent z-index - vous pouvez définir rapidement z-index à celui de l'élément actuellement focalisé (éventuellement paramètre d'attribut « caché »), mise au point réglée, puis réglez-le revenir à Z- d'origine indice.

  2. Essayez de flouter() l'élément actuellement ciblé.

  3. Si l'élément est "calé", faites la mise au point sur l'élément "shim".

+0

Que voulez-vous dire par "shimmed"? –

+0

http://blogs.sun.com/venky/entry/ie_shim_technique – Thevs

1

Il semble que IE ne met pas à jour le DOM tant que le script n'est pas terminé. Ainsi, un test de boucle pour focus ne permettra pas au DOM de se mettre à jour. L'utilisation de setTimeout est probablement la seule solution de travail.

Votre exemple avec .focus() est un exemple bien connu, voir par ex. this answer.

1

Avez-vous essayé d'ajouter l'attribut autofocus="autofocus" à l'élément de zone de texte que vous appelez via Ajax?

Normalement, lorsque j'ai besoin de certaines fonctionnalités JavaScript supplémentaires pour exécuter du contenu dynamique, je vais simplement ajouter ce JavaScript au contenu appelé.

Ce JavaScript sera également exécuté après son ajout au DOM. Je ne vois pas l'intérêt d'écrire du JavaScript dans votre fichier parent et d'écouter ensuite les modifications apportées au DOM. Comme vous l'avez mentionné, setTimeout() est plus un hack que n'importe quoi d'autre pour quelque chose comme ça :)

Questions connexes