Как закрывать выпадающее меню при клике вне его самого?

Есть такое меню:
71d22695879f4ad29dadecca13775dc1.png

Все хорошо сделал открывается, но вот проблема, как сделать чтобы если клик вне меню то окно закрывалось, а когда внутри то ничего не происходило ?

сделал

document. body. addEventListener ('click', closeAll, false);

И тут проверяю открыто ли окно, если да закрываю, если нет иду дальше
и так все выпадающие меню...


Но проблема в том, что клик даже внутри списка по "Пункт 1/2" Приводит к закрыванию всех выпадающих списков, (открыт может быть только 1, если нажал на 2, то первый закроется)

Как быть, помогите пожалуйста?

Менял местами евенты (обработку и повеску event'ov)
все также..
  • Вопрос задан
  • 11659 просмотров
Решения вопроса 2
erniesto77
@erniesto77
oop, rb, py, php, js
function clickOutside (el) {
	$(document).on('click', function(event) {
		event.stopPropagation();
		if ($(event.target).is(el)) return;

		console.log('Клик мимо меня');
	});
}

upd:

function clickOutside (selector) {
	document.addEventListener('click', function (event) {
		event.stopPropagation();
		var el = document.querySelector(selector);
		if (event.target === el) return;

		console.log('Не попал =)');
	});
}

upd:

function findParentBySelector(elm, selector) {
    var all = document.querySelectorAll(selector);
    var cur = elm.parentNode;
    while(cur && !collectionHas(all, cur)) {
        cur = cur.parentNode;
    }
    return cur;
}

function clickOutside (selector) {
	document.addEventListener('click', function (event) {
		event.stopPropagation();
		var el = document.querySelector(selector);
		if (event.target == el) return;

    // Проверка на то что это дочерний элемент
    if (event.target == findParentBySelector(selector)) return;

		console.log('Не попал =)');
	});
}
Ответ написан
Основная идея: у класса event в javascript есть свойство target. Он содержит ссылку на тот DOM элемент, на котором этот event произошел. В таких случаях как у вас, можно проверять значение этого свойства прежде чем выполнять какие-то действия.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@everdimension
Использовать e.stopPropagation() — плохая идея. Читайте

Правильный способ — проверять, является ли target сделанного клика элементом меню или чем-то другим. Если это не меню — закрывать меню.

Появляется правильный вопрос, что делать, если кликнутый элемент — дочерний элемент меню? Для этого есть офигенный метод node.contains()

Собственно, вся требуемая проверка получается совсем несложная — gist
var el = document.getElementById('el');

document.addEventListener('click', outsideEvtListener);

function outsideEvtListener(evt) {
    if (evt.target === el || el.contains(evt.target)) {
        // клик внутри
        return;
    }
    // код для закрытия меню, например el.classList.add('hidden')
   
    // не забыть убрать слушатель событий (не для каждой имплементации требуется)
    document.removeEventListener(outsideEvtListener);
}
Ответ написан
svistiboshka
@svistiboshka
живые веб интерфейсы
на onclick в меню повесить обработчик event.preventDefault()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы