2010-12-05 35 views
6

Dans l'exemple suivant, j'obtiens une seule zone d'alerte. J'ai lu que l'accent est mis avant que le code JavaScript est exécuté. Y a-t-il un moyen de le faire fonctionner?onfocus n'est pas appelé lors de l'utilisation de l'attribut autofocus sur une étiquette d'entrée

<input id="i" type="text" autofocus onfocus="alert(1)"> 

<script type="text/javascript"> 
document.getElementById('i').addEventListener('focus', function() { 
    alert(2); 
}, false); 
</script> 

(je n'ai testé dans Safari)

Edit: Je ne peux évidemment le faire de cette façon (sélecteur prototypejs):

var autofocusElement = $$('input[autofocus]')[0]; 
callListener(autofocusElement); 

Mais il semble laid par rapport à ajouter seulement un écouteur d'événement.

Edit:

Ne vous inquiétez pas sur un manque de soutien du navigateur pour l'attribut autofocus. Il a résolu facilement comme je l'ai fait dans les liens de violon que je fais ci-dessous. Il y a aussi la meilleure solution au problème que je peux voir. Ma question est si je peux le faire dans un moins laid que d'avoir à appeler l'auditeur manuellement.

http://jsfiddle.net/tellnes/7TMBJ/3/

Il fonctionne très bien dans Firefox 3.6 car Firefox ne prend pas en charge l'autofocus. Mais dans Safari, qui prend en charge l'autofocus, l'événement n'est pas appelé.

+0

Mauvais lien de violon? – Rahul

+0

@Rahul On dirait que j'ai renommé mon nom d'utilisateur jsfiddle depuis sa publication. J'ai mis à jour le lien. –

Répondre

5

De l'HTML5 working draft:

Il ne doit pas avoir plus d'un élément dans le document avec l'attribut autofocus spécifié.

Vous demandez donc un comportement non défini de toute façon.

Avec un seul élément autofocus, sous Firefox 3.6, aucun des gestionnaires n'est appelé au chargement de la page. Le fait de donner manuellement le focus à l'élément appelle les deux gestionnaires (puis se poursuit dans une boucle infinie, en raison des boîtes d'alerte donnant le focus à l'élément lors de la fermeture).

Le projet de HTML5 ne dit que autofocus devrait effectuer la focusing steps la charge de page, y compris l'événement est focus, mais il est probable que les navigateurs ne sont pas actuellement en œuvre cette fonction d'une manière complète ou cohérente. Vous pouvez appeler explicitement votre gestionnaire d'événements focus pendant le chargement de la page jusqu'à ce que la spécification HTML5 soit terminée et que les navigateurs commencent à viser un support complet.

+0

Le fait est que je ne reçois pas le deuxième événement. C'était juste mon code de test qui avait deux éléments d'entrée. Ont mis à jour le code maintenant. –

+0

@ Christian, mais cela fonctionne si vous donnez manuellement le focus au contrôle après le chargement de la page, non? –

+0

@ Frédéric Hamidi Il ne déclenche pas l'addEventListener dans IE8. Semble fonctionner dans Firefox. – matthewpavkov

0

Le code suivant de votre exemple actuel:

<input id="i" type="text" autofocus onfocus="alert(1)"> 

<script type="text/javascript"> 
    document.getElementById('i').addEventListener('focus', function() { 
     alert(2); 
    }, false); 
</script> 

va provoquer une boucle infinie d'alertes en cours 1-2

[Eidt]

parce que: (ce qui ne se produit que dans broswers qui prennent en charge autofocus)

entrée

reçoit l'événement mise au point automatique, feux qui déclenche une alerte, grappins alerte se concentrer, cliquez sur OK, grappins d'entrée se concentrer, l'événement se concentrer déclenche nouvel événement déclencheur maintenant deux alertes différentes (DOM entièrement chargé maintenant si nouvel événement est ajouté avec une autre alerte), les deux alertes saisir focus, cliquez sur ok, cliquez sur OK, saisie saisit les incendies focus nouvel événement déclenchant maintenant deux alertes différentes, focus grabbs alerte, cliquez sur OK, alerte suivante saisit grab, cliquez sur ok, saisie grabbs focus, déclenche les deux événements, alerte grabbs focus, cliquez sur ok, alerte suivante grabbs focus, cliquez sur ok, saisie grabbs focus, déclenche les deux événements, alerte grabbs focus, cliquez sur ok, alerte suivante grabbs focus, cliquez sur ok, entrée saisir la mise au point, déclencher les deux événements, mettre en évidence les mises au point, cliquer sur OK, saisir l'alerte suivante, cliquer sur OK, saisir les mises au point, déclencher les deux événements, entrer gra bs focus, déclenche les deux événements, alerte grabbs focus, cliquez sur ok, alerte suivante grabbs focus, cliquez sur ok, input grabbs focus, déclenche les deux événements, saisit grabbs focus, déclenche les deux événements, alerte grabbs focus, cliquez sur ok, alerte suivante grabbs focus, cliquez sur OK, saisie grabbs focus, déclenche les deux événements, saisie grabbs focus, déclenche les deux événements, alerte grabbs focus, cliquez sur OK, alerte suivante grabbs focus, cliquez sur ok, saisie grabbs focus, déclenche les deux événements ...

Description textuelle d'un processus infini FTW! ....? : P

[/ modifier]

Dans vos exemples précédents avec deux axes d'auto-appliquée, il semble que le dernier sera exécuté comme dans l'exemple que je joins au fond. J'ai également ajouté un moyen d'ajouter un événement de focus à chaque entrée en fonction d'un nom de classe ... Je ne sais pas si vous êtes à la recherche de cela, mais cela pourrait être utile.

JSFiddle Example of onfocus event

+0

Il ne provoque pas une boucle infinie d'alertes. L'onfocus/focus est un événement unique, avec deux ensembles de code qui devraient être en cours d'exécution. Il n'y a pas de boucle. – matthewpavkov

+0

@matthewpavkov hmm ... cela a fait pour moi http://jsfiddle.net/subhaze/vxErx/ les deux ensembles de code est ce qui cause la boucle. Je suppose que 'loop' est un terme incorrect pour ça ... – subhaze

+0

Ouais ... je suppose que c'est un peu comme une boucle. Mais * boucle infinie * suggère que le code s'exécute encore et encore, en boucle, seul. L'utilisateur doit remettre l'accent sur l'entrée pour que le code s'exécute à nouveau. – matthewpavkov

0

Vous devez donner une valeur à mise au point automatique.
<input id="i" type="text" onfocus="alert(1)" autofocus="">