javascript Quando si verifica un evento "sfocato", come posso scoprire quale elemento è stato attivato per la messa a fuoco * su *?




11 Answers

Risposta 2015 : in base agli eventi dell'interfaccia utente , è possibile 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 }
<p>Blurred elements will become orange.</p>
<p>Focused elements should become lime.</p>
<input /><input /><input />

Nota Firefox non supporterà relatedTarget fino alla versione 48 ( bug 962251 , MDN ).

javascript events

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

<input id="myInput" onblur="function() { ... }"></input>

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:

<span id="mySpan">Hello World</span>

Se faccio clic sullo span subito dopo l'attivazione 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 attivare 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.




È possibile utilizzare l'evento Mousedown del documento anziché la sfocatura:

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



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.




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:

<html>
<head>
    <script type="text/javascript">
        function somefunction(){
            var myVar = null;

            myVar = document.getElementById('myInput');

            if(myVar.value=='')
                setTimeout(setFocusOnJobTitle,1000);
            else
                myVar.value='Success';
        }
        function setFocusOnJobTitle(){
            document.getElementById('myInput').focus();
        }
    </script>
</head>
<body>
<label id="jobTitleId" for="myInput">Job Title</label>
<input id="myInput" onblur="somefunction();"></input>
</body>
</html>



Come indicato in questa risposta , è possibile 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!
    // ...
  }
}



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.

<script type="text/javascript">
   var lastFocusedElement;
</script>
<input id="myInput" onFocus="lastFocusedElement=this;" />

Risposta originale: puoi passare "questo" alla funzione.

<input id="myInput" onblur="function(this){
   var theId = this.id; // will be 'myInput'
}" />



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:

<input id="btn1" onblur="showBlur(event)" value="text1">
<input id="btn2" onblur="showBlur(event)" value="text2">
<input id="btn3" onblur="showBlur(event)" value="text3">



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).

<input id="myInput" onblur="blured = this.id;"></input>
<span onfocus = "sortOfCallback(this.id)" id="mySpan">Hello World</span>

In testa qualcosa del genere

<head>
    <script type="text/javascript">
        function sortOfCallback(id){
            bluredElement = document.getElementById(blured);
            // Do whatever you want on the blured element with the id of the focus element


        }

    </script>
</head>



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.





Penso che sia facilmente possibile tramite jquery passando il riferimento del campo che causa l'evento onblur in "this".
Per es

<input type="text" id="text1" onblur="showMessageOnOnblur(this)">

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

Grazie
Monika






Related