#javascript #dom-events
#javascript #dom-события
Вопрос:
Я пытался определить, был ли :focus-within
потерян класс. Я пытался обнаружить щелчок вне с помощью addEventListener для ‘click’, ‘auxclick’, ‘blur’, ‘mouseup’. Но я не могу понять, как обнаружить щелчок за пределами фактического документа. Например, нажмите на ввод URL. Как я могу это решить?
Комментарии:
1. Не могли бы вы объяснить более подробно, чтобы каждый мог легко понять вопрос и предоставить вам наилучшее решение по нему?
2. Нужное вам событие
focusout
и тест, который вы хотите выполнить, когда произойдет событиеevent.target.matches(':focus-within')
. Действия, которые на самом деле не удаляют фокус (как вы описываете), не могут быть прослушаны.
Ответ №1:
Чтобы определить, был ли потерян элемент DOM :focus-within
, вы можете использовать focusout
событие следующим образом:
containerElement.addEventListener('focusout', function(e) {
if (e.currentTarget.contains(e.relatedTarget)) {
/* Focus will still be within the container */
} else {
/* Focus will leave the container */
}
});
Когда фокус полностью теряется страницей (посещение URL-адреса, переключение вкладок и т. Д.), e.relatedTarget
Не существует, Поэтому код просто работает. Если вы хотите игнорировать, когда страница теряет фокус, вы можете использовать document.hasFocus()
для проверки:
containerElement.addEventListener('focusout', function(e) {
/*
If the document has lost focus,
skip the containment check
and keep the element visible.
*/
if (!document.hasFocus()) {
return;
}
if (!e.currentTarget.contains(e.relatedTarget)) {
hideSelf();
}
});
… но тогда вы должны реагировать, когда фокус возвращается на страницу, поэтому полное (er) решение выглядит примерно так:
containerElement.addEventListener('focusout', function(e) {
const self = e.currentTarget;
/*
If the document has lost focus,
don't hide the container just yet,
wait until the focus is returned.
*/
if (!document.hasFocus()) {
window.addEventListener('focus', function focusReturn() {
/*
We want the listener to be triggered just once,
so we have it remove itself from the `focus` event.
*/
window.removeEventListener('focus', focusReturn);
/*
Test whether the active element
is within our container.
*/
if (!self.contains(document.activeElement)) {
hideSelf();
}
});
return;
}
if (!self.contains(e.relatedTarget)) {
hideSelf();
}
});