Кратко
СкопированоСобытие blur вызывается, когда элемент теряет фокус. У этого события нет фазы всплытия.
Пример
Скопированоblur удобно использовать, например, для валидации введённых данных:
Как пишется
Скопировано
element.addEventListener('blur', (event) => { console.log('Элемент потерял фокус')})
element.addEventListener('blur', (event) => {
console.log('Элемент потерял фокус')
})
Как понять
СкопированоСобытие blur инициируется в момент, когда интерактивный элемент теряет фокус и он перемещается на другой элемент (например, по клику или нажатию Tab).
Событие срабатывает на тех html-элементах, которые имеют атрибут tabindex, либо атрибут contenteditable.
Некоторые html-элементы по умолчанию имеют tabindex:
<button>;<input>;<textarea>;<select>;<frame>;<iframe>;<object>;<a>или<area>с атрибутомhref;<summary>в связке с<details>.
Как добавить событие на любой элемент
СкопированоЧтобы blur работал на произвольном элементе (например, на <div>), добавьте ему атрибут tabindex или атрибут contenteditable.
tabindex указывает браузеру, что на элементе можно сфокусироваться (а, значит, и потерять фокус).
contenteditable указывает браузеру, что элемент может редактироваться пользователем.
<div tabindex="0"> Здесь можно сфокусироваться и потерять фокус</div><div contenteditable="true"> Здесь так же можно сфокусироваться и потерять фокус</div>
<div tabindex="0">
Здесь можно сфокусироваться и потерять фокус
</div>
<div contenteditable="true">
Здесь так же можно сфокусироваться и потерять фокус
</div>
Пример
СкопированоВ примере ниже одинаковый обработчик события окрашивает границы блока при потере фокуса. Кликните на блок, а затем на любое другое место:
<div class="wrapper"> <div>Блок не может получить и потерять фокус:</div> <div class="block" id="block1"></div></div><div class="wrapper"> <div>Блок может получить и потерять фокус (с tabindex):</div> <div class="block" id="block2" tabindex="0"></div></div><div class="wrapper"> <div>Блок может получить и потерять фокус (с contenteditable):</div> <div class="block" id="block3" contenteditable="true"></div></div>
<div class="wrapper">
<div>Блок не может получить и потерять фокус:</div>
<div class="block" id="block1"></div>
</div>
<div class="wrapper">
<div>Блок может получить и потерять фокус (с tabindex):</div>
<div class="block" id="block2" tabindex="0"></div>
</div>
<div class="wrapper">
<div>Блок может получить и потерять фокус (с contenteditable):</div>
<div class="block" id="block3" contenteditable="true"></div>
</div>
const block1 = document.getElementById("block1");const block2 = document.getElementById("block2");const block3 = document.getElementById("block3");function blurHandler(event) { event.target.classList.add('green') event.target.innerHTML = '👋 Я потерял фокус'}block1.addEventListener('blur', blurHandler);block2.addEventListener('blur', blurHandler);block3.addEventListener('blur', blurHandler);
const block1 = document.getElementById("block1");
const block2 = document.getElementById("block2");
const block3 = document.getElementById("block3");
function blurHandler(event) {
event.target.classList.add('green')
event.target.innerHTML = '👋 Я потерял фокус'
}
block1.addEventListener('blur', blurHandler);
block2.addEventListener('blur', blurHandler);
block3.addEventListener('blur', blurHandler);
Делегирование события
СкопированоИз-за того, что у события blur нет фазы всплытия, его нельзя просто так делегировать родительскому элементу. Вариант решения этой проблемы — передать в метод add параметр { capture.
Обычно слушатель обрабатывает события на фазе всплытия, но, если установлен параметр { capture, будет обрабатывать событие раньше, на фазе захвата. Нужно иметь в виду, что в этом случае событие будет обработано родительским элементом раньше, чем целевым (дочерним), т.к. фаза захвата происходит до того, как событие достигает целевого элемента.
parentElement.addEventListener( 'blur', (event) => { console.log('Элемент потерял фокус') }, { capture: true })//либо эквивалентная запись:parentElement.addEventListener( 'blur', (event) => { console.log('Элемент потерял фокус') }, true //тоже самое, что прописать { capture: true })
parentElement.addEventListener(
'blur',
(event) => {
console.log('Элемент потерял фокус')
},
{ capture: true }
)
//либо эквивалентная запись:
parentElement.addEventListener(
'blur',
(event) => {
console.log('Элемент потерял фокус')
},
true //тоже самое, что прописать { capture: true }
)
Пример
СкопированоВ примере ниже одинаковый обработчик события, выводящий ошибку о незаполненном поле, вешается на две формы. В первой форме параметр { capture не установлен, во второй установлен.
<form class="form" id="form1"> <div class="form-row"> <label for="name1">Введите имя:</label> <input id="name1" type="text"> </div> <div class="form-row"> <label for="city1">Введите город:</label> <input id="city1" type="text"> </div></form>
<form class="form" id="form1">
<div class="form-row">
<label for="name1">Введите имя:</label>
<input id="name1" type="text">
</div>
<div class="form-row">
<label for="city1">Введите город:</label>
<input id="city1" type="text">
</div>
</form>
const form1 = document.getElementById("form1");const form2 = document.getElementById("form2");function blurHandler(event) { const input = event.target; if (!event.target.value) { input.classList.add('invalid'); const error = document.createElement('div'); error.textContent = 'Поле обязательно для заполнения!'; error.classList.add('error-message'); input.insertAdjacentElement('afterend', error); }}form1.addEventListener('blur', blurHandler);form2.addEventListener('blur', blurHandler, { capture: true });
const form1 = document.getElementById("form1");
const form2 = document.getElementById("form2");
function blurHandler(event) {
const input = event.target;
if (!event.target.value) {
input.classList.add('invalid');
const error = document.createElement('div');
error.textContent = 'Поле обязательно для заполнения!';
error.classList.add('error-message');
input.insertAdjacentElement('afterend', error);
}
}
form1.addEventListener('blur', blurHandler);
form2.addEventListener('blur', blurHandler, { capture: true });