Comment détecter une div ayant perdu le focus?

Avec le balisage suivant, je souhaite détecter le moment où un éditeur a perdu le focus

EDIT: Lorsque l’utilisateur divise les éléments d’entrée et que chaque éditeur perd le focus (c’est-à-dire qu’il se trouve en dehors du div), ajoutez la classe de chargement au div qui a perdu le focus.

Ce peu de jQuery est ce que je m’attendais à travailler, mais il ne fait rien:

 $(".editor") .blur(function(){ $(this).addClass("loading"); }); 

Cela semble fonctionner jusqu’à ce que vous ajoutiez le journal de la console et que vous réalisiez qu’il se déclenche à chaque activation des entrées.

 $('div.editor input').focus( function() { $(this).parent() .addClass("focused") .focusout(function() { console.log('focusout'); $(this).removeClass("focused") .addClass("loading"); }); }); 

Voici un extrait de mon cas de test sur lequel j’ai travaillé. Je sais qu’il me manque quelque chose de fondamental ici. Quelqu’un peut-il m’éclairer?

EDIT: Après certains des commentaires ci-dessous, cela fonctionne presque comme je le veux. Le problème est maintenant de détecter quand le focus passe quelque part en dehors d’un éditeur. Voici ma mise en œuvre actuelle:

 function loadData() { console.log('loading data for editor ' + $(this).attr('id')); var $editor = $(this).removeClass('loaded') .addClass('loading'); $.post('/echo/json/', { delay: 2 }) .done(function () { $editor.removeClass('loading') .addClass('loaded'); }); } $('div.editor input').on('focusin', function () { console.log('focus changed'); $editor = $(this).closest('.editor'); console.log('current editor is ' + $editor.attr('id')); if (!$editor.hasClass('focused')) { console.log('switched editors'); $('.editor.focused') .removeClass('focused') .each(loadData); $editor.addClass('focused'); } }) 

Un peu plus compliqué, et utiliser des classes pour state. J’ai également ajouté un élément de complexité supplémentaire, qui consiste à émettre un appel asynchrone lorsqu’un éditeur perd le focus. Voici un mon fond de mon travail actuel.

Si vous souhaitez traiter l’entrée et la sortie des paires d’entrées comme si elles avaient été combinées dans un seul contrôle, vous devez voir si l’élément ayant le focus est dans le même editor . Vous pouvez faire cela en retardant la vérification d’un cycle en utilisant un setTimeout de 0 (qui attend que toutes les tâches en cours soient terminées).

 $('div.editor input').focusout(function () { var $editor = $(this).closest('.editor'); // wait for the new element to be focused setTimeout(function () { // See if the new focused element is in the editor if ($.contains($editor[0], document.activeElement)) { $editor.addClass("focused").removeClass("loading"); } else { $editor.removeClass("focused").addClass("loading"); } }, 1); }); 

JSFiddle: http://jsfiddle.net/TrueBlueAussie/8s8ayv52/18/

Pour compléter le puzzle (obtenir votre état vert initial), vous devez également capturer l’événement focusin et voir s’il provient ou non du même éditeur (enregistrez l’élément ciblé précédent dans un élément global, etc.).

Note latérale: j’ai récemment dû écrire un plugin jQuery qui faisait tout cela pour des groupes d’éléments. Il génère des événements groupfocus et groupblur personnalisés pour faciliter l’utilisation du rest du code.

Mise à jour 1: http://jsfiddle.net/TrueBlueAussie/0y2dvxpf/4/

Sur la base de votre nouvel exemple, vous pouvez capturer la mise au point à plusieurs resockets sans l’endommager. Par conséquent, il n’est pas nécessaire de suivre la mise au point précédente. L’utilisation de mon exemple précédent setTimeout résout le problème que vous rencontrez en cliquant en dehors des divs.

 $('div.editor input').focusin(function(){ var $editor = $(this).closest('.editor'); $editor.addClass("focused").removeClass("loading"); }).focusout(function () { var $editor = $(this).closest('.editor'); // wait for the new element to be focused setTimeout(function () { // See if the new focused element is in the editor if (!$.contains($editor[0], document.activeElement)) { $editor.removeClass("focused").each(loadData); } }, 0); }); 

Voici ce qui a fonctionné pour moi:

 $(".editor").on("focusout", function() { var $this = $(this); setTimeout(function() { $this.toggleClass("loading", !($this.find(":focus").length)); }, 0); }); 

Exemple:

http://jsfiddle.net/Meligy/Lxm6720k/

Je pense que tu peux faire ça. c’est un exemple que j’ai fait. Découvrez-le: http://jsfiddle.net/igoralves1/j9soL21x/

 $( "#divTest" ).focusout(function() { alert("focusout"); });