Набросок небольшого скипта для отслеживания нажатия на другой элемент на нативном javascript.
Например, нам нужно скрыть меню или закрыть диалоговое окно, когда пользователь нажимает на "свободное место".
Если сразу перейти к сути, но нам нужно проверить, что нажали не на наш блок или не на его содержимое:
const elBlock = document.getElementById(selectorBlock);
const clickListener = (event) => {
const target = event.target;
if ( (target !== elBlock) && (!elBlock.contains(target)) ) {
doClose();
}
}
Сприпт ниже также тажке запрещает добавление нескольких событий к одному элементу.
Демонстрация результата:
Title
X
HTML каркас:
<button id="btnClickMe">Click me</button>
<div id="dialog" class="dialog hidden">
<h2 class="dialog__title">Title</h2>
<div id="btnDialogClose" class="dialog__close">X</div>
<div class="dialog__controls">
<button>Do nothing 1</button>
<button>Do nothing 2</button>
</div>
</div>
Основной java script код:
const sHideClass = "hidden";
const sDialog = "dialog";
const sDialogClose = "btnDialogClose";
const btnClickMe = document.getElementById("btnClickMe");
function hideOnClickOutside(selectorBlock, selectorTrigger, selectorBtnClose) {
const sBlocker = "_ListenerSet";
const elBlock = document.getElementById(selectorBlock);
if ( !(sBlocker in elBlock.dataset)) {
elBlock.dataset.__blListenerSet = "set";
const elBtnClose = document.getElementById(selectorBtnClose);
elBlock.classList.remove(sHideClass);
const clickListener = (event) => {
const target = event.target;
if ( (target !== elBlock) && (!elBlock.contains(target)) ) {
doClose();
}
};
const doClose = () => {
elBlock.classList.add(sHideClass);
delete (elBlock.dataset.sBlocker);
document.removeEventListener('click', clickListener);
};
elBtnClose.addEventListener('click', doClose);
document.addEventListener('click', clickListener);
}
}
btnClickMe.addEventListener("click", (event) => {
event.stopPropagation();
hideOnClickOutside(sDialog, btnClickMe, sDialogClose);
});
И немного стилей:
.dialog {
border-radius: 10px;
border: 1px aqua solid;
padding: 20px;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-100%, -100%);
}
.dialog__close {
position: absolute;
top: 5px;
right: 5px;
cursor: pointer;
padding: 10px;
}
.hidden {
display: none;
}