W3docs

Eventi focus e blur in JavaScript

Scopri come funzionano gli eventi focus e blur in JavaScript, le differenze da focusin e focusout, e come usarli per la validazione dei form e gli input accessibili.

JavaScript offre un controllo preciso sull'elemento attualmente in focus — l'elemento che riceve l'input da tastiera. Gli eventi focus e blur permettono di reagire nel momento in cui un elemento acquisisce o perde il focus, il che costituisce la base per la validazione inline dei form, l'evidenziazione del campo attivo, la creazione di widget accessibili da tastiera e la guida degli utenti attraverso un form. Questo articolo spiega cosa sono questi eventi, come si differenziano dai loro equivalenti con bubbling focusin/focusout, e alcuni pattern pratici.

Questa pagina si basa sull'introduzione agli eventi del browser. Se hai bisogno di gestire eventi su molti elementi contemporaneamente, leggi anche la sezione su bubbling e capturing.

Comprendere focus e blur in JavaScript

L'evento focus si attiva quando un elemento diventa il target attivo dell'input da tastiera — l'elemento a cui punta document.activeElement. L'evento blur si attiva quando quell'elemento perde il focus, ad esempio perché l'utente ha cliccato altrove, premuto Tab, oppure il focus è stato spostato tramite script.

Per impostazione predefinita, solo gli elementi interattivi possono ricevere il focus: i link (<a href>), i controlli di form (<input>, <textarea>, <select>, <button>) e pochi altri. Per rendere qualsiasi elemento focalizzabile — un <div>, <span> o <li> — è necessario assegnargli un attributo tabindex. Usa tabindex="0" per inserirlo nell'ordine di tabulazione naturale, oppure tabindex="-1" per renderlo focalizzabile solo tramite script (element.focus()).

Un'insidia critica: focus e blur non fanno bubbling. Un listener collegato a un elemento genitore non si attiverà quando un input discendente acquisisce il focus. Quando hai bisogno della delega degli eventi su un contenitore, usa invece gli equivalenti con bubbling focusin e focusout — si comportano in modo identico ma si propagano verso l'alto nell'albero DOM.

focus vs. blur vs. focusin vs. focusout

EventoSi attiva quandoFa bubbling?
focusl'elemento acquisisce il focusNo
blurl'elemento perde il focusNo
focusinl'elemento acquisisce il focus
focusoutl'elemento perde il focus

Per un singolo elemento noto, focus/blur sono la scelta più semplice. Per un intero form o un elenco di campi, collega focusin/focusout una sola volta sul contenitore.

Come implementare gli eventi focus

Per usare l'evento focus, collega un listener all'elemento. L'esempio seguente evidenzia un input nel momento in cui acquisisce il focus:

<input type="text" id="nameInput" placeholder="Enter Your Name">
<script>
  document.getElementById('nameInput').addEventListener('focus', function(event) {
    event.target.style.backgroundColor = 'lightblue';
  });
</script>

Questo frammento di codice rende lo sfondo del campo di input celeste quando è in focus, migliorando l'interfaccia utente indicando dove l'utente sta digitando. Per uno stile semplice, considera l'uso della pseudo-classe CSS `:focus` come alternativa standard senza JavaScript:

input:focus {
  background-color: lightblue;
}

Come implementare gli eventi blur

La validazione tramite blur è uno degli usi più comuni di questi eventi: si lascia all'utente il tempo di finire di digitare, poi si controlla il valore quando sposta il focus altrove. Ecco come validare un indirizzo email quando l'input perde il focus:

<input type="email" id="emailInput" placeholder="Enter Your Email">
<script>
  document.getElementById('emailInput').addEventListener('blur', function(event) {
    // Simplified regex for educational purposes
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(event.target.value)) {
      alert('Please enter a valid email address.');
      event.target.style.backgroundColor = 'salmon';
    } else {
      event.target.style.backgroundColor = 'lightgreen';
    }
  });
</script>

Questo script verifica se l'email inserita corrisponde a un formato email standard e avvisa l'utente se l'input non è valido. Il colore di sfondo diventa verde se valido e salmone in caso contrario, fornendo un feedback visivo immediato.

Impostare il focus tramite script

Oltre a reagire agli eventi, puoi spostare il focus manualmente con element.focus() e rimuoverlo con element.blur(). Questo è utile per portare il cursore al primo campo al caricamento della pagina, oppure per restituire il focus a un campo non valido dopo la validazione.

<input id="search" placeholder="Search..." />
<button id="go">Focus the search box</button>
<script>
  document.getElementById('go').addEventListener('click', () => {
    document.getElementById('search').focus();
  });
</script>

Due utili aggiuntivi:

  • document.activeElement restituisce sempre l'elemento che ha attualmente il focus (o <body> se nessuno ce l'ha). È comodo per verificare lo stato del focus senza listener.
  • focus({ preventScroll: true }) imposta il focus su un elemento senza scorrere la pagina per portarlo in vista — utile quando gestisci lo scroll manualmente.

Per un campo che deve ricevere il focus non appena la pagina si carica, l'attributo HTML autofocus (<input autofocus>) è l'opzione dichiarativa senza JavaScript.

Usare focusin/focusout per la delega

Poiché focus e blur non fanno bubbling, collegare un solo listener a un form non intercetterà i cambiamenti di focus sui suoi input. Gli eventi con bubbling focusin/focusout risolvono questo problema — è possibile gestire ogni campo da un singolo listener sul genitore:

<form id="signup">
  <input name="email" placeholder="Email" />
  <input name="password" type="password" placeholder="Password" />
</form>
<script>
  const form = document.getElementById('signup');
  form.addEventListener('focusin', (event) => {
    event.target.style.outline = '2px solid royalblue';
  });
  form.addEventListener('focusout', (event) => {
    event.target.style.outline = '';
  });
</script>

L'evento focusout espone anche event.relatedTarget — l'elemento che riceverà il focus successivamente — consentendo di sapere dove sta andando il focus.

Tecniche avanzate: gestione di più campi

Quando un utente compila correttamente un campo del form, puoi spostare automaticamente il focus all'input successivo non appena il corrente perde il focus. Questo semplifica la compilazione del form eliminando la necessità di clic manuali. Ecco come implementare questo comportamento:

<input type="text" id="firstName" placeholder="First Name" />
<input type="text" id="lastName" placeholder="Last Name" />
<div id="error" style="color: red;"></div> <!-- Display error message here -->
<script>
  document.getElementById('firstName').addEventListener('blur', validateFirstName);

  function validateFirstName(event) {
    const input = event.target;
    const errorDiv = document.getElementById('error');
    // Allow only letters and spaces, must not be empty
    const nameRegex = /^[A-Za-z ]+$/;
    if (!nameRegex.test(input.value)) {
      errorDiv.textContent = 'Please enter a valid first name.'; // Display error message
      input.style.backgroundColor = 'salmon'; // Set background to salmon on invalid input
      input.focus(); // Keep focus on the first name input to encourage correction
    } else {
      input.style.backgroundColor = 'white'; // Reset background to white on valid input
      errorDiv.textContent = ''; // Clear error message
      document.getElementById('lastName').focus(); // Optionally move focus to the last name input
    }
  }
</script>

Questo esempio sposta automaticamente il focus al campo lastName una volta inserito un nome valido, migliorando l'esperienza utente riducendo la necessità di clic manuali.

Chiamare input.focus() dall'interno di un handler blur può creare conflitti con l'utente. Se stava cercando di cliccare su un altro elemento, rimettere il focus sul campo può sembrare una trappola. Usa questo pattern con parsimonia e preferisci mostrare un messaggio di errore che l'utente può correggere a suo ritmo.

Errori comuni

  • Non aspettarti che focus/blur facciano bubbling. Un listener su un contenitore per focus non si attiverà mai; passa a focusin/focusout per la delega.
  • blur si esegue prima che il clic su un altro controllo sia completato. Se un handler blur nasconde o rimuove un elemento su cui l'utente ha appena cliccato, il clic potrebbe non essere registrato — controlla prima event.relatedTarget.
  • Gli elementi nascosti o con display:none non possono ricevere il focus. element.focus() non produce alcun effetto su di essi.
  • Forzare il focus può danneggiare l'accessibilità quando è inaspettato. Mantieni l'ordine di tabulazione da tastiera prevedibile ed evita di intrappolare il focus.
  • Per lo stile visivo del focus, preferisci le pseudo-classi CSS :focus / :focus-visible rispetto a JavaScript — non richiedono listener e funzionano anche con la navigazione solo da tastiera.

Conclusione

Gli eventi focus e blur sono la spina dorsale dei form interattivi e accessibili. Sapere che focus/blur non fanno bubbling (mentre focusin/focusout sì), come spostare il focus con element.focus(), e dove tracciare il confine tra JavaScript e la pseudo-classe CSS :focus ti permette di creare esperienze di input reattive senza sorprendere i tuoi utenti.

In seguito, esplora le interazioni correlate del browser: gli eventi da tastiera, gli eventi change, input, cut, copy, paste e il bubbling e capturing per la delega.

Esercitazione

Pratica
Quali delle seguenti affermazioni sugli eventi focus e blur in JavaScript sono corrette?
Quali delle seguenti affermazioni sugli eventi focus e blur in JavaScript sono corrette?
Was this page helpful?