У меня есть меню, которое открывает раздел подменю по щелчку (давайте назовем контейнер: «подменю»). Я хотел бы, чтобы «подменю» исчезло, если пользователь щелкнет за его пределами/на остальной части страницы.
Вроде решено на Как определить клик вне элемента? Но я не могу понять, как использовать фрагмент кода из второго по популярности ответа:
export function hideOnClickOutside(selector) {
const outsideClickListener = (event) => {
const $target = $(event.target);
if (!$target.closest(selector).length && $(selector).is(':visible')) {
$(selector).hide();
removeClickListener();
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
Не могли бы вы подсказать мне, как его использовать?
Я отредактировал и включил базовый пример. -> Я хочу, чтобы подменю также закрывалось при нажатии на «белое» пространство. Но не в родительском элементе «главного меню».
document.getElementById("main-menu").addEventListener("click", function() {bouttonexpand('sub-menu-class')});
function bouttonexpand(id) {
var elemeacacher = document.getElementsByClassName(id);
if (elemeacacher[0].style.display != "none"){
for(var y=0;y<elemeacacher.length;y++)
elemeacacher[y].style.display = "none";
}
else {
for(var y=0;y<elemeacacher.length;y++)
elemeacacher[y].style.display = "block";
}
}
#main-menu {
display:inline-block;
height:20px;
width:100px;
background: blue;
padding: 5%;
}
#sub-menu {
display:inline-block;
height:50px;
width:50px;
background: red;
display: none;
}
<div><div id = "main-menu">Main menu</div></div>
<div><div id = "sub-menu" class = "sub-menu-class">Sub menu</div></div>
Спасибо
Привет Крис, я добавил пример. Возможно, это был не самый подходящий код, я совсем новичок в кодировании :)
Пришлось немного изменить, но вот суть: jsfiddle.net/0j7p81sL
Спасибо ! Он действительно работает нормально. Однако я несколько раз читал, что .stopPropagation следует избегать
Я нашел эту статью по этому поводу, и я не собираюсь спорить с автором по поводу его общей точки зрения, но, на мой взгляд, статья является скорее рекомендацией разработчикам библиотек не использовать .stopPropagation(). Дело в том, что предложенный авторами способ справиться с этим не исправляет ошибку начальной загрузки, которую они представили ранее. Я согласен с тем, что вызывать его в обработчиках документов — плохая идея, но я не вижу абсолютно никаких проблем с вызовом его в обработчике кликов одного (пустого) элемента.
Используя jQuery, вы можете привязываться к событию щелчка документа и скрывать контейнер div, когда элемент, по которому щелкнули, не является самим контейнером или потомком элемента div.
var container = $("#sub-menu");
if (!container.is(event.target) && !container.has(event.target).length) {
container.hide();
}
Если вы хотите скрыть этот контейнер без проверки самого контейнера или потомка элемента div, просто удалите условие и просто используйте container.hide();
.
Кроме того, вместо того, чтобы устанавливать display: none;
на sub-menu
в CSS, установите его вручную, чтобы вы могли переключать sub-menu
с самого первого щелчка.
Взгляните на фрагмент ниже:
var x = document.getElementById("sub-menu");
x.style.display = "none";
$(document).click(function (evt) {
if ($(evt.target).is('#main-menu')) { // control click event if it's main-menu
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
else {
var container = $("#sub-menu");
if (!container.is(event.target) && !container.has(event.target).length) { // if you don't want that remove the condition and write container.hide(); only
container.hide();
}
}
});
#main-menu {
display: inline-block;
height: 20px;
width: 100px;
background: blue;
padding: 5%;
}
#sub-menu {
display: inline-block;
height: 50px;
width: 50px;
background: red;
}
<script src = "https://code.jquery.com/jquery-3.5.1.min.js"
integrity = "sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0 = " crossorigin = "anonymous"></script>
<div id = "main-menu">Main menu</div>
<div id = "sub-menu" class = "sub-menu-class">Sub menu</div>
Отличный ответ, он решил это! И вы правы насчет дисплея: никому не нужен.
@Нага, с удовольствием.
Зачем удалять прослушиватель кликов? Также, пожалуйста, создайте минимальный воспроизводимый пример.