11540 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Soient deux éléments focus-ables A et B, chacun doté de gestionnaires d'événements onblur et onfocus.
Quand le focus passe de A à B,
--------------------------
L'ordre des événements (onblur sur A et onfocus sur B) est il :

1- Définitivement fixé (quel que soit le navigateur / quel que soit l'ordre des déclarations / la position des éléments dans l'arbre du DOM...)
2- Fixé en fonction de beaucoup de paramètres, c'est à dire... plus ou moins aléatoire
3- Définitivement aléatoire.

Dans les hypothèses 2 et 3 (que je crains puisque je n'ai rien lu à ce sujet dans les spécifications du W3C) si je souhaite que onblur sur A soit systématiquement joué avant le onfocus sur B, quelle est la meilleure pratique ? Un timeout sur onfocus ? (Je n'aime pas bien les timeouts)
--------------------------------------
Soit maintenant un élément dont les propriétés css suivent:
.texte TD.stdred:focus{
	background-color:yellow;}
.texte TD.stdred{
	background-color:red;}

Mêmes questions 1/2/3 relativement à l'ordre :
- exécution du gestionnaire d'événement onfocus / prise en compte de la propriété CSS, c'est à dire la coloration de son fond en jaune.
Modifié par aCOSwt (19 Jul 2014 - 10:00)
Bonjour,
Si un élément a le focus, il est le seul à le posséder.
Donc lorsque tu quittes cet élément pour une sélectionner un autre, l'élément que tu quittes déclenche un onblur (perte de focus) avant que le nouvel élément prenne le focus. C'est immuable quel que soit le navigateur.
Tu peux aussi forcer le focus sur un élément lors du chargement de la page. Par exemple le forcer sur l'élément A. Après c'est la chaine des événements qui s'enclenche (onfocus sur A -> onblur A -> onfocus B etc etc).
Modifié par semantic (19 Jul 2014 - 11:15)
Merci semantic.

Ta logique est rigoureuse et pleine de bon sens.
Bon...juste que... je n'ai jamais été habitué à ce que tous les navigateurs partagent la même conception du bon sens...

Une idée pour le séquencement interne à l'onfocus (activation du style css dédié / déroulement du code du handler) ?
Modifié par aCOSwt (19 Jul 2014 - 14:41)
Modérateur
Bonjour,

Il faut se méfier si on souhaite construire une usine à gaz lors du gain ou de la perte du focus. En particulier quand l'internaute quitte la fenêtre, plus aucun élément de la fenêtre contenant le joli code gérant le focus n'a le focus et donc aucun event onfocus n'est généré pour cette fenêtre. Et quand l'internaute revient ensuite dans la fenêtre, aucun onblur event n'est généré pour la fenêtre contenant le joli code gérant le focus.

Du coup, si l'ordre des onblur et onfocus est important, il y a fort à parier que l'ensemble ne fonctionnera pas forcément comme on l'espérait lorsqu'on a mis au point le joli code gérant le focus.

Amicalement,
Ha! Quand je pense que... je n'ai jamais rien fait avec parcimonie...
Et que là! PifBoumShplafBem! 54 ans de sardanapalisme militant pour... admettre la pertinence des conseils de parsimonhi! Smiley biggol

Merci quand même! Smiley cligne
Et même sérieusement beaucoup puisque je n'aurais pas pensé à ce cas de figure.
Il y a logiquement un focus par page ou onglet ouvert.
Un élément sélectionné reste sélectionné même si l'utilisateur passe d'un onglet/fenêtre à l'autre.

Il n'y a que deux façons pour qu'un élément perde le focus.
- Fermer la fenêtre du navigateur ou l'onglet
- Cliquer en dehors de la l'élément (ça déclenchera un onblur)

Si tu dois converser le chaine des événements même lorsque le navigateur est fermé.
Il faut détecter la fermeture du navigateur et sauvegarder via une requête ajax l'élément sélectionné sur ton serveur, puis remettre le focus sur l'élément lorsque l'utilisateur revient sur la page.
Modifié par semantic (19 Jul 2014 - 18:20)
Modérateur
semantic a écrit :
Il y a logiquement un focus par page ou onglet ouvert.
Un élément sélectionné reste sélectionné même si l'utilisateur passe d'un onglet/fenêtre à l'autre.


Douteux. Quand on change d'onglet ou de fenêtre (les moyens de le faire sont nombreux), un onblur est généré pour l'élément qui avait le focus dans la fenêtre qu'on vient de quitter. Même si cet élément te semble toujours "sélectionné' (je n'ai pas bien compris au passage ce que tu entends par là), il n'a donc plus le focus. Ce n'est que si tu reviens dans cet onglet ou cette fenêtre que cet élément reprendra éventuellement le focus (ça dépend de la manière dont on revient dans la fenêtre quand même).

semantic a écrit :

Il n'y a que deux façons pour qu'un élément perde le focus.
- Fermer la fenêtre du navigateur ou l'onglet
- Cliquer en dehors de la l'élément (ça déclenchera un onblur)


C'est sensiblement plus compliqué que ça, car il faut aussi considérer une éventuelle navigation clavier, et éventuellement d'autres cas ésotériques (qui ont toutes les chances d'être navigateur-dépendants").

EDIT : il faut aussi considérer les cas où l'on change le focus via un script.

Amicalement,
Modifié par parsimonhi (19 Jul 2014 - 19:48)
Oui tu as raison, le changement d'onglet provoque bien un onblur.
Autant pour moi.
Petit test pour les curieux



<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>test/title>
<script type="text/javascript">
function test1(){
	console.log('focus');
}
function test2(){
	console.log('blur');
}
</script>
</head>

<body>
<input type="text" onfocus="test1()" onblur="test2()">
</body>
</html>


Affiche dans console

focus
blur
focus

Merci d'avoir corrigé Smiley cligne
parsimonhi a écrit :
EDIT : il faut aussi considérer les cas où l'on change le focus via un script

Smiley biggol Arghhh! C'est aussi mon cas! Smiley lol
EtZalor ? Dans ce cas précis... à quelle surprise dois-je m'attendre ? Smiley confused
(Toujours dans le sens séquencement onblur onfocus)
Modifié par aCOSwt (19 Jul 2014 - 22:09)
Pour les façons de perdre le focus, il y en a plein qui n'ont pas été citées: clic dans une autre fenêtre, clic dans des barres systèmes p.ex. menu démarrer, ouverture d'un menu par clic ou Alt+mnemonic, Alt+Tab, Ctrl+Alt+Del, une popup surgissante d'un autre logiciel...

a écrit :
EDIT : il faut aussi considérer les cas où l'on change le focus via un script

Je pensais que les évènements n'étaient pas déclenchés lorsqu'on les exécutait par script. Eh bien, en ce qui concerne le focus, visiblement, ça dépend. Ca me paraît complètement illogique, d'habitude il me semblais que ce n'était pas le cas...

LE code ci-dessous le prouve, il fait planter IE Smiley lol

<!DOCTYPE HTML>
<html><head>
<title>Test</title>
<script type="text/javascript">
window.onload = function(){
var f1 = document.getElementById('f1'), f2 = document.getElementById('f2'), f3 = document.getElementById('f3');
registerEvents(f1,f2);
registerEvents(f2,f3);
registerEvents(f3,f1);
}

function registerEvents (e, f) {
e.onfocus = function(){ f.focus(); }
}

</script>
</head><body>
<p><label for="f1">Champ 1: </label><input type="text" id="f1" /></p>
<p><label for="f2">Champ 2: </label><input type="text" id="f2" /></p>
<p><label for="f3">Champ 3: </label><input type="text" id="f3" /></p>
</body></html>
BubBLing ma tuer Smiley biggol

Bon, je viens de lire un truc (an anglais donc je ne citerai pas) qui explique que beaucoup de ces ennuis que vous décrivez (dont la plus ou moins non génération d'événement onfocus / onblur via setting du focus par javascript) viendrait du fait que les événements onfocus et onblur ne bubble pas.
Et que, si c'est ce que l'on souhaite, il vaut mieux utiliser onfocusin / onfocusout.

Qu'en pensez-vous ? Article obsolete ? Je n'ai rien compris ? Rien Navoir ? Smiley confus
Modifié par aCOSwt (20 Jul 2014 - 00:07)
a écrit :
Bon, je viens de lire un truc (an anglais donc je ne citerai pas) qui explique que beaucoup de ces ennuis que vous décrivez (dont la plus ou moins non génération d'événement onfocus / onblur via setting du focus par javascript) viendrait du fait que les événements onfocus et onblur ne bubble pas.
Et que, si c'est ce que l'on souhaite, il vaut mieux utiliser onfocusin / onfocusout.


Est-ce que tu pourrais mettre un lien vers la source même si c'est en anglais ? En informatique, je ne pense pas qu'on puisse se permettre d'être anglophobe.

Je n'ai jamais entendu parler de ces évènements, donc j'ignore totalement s'ils sont standard ou pas. IL faudrait se documenter et tester.
Modérateur
Bonjour,

Si on a un code qui est sensible au fait qu'on est en "bubbling mode" (l'évènement est d'abord généré sur l'élément contenant puis sur l'élément contenu) ou en "capturing mode" (l'évènement est d'abord généré sur l'élément contenu puis sur l'élément contenant), on a toutes les chances que ça ne marche pas. Au mieux, ce sera navigateur-dépendant.

En ce qui concerne focusin ou focusout, ça ne marche pas encore partout (et en particulier pas sous firefox).

En combinant dans tous les sens, on peut peut-être s'en sortir, mais ça dépend de tellement de paramètres et de ce qu'on veut faire qu'il est difficile de donner ici une recette.

Tout ce qu'on peut dire, c'est que pour avoir un code robuste en la matière, la meilleure philosophie est de limiter au maximum le recours aux focus ou blur events, et surtout de limiter l'utilisation de la fonction focus() de javascript au strict nécessaire.

Note : quand on utilise la fonction focus() de javascript, il faut aussi faire attention à la manière dont est scrollé la page si celle-ci dépasse la taille de la fenêtre (le navigateur effectue éventuellement un scroll automatiquement pour rendre visible un élément prenant le focus s'il ne l'était pas déjà, et ça ne marche pas forcément partout de la même façon selon ce qu'on est en train d'essayer de faire).

Amicalement,
QuentinC a écrit :
Est-ce que tu pourrais mettre un lien vers la source même si c'est en anglais ?

http://javascript.info/tutorial/focus
En fait, l'info qui m'a permis de comprendre pourquoi est, (je traduis)
a écrit :
Détecter qu'une fenêtre a le focus et donner le focus à une fenêtre ou un onglet est particulièremnt bordélique.
Ceci est pour partie dû au fait que les événements focus et blur ne se propagent pas ET aussi parce que la fenêtre de navigateur est liée au système d'exploitation ET que JavaScript n'est pas intégré au gestionnaire d'écran.
Bon... grâce à vos conseils (à l'exclusion de ceux de prudence... Smiley lol )
Je crois être parvenu à mes fins.
Cela fonctionne pour moi... (FireFox + Chrome + Safari + IE) (récents)

@QuentinC... n'essaye pas encore... tu ne t'en sortirais pas parce que j'ai encore dû jouer avec un preventDefault qui va te coincer dans la grille.
Je m'attellerai à cela c'est promis.

Bon alors pour résumer la réponse à mes questions, j'ai pu constater (dans mon cas précis, c'est à dire que cela ne veut pas dire que cela fonctionnerait ainsi dans d'autres... cf remarques avisées des contributeurs ci-dessus)

1/ Si un objet TD (1) à le focus ET que le focus est donné à un objet TD (2) que ce soit par action de l'utilisateur OU par JavaScripting... Alors :
- L'événement onblur sur (1) est systématiquement généré AVANT l'événement onfocus sur (2)
- L'application du style CSS particulier sur focus ne se mélange pas les pinceaux avec ça et est bien concurrente avec l'événement onfocus.
- Et accessoirement, lorsque l'on quitte la fenêtre de navigateur au profit d'une autre ou que l'on change d'onglet et que l'on revient ensuite sur cette fenêtre / onglet alors : En fonction des navigateurs / OS :
Soit on retrouve la même situation (c'est à dire que l'objet a bien gardé le focus)
Soit l'objet a perdu le focus MAIS la onblur associé a bien été joué.

Cool Donc.

Et Merci encore pour votre aide.
Résolu donc.
Pourquoi faut-il créer un nouveau post pour avoir la casàcochér résolu.
Errr... Pourquoi ne peut-on avoir ladite case à cocher quand on ré-édite ?
Hmm... Je devine la réponse... (Parce que c'est comme ça?) Smiley biggol
Modifié par aCOSwt (25 Jul 2014 - 11:43)