Zaostřování:zaostření/rozostření

Prvek získá fokus, když na něj uživatel klikne nebo použije Tab klávesu na klávesnici. Je zde také autofocus Atribut HTML, který ve výchozím nastavení zaměří na prvek při načtení stránky a další způsoby, jak zaostřit.

Zaměření na prvek obecně znamená:„připravte se na přijetí dat zde“, takže to je okamžik, kdy můžeme spustit kód pro inicializaci požadované funkce.

Okamžik ztráty zaostření („rozostření“) může být ještě důležitější. To je, když uživatel klikne někam jinam nebo stiskne Tab přejít na další pole formuláře, nebo existují i ​​jiné způsoby.

Ztráta fokusu obecně znamená:„data byla vložena“, takže můžeme spustit kód a zkontrolovat je nebo dokonce uložit na server a tak dále.

Při práci s ohniskovými událostmi existují důležité zvláštnosti. Uděláme vše, abychom je pokryli dále.

Zaměření/rozmazání událostí

focus událost je volána při zaměření a blur – když prvek ztratí fokus.

Použijme je pro ověření vstupního pole.

V níže uvedeném příkladu:

  • blur handler zkontroluje, zda je v poli zadán e-mail, a pokud ne – zobrazí chybu.
  • focus handler skryje chybovou zprávu (na blur bude znovu zkontrolováno):
<style>
 .invalid { border-color: red; }
 #error { color: red }
</style>

Your email please: <input type="email" id="input">

<div id="error"></div>

<script>
input.onblur = function() {
 if (!input.value.includes('@')) { // not email
 input.classList.add('invalid');
 error.innerHTML = 'Please enter a correct email.'
 }
};

input.onfocus = function() {
 if (this.classList.contains('invalid')) {
 // remove the "error" indication, because the user wants to re-enter something
 this.classList.remove('invalid');
 error.innerHTML = "";
 }
};
</script>

Moderní HTML nám umožňuje provádět mnoho ověření pomocí vstupních atributů:required , pattern a tak dále. A někdy jsou přesně tím, co potřebujeme. JavaScript lze použít, když chceme větší flexibilitu. Také bychom mohli automaticky odeslat změněnou hodnotu na server, pokud je správná.

Metody zaostření/rozmazání

Metody elem.focus() a elem.blur() nastavit/zrušit zaměření na prvek.

Ukažme například, že návštěvník nebude moci opustit vstup, pokud je hodnota neplatná:

<style>
 .error {
 background: red;
 }
</style>

Your email please: <input type="email" id="input">
<input type="text" style="width:220px" placeholder="make email invalid and try to focus here">

<script>
 input.onblur = function() {
 if (!this.value.includes('@')) { // not email
 // show the error
 this.classList.add("error");
 // ...and put the focus back
 input.focus();
 } else {
 this.classList.remove("error");
 }
 };
</script>

Funguje ve všech prohlížečích kromě Firefoxu (chyba).

Pokud do vstupu něco zadáme a pak zkusíme použít Tab nebo klikněte mimo <input> a poté onblur vrátí fokus zpět.

Upozorňujeme, že nemůžeme „zabránit ztrátě pozornosti“ voláním event.preventDefault() v onblur , protože onblur funguje po prvek ztratil fokus.

V praxi by si však měl člověk před implementací něčeho takového dobře rozmyslet, protože obecně měli bychom vykazovat chyby uživateli, ale neměly by bránit jejich postupu při vyplňování našeho formuláře. Možná budou chtít nejprve vyplnit další pole.

Ztráta fokusu iniciovaná JavaScriptem

Ke ztrátě zaostření může dojít z mnoha důvodů.

Jednou z nich je, když návštěvník klikne někam jinam. Může to ale způsobit i samotný JavaScript, například:

  • alert přesune fokus na sebe, takže způsobí ztrátu fokusu u prvku (blur událost) a když alert se zavře, fokus se vrátí (focus událost).
  • Pokud je prvek odstraněn z DOM, způsobí to také ztrátu fokusu. Pokud jej později znovu vložíte, zaměření se nevrátí.

Tyto funkce někdy způsobují focus/blur manipulátory se chovat špatně – spouštět, když nejsou potřeba.

Nejlepším receptem je být při používání těchto akcí opatrný. Pokud chceme sledovat ztrátu soustředění iniciovanou uživatelem, měli bychom se vyhnout tomu, abychom ji sami způsobili.

Povolit zaměření na libovolný prvek:tabindex

Ve výchozím nastavení mnoho prvků ostření nepodporuje.

Seznam se mezi prohlížeči trochu liší, ale jedna věc je vždy správná:focus/blur podpora je zaručena pro prvky, se kterými může návštěvník interagovat:<button> , <input> , <select> , <a> a tak dále.

Na druhou stranu prvky, které existují pro formátování něčeho, například <div> , <span> , <table> – jsou ve výchozím nastavení nezaostřitelné. Metoda elem.focus() na nich nefunguje a focus/blur události se nikdy nespouštějí.

To lze změnit pomocí HTML atributu tabindex .

Jakýkoli prvek se stane zaostřitelným, pokud má tabindex . Hodnota atributu je pořadové číslo prvku, když Tab (nebo něco takového) se používá k přepínání mezi nimi.

To znamená:pokud máme dva prvky, první má tabindex="1" a druhý má tabindex="2" a poté stiskněte Tab zatímco v prvním prvku – přesune fokus na druhý.

Pořadí přepínačů je:prvky s tabindex z 1 a výše přejděte jako první (v tabindex pořadí) a poté prvky bez tabindex (např. běžný <input> ).

Prvky neodpovídající tabindex jsou přepnuty v pořadí zdroje dokumentu (výchozí pořadí).

Existují dvě speciální hodnoty:

  • tabindex="0" vloží prvek mezi prvky bez tabindex . To znamená, že když přepneme prvky, prvky s tabindex=0 přejděte za prvky s tabindex ≥ 1 .

    Obvykle se používá k tomu, aby byl prvek zaostřitelný, ale ponechte výchozí pořadí přepínání. Chcete-li učinit prvek součástí formuláře na stejné úrovni jako <input> .

  • tabindex="-1" umožňuje pouze programové zaměření na prvek. Karta klíč takové prvky ignoruje, ale metoda elem.focus() funguje.

Zde je například seznam. Klikněte na první položku a stiskněte Tab :

Click the first item and press Tab. Keep track of the order. Please note that many subsequent Tabs can move the focus out of the iframe in the example.
<ul>
 <li tabindex="1">One</li>
 <li tabindex="0">Zero</li>
 <li tabindex="2">Two</li>
 <li tabindex="-1">Minus one</li>
</ul>

<style>
 li { cursor: pointer; }
 :focus { outline: 1px dashed green; }
</style>

Pořadí je toto:1 - 2 - 0 . Normálně <li> nepodporuje ostření, ale tabindex full to umožňuje spolu s událostmi a stylingem pomocí :focus .

Vlastnost elem.tabIndex funguje také

Můžeme přidat tabindex z JavaScriptu pomocí elem.tabIndex vlastnictví. To má stejný účinek.

Delegování:focusin/focusout

Události focus a blur nebublá.

Nemůžeme například zadat onfocus na <form> pro zvýraznění takto:

<!-- on focusing in the form -- add the class -->
<form onfocus="this.className='focused'">
 <input type="text" name="name" value="Name">
 <input type="text" name="surname" value="Surname">
</form>

<style> .focused { outline: 1px solid red; } </style>

Výše uvedený příklad nefunguje, protože když se uživatel zaměří na <input> , focus událost spouští pouze na tomto vstupu. Nebublá to. Takže form.onfocus nikdy nespustí.

Existují dvě řešení.

Za prvé, je tu vtipná historická funkce:focus/blur nevybublávají, ale šíří se dolů ve fázi zachycování.

Toto bude fungovat:

<form id="form">
 <input type="text" name="name" value="Name">
 <input type="text" name="surname" value="Surname">
</form>

<style> .focused { outline: 1px solid red; } </style>

<script>
 // put the handler on capturing phase (last argument true)
 form.addEventListener("focus", () => form.classList.add('focused'), true);
 form.addEventListener("blur", () => form.classList.remove('focused'), true);
</script>

Za druhé, existuje focusin a focusout události – přesně stejné jako focus/blur , ale bubliny.

Pamatujte, že musí být přiřazeny pomocí elem.addEventListener , nikoli on<event> .

Takže tady je další pracovní varianta:

<form id="form">
 <input type="text" name="name" value="Name">
 <input type="text" name="surname" value="Surname">
</form>

<style> .focused { outline: 1px solid red; } </style>

<script>
 form.addEventListener("focusin", () => form.classList.add('focused'));
 form.addEventListener("focusout", () => form.classList.remove('focused'));
</script>

Shrnutí

Události focus a blur spoušť na prvku zaostření/ztráta zaostření.

Jejich speciality jsou:

  • Nebublávají. Místo toho lze použít stav zachycení nebo focusin/focusout .
  • Většina prvků ve výchozím nastavení nepodporuje zaměření. Použijte tabindex aby bylo možné cokoli zaměřit.

Aktuální aktivní prvek je dostupný jako document.activeElement .