Quando si verifica un evento “sfocato”, come posso scoprire quale elemento è stato triggersto per la messa a fuoco * su *?

Supponiamo che allega una funzione di blur a una casella di input HTML come questa:

  

C’è un modo per ottenere l’ID dell’elemento che ha causato l’evento di blur (l’elemento su cui è stato fatto clic) all’interno della funzione? Come?

Ad esempio, supponiamo di avere un’estensione del genere:

 Hello World 

Se faccio clic sullo span subito dopo l’triggerszione dell’elemento di input, l’elemento di input perderà il focus. Come fa la funzione a sapere che è stato fatto clic su mySpan ?

PS: se l’evento onclick dello span dovesse verificarsi prima dell’evento onblur dell’elemento input, il mio problema sarebbe risolto, perché potrei impostare un valore di stato che indica che un elemento specifico è stato cliccato.

PPS: lo sfondo di questo problema è che voglio triggersre un controllo del completamento automatico AJAX esternamente (da un elemento cliccabile) per mostrare i suoi suggerimenti, senza che i suggerimenti scompaiano immediatamente a causa dell’evento blur sull’elemento di input. Quindi voglio controllare la funzione blur se è stato fatto clic su un elemento specifico e, in tal caso, ignorare l’evento sfocatura.

Hmm … In Firefox, puoi usare explicitOriginalTarget per tirare l’elemento su cui è stato fatto clic. Mi aspettavo di fare lo stesso per IE, ma non sembra funzionare … Tuttavia, è ansible estrarre l’elemento appena focalizzato dal documento:

 function showBlur(ev) { var target = ev.explicitOriginalTarget||document.activeElement; document.getElementById("focused").value = target ? target.id||target.tagName||target : ''; } ...     

Avvertenza: questa tecnica non funziona per le modifiche alla messa a fuoco causate dalla tabulazione attraverso i campi con la tastiera e non funziona affatto in Chrome o Safari. Il grosso problema con l’utilizzo di activeElement (eccetto in IE) è che non viene aggiornato costantemente fino a quando l’evento di blur è stato elaborato e potrebbe non avere alcun valore valido durante l’elaborazione! Questo può essere mitigato con una variazione della tecnica utilizzata da Michiel per :

 function showBlur(ev) { // Use timeout to delay examination of activeElement until after blur/focus // events have been processed. setTimeout(function() { var target = document.activeElement; document.getElementById("focused").value = target ? target.id||target.tagName||target : ''; }, 1); } 

Questo dovrebbe funzionare nella maggior parte dei browser moderni (testato in Chrome, IE e Firefox), con l’avvertenza che Chrome non imposta lo stato attivo sui pulsanti su cui si fa clic (da tabulato a).

Risposta 2015 : in base agli eventi dell’interfaccia utente , è ansible utilizzare la proprietà relatedTarget dell’evento:

Utilizzato per identificare un EventTarget secondario relativo a un evento Focus, in base al tipo di evento.

Per gli eventi blur ,

relatedTarget : destinazione dell’evento che riceve attenzione.

Esempio:

 function blurListener(event) { event.target.className = 'blurred'; if(event.relatedTarget) event.relatedTarget.className = 'focused'; } [].forEach.call(document.querySelectorAll('input'), function(el) { el.addEventListener('blur', blurListener, false); }); 
 .blurred { background: orange } .focused { background: lime } 
 

Blurred elements will become orange.

Focused elements should become lime.

L’ho risolto alla fine con un timeout sull’evento onblur (grazie al consiglio di un amico che non è StackOverflow):

  Hello World 

Funziona sia in FF che in IE.

È ansible utilizzare l’evento Mousedown del documento anziché la sfocatura:

 $(document).mousedown(function(){ if ($(event.target).attr("id") == "mySpan") { // some process } }); 

Le istanze di tipo FocusEvent hanno attributo relatedTarget , tuttavia, fino alla versione 47 di FF, in particolare, questo attributo restituisce null, da 48 già funzionante.

Puoi vedere di più qui .

Sto anche cercando di far sì che l’autocompletatore ignori la sfocatura se un elemento specifico ha fatto clic e ha una soluzione funzionante, ma solo per Firefox a causa di explicitOriginalTarget

 Autocompleter.Base.prototype.onBlur = Autocompleter.Base.prototype.onBlur.wrap( function(origfunc, ev) { if ($(this.options.ignoreBlurEventElement)) { var newTargetElement = (ev.explicitOriginalTarget.nodeType == 3 ? ev.explicitOriginalTarget.parentNode : ev.explicitOriginalTarget); if (!newTargetElement.descendantOf($(this.options.ignoreBlurEventElement))) { return origfunc(ev); } } } ); 

Questo codice avvolge il metodo onBlur predefinito di Autocompleter e controlla se sono impostati i parametri ignoreBlurEventElement. se è impostato, controlla ogni volta per vedere se l’elemento cliccato ignoraBlurEventElement o no. Se lo è, l’autocompletatore non esegue onlurl, altrimenti chiama onBlur. L’unico problema è che funziona solo in Firefox perché la proprietà explicitOriginalTarget è specifica per Mozilla. Ora sto cercando di trovare un modo diverso rispetto a usare explicitOriginalTarget. La soluzione che hai menzionato richiede di aggiungere manualmente il comportamento onclick all’elemento. Se non riesco a risolvere il problema di UnknownOriginalTarget, suppongo che seguirò la tua soluzione.

Puoi invertire ciò che stai controllando e quando? Cioè se ti ricordi cosa era l’ultimo sfocato:

  

e poi su onClick for your span, chiama function () con entrambi gli oggetti:

 Hello World 

La tua funzione potrebbe quindi decidere se triggersre o meno il controllo Ajax.AutoCompleter. La funzione ha l’object cliccato e l’object sfocato. Il onBlur è già successo, quindi non farà sparire i suggerimenti.

Usa qualcosa del genere:

 var myVar = null; 

E poi dentro la tua funzione:

 myVar = fldID; 

E poi:

 setTimeout(setFocus,1000) 

E poi:

 function setFocus(){ document.getElementById(fldID).focus(); } 

Codice finale:

          

Penso che non sia ansible, con IE puoi provare a usare window.event.toElement , ma non funziona con Firefox!

Come indicato in questa risposta , è ansible verificare il valore di document.activeElement . document è una variabile globale, quindi non devi fare magie per usarlo nel tuo gestore onBlur:

 function myOnBlur(e) { if(document.activeElement === document.getElementById('elementToCheckForFocus')) { // Focus went where we expected! // ... } } 
  • document.activeElement potrebbe essere un nodo genitore (per esempio body node perché si trova in una fase temporanea che passa da un target a un altro), quindi non è utilizzabile per il tuo scope
  • ev.explicitOriginalTarget non è sempre valutato

Quindi il modo migliore è usare onclick su body event per capire indirettamente che il tuo nodo (event.target) è sfocato

Modifica: un modo hacky per farlo sarebbe quello di creare una variabile che tenga traccia di messa a fuoco per ogni elemento che ti interessa. Quindi, se ti interessa che “myInput” abbia perso la messa a fuoco, imposta una variabile su di essa.

   

Risposta originale: puoi passare “questo” alla funzione.

  

Suggerisco di usare le variabili globali blurfrom e blurto. Quindi, configura tutti gli elementi che ti interessano per assegnare la loro posizione nel DOM alla variabile blurfrom quando perdono lo stato attivo. Inoltre, configuralo in modo tale che ottenere il focus imposta la variabile blur alla loro posizione nel DOM. Quindi, è ansible utilizzare un’altra funzione per analizzare la sfocatura e la sfocatura dei dati.

tieni presente che la soluzione con explicitOriginalTarget non funziona per i salti di input testo-input-testo.

prova a sostituire i pulsanti con i seguenti input di testo e vedrai la differenza:

    

Ho giocato con questa stessa funzione e ho scoperto che FF, IE, Chrome e Opera hanno la capacità di fornire l’elemento sorgente di un evento. Non ho provato Safari, ma suppongo che potrebbe avere qualcosa di simile.

 $('#Form').keyup(function (e) { var ctrl = null; if (e.originalEvent.explicitOriginalTarget) { // FF ctrl = e.originalEvent.explicitOriginalTarget; } else if (e.originalEvent.srcElement) { // IE, Chrome and Opera ctrl = e.originalEvent.srcElement; } //... }); 

Non mi piace usare il timeout durante la codifica di javascript, quindi farei il contrario di Michiel Borkent. (Non ho provato il codice ma dovresti avere l’idea).

  Hello World 

In testa qualcosa del genere

    

Puoi correggere IE con:

  event.currentTarget.firstChild.ownerDocument.activeElement 

Sembra “explicitOriginalTarget” per FF.

Antoine e J

Ho scritto una soluzione alternativa su come rendere qualsiasi elemento focalizzabile e “sfuocato”.

Si basa sul rendere un elemento come contentEditable e nasconderlo visivamente e disabilitare la modalità di modifica stessa:

 el.addEventListener("keydown", function(e) { e.preventDefault(); e.stopPropagation(); }); el.addEventListener("blur", cbBlur); el.contentEditable = true; 

DEMO

Nota: testato in Chrome, Firefox e Safari (OS X). Non sono sicuro di IE.


Correlati: Stavo cercando una soluzione per VueJs, quindi per coloro che sono interessati / curiosi su come implementare tale funzionalità usando la direttiva Vue Focusable, per favore date un’occhiata .

Funziona su Google Chrome v66.x, Mozilla v59.x e Microsoft Edge … Soluzione con jQuery.

Eseguo il test in Internet Explorer 9 e non sono supportato.

 $("#YourElement").blur(function(e){ var InputTarget = $(e.relatedTarget).attr("id"); // GET ID Element console.log(InputTarget); if(target == "YourId") { // If you want validate or make a action to specfic element ... // your code } }); 

Commenta il tuo test in altre versioni di Internet Explorer.

Vedo solo hack nelle risposte, ma in realtà c’è una soluzione integrata molto facile da usare: in pratica puoi catturare l’elemento focus in questo modo:

 const focusedElement = document.activeElement 

https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement

Per di qua:

   

O se si collega l’ascoltatore tramite JavaScript (jQuery in questo esempio):

 var input = $('#myinput').blur(function() { alert(this); }); 

Modifica : mi dispiace Ho letto male la domanda.

Penso che sia facilmente ansible tramite jquery passando il riferimento del campo che causa l’evento onblur in “this”.
Per es

  function showMessageOnOnblur(field){ alert($(field).attr("id")); } 

Grazie
Monika

Potresti farlo in questo modo: