blur event.relatedTarget возвращает ноль

У меня есть <input type="text"> поле, и мне нужно очистить его, когда это поле теряет фокус (что означает, что пользователь нажал где-то на странице). Но есть одно исключение. Поле ввода текста не должно быть очищено, когда пользователь нажимает на определенный элемент.

Я пытался использовать event.relatedTarget определить, нажал ли пользователь не только где-то, но и на мой конкретный <div>,

Однако, как вы можете видеть из фрагмента ниже, он просто не работает. event.relatedTarget всегда возвращается null!

function lose_focus(event) {
  if(event.relatedTarget === null) {
    document.getElementById('text-field').value = '';
  }
}
.special {
  width: 200px;
  height: 100px;
  background: #ccc;
  border: 1px solid #000;
  margin: 25px 0;
  padding: 15px;
}
.special:hover {
  cursor: pointer;
}
<input id="text-field" type="text" onblur="lose_focus(event)" placeholder="Type something...">

<div class="special">Clicking here should not cause clearing!</div>

1 ответ

Краткий ответ: добавить tabindex="0" приписать элемент, который должен появиться в event.relatedTarget,

Объяснение: event.relatedTarget содержит элемент, который получил фокус. И проблема в том, что ваш конкретный div не может получить фокус, потому что браузер считает, что этот элемент не является кнопкой / полем или каким-то другим элементом управления.

Вот элементы, которые могут получить фокус по умолчанию:

  • <a> элементы с href указанный атрибут
  • <link> элементы с href указанный атрибут
  • <button> элементы
  • <input> элементы, которые не являются hidden
  • <select> элементы
  • <textarea> элементы
  • <menuitem> элементы
  • элементы с атрибуцией draggable
  • <audio> а также <video> элементы с controls указанный атрибут

Так event.relatedTarget будет содержать вышеуказанные элементы, когда onblur случается. Все остальные элементы не будут учитываться, и нажатие на них приведет к null в event.relatedTarget,

Но можно изменить это поведение. Вы можете "пометить" элемент DOM как элемент, который может получить фокус с атрибутом tabindex. Вот что говорит стандарт:

tabindex Атрибут содержимого позволяет авторам указывать, что элемент должен быть фокусируемым, должен ли он быть доступным с помощью последовательной навигации по фокусу и, необязательно, предлагать, где в последовательности навигации с последовательным фокусом появляется элемент.

Итак, вот исправленный фрагмент кода:

function lose_focus(event) {
  if(event.relatedTarget === null) {
    document.getElementById('text-field').value = '';
  }
}
.special {
  width: 200px;
  height: 100px;
  background: #ccc;
  border: 1px solid #000;
  margin: 25px 0;
  padding: 15px;
}
.special:hover {
  cursor: pointer;
}
<input id="text-field" type="text" onblur="lose_focus(event)" placeholder="Type something...">

<div tabindex="0" class="special">Clicking here should not cause clearing!</div>

Другие вопросы по тегам