29

Как обнаружить клик вне элемента?

17

Описание проблемы

У меня есть несколько HTML-меню, которые полностью отображаются, когда пользователь кликает по заголовку этих меню. Я хотел бы скрыть эти элементы, когда пользователь кликает вне области меню.

Возможно ли реализовать что-то подобное с помощью jQuery?

$("#menuscontainer").clickOutsideThisElement(function() {
    // Скрыть меню
});

Буду признателен за любые советы или примеры кода!

4 ответ(ов)

1

Другие решения здесь не сработали для меня, поэтому мне пришлось использовать следующий код:

if(!$(event.target).is('#foo')) {
    // скрыть меню
}

Редактирование: Вариант на чистом JavaScript (2021-03-31)

Я использовал этот метод для закрытия выпадающего меню при клике вне его.

Сначала я создал уникальное имя класса для всех элементов компонента. Это имя класса будет добавлено ко всем элементам, которые составляют виджет меню.

const className = `dropdown-${Date.now()}-${Math.random() * 100}`;

Затем я создал функцию для проверки кликов и имени класса элемента, по которому кликнули. Если элемент, по которому кликнули, не содержит сгенерированное имя класса, я установлю флаг show в значение false, и меню закроется.

const onClickOutside = (e) => {
    if (!e.target.className.includes(className)) {
        show = false;
    }
};

После этого я прикрепил обработчик кликов к объекту окна.

// добавьте при загрузке виджета
window.addEventListener("click", onClickOutside);

... и наконец, немного housekeeping

// удалите слушатель при уничтожении виджета
window.removeEventListener("click", onClickOutside);
0

После исследования я нашел три работающих решения.

Первое решение

<script>
    //Преимущество этого решения в том, что оно не останавливает распространение события.

    var clickFlag = 0;
    $('body').on('click', function () {
        if(clickFlag == 0) {
            console.log('скрыть элемент здесь');
            /* Скрыть элемент здесь */
        } else {
            clickFlag = 0;
        }
    });
    $('body').on('click', '#testDiv', function (event) {
        clickFlag = 1;
        console.log('показать элемент');
        /* Показать элемент */
    });
</script>

Второе решение

<script>
    $('body').on('click', function(e) {
        if($(e.target).closest('#testDiv').length == 0) {
           /* Скрыть выпадающий список здесь */
        }
    });
</script>

Третье решение

<script>
    var specifiedElement = document.getElementById('testDiv');
    document.addEventListener('click', function(event) {
        var isClickInside = specifiedElement.contains(event.target);
        if (isClickInside) {
          console.log('Вы кликнули внутри')
        } else {
          console.log('Вы кликнули вне')
        }
    });
</script>

Каждое из этих решений имеет свои особенности, и вы можете выбрать то, которое лучше всего подходит для вашей ситуации.

0

Ваш код выглядит правильно, и он выполняет следующие действия: при клике на элемент с идентификатором menuscontainer, он получает фокус, а при потере фокуса этот элемент скрывается. Если у вас есть какие-то проблемы с его работой, убедитесь, что jQuery подключен и что элемент #menuscontainer действительно существует на странице. Можно также проверить, не конфликтуют ли другие обработчики событий с вашим кодом. В целом, ваш код работает отлично.

0

Простое решение для данной ситуации выглядит следующим образом:

$(document).mouseup(function (e)
{
    var container = $("ВАШ СЕЛЕКТОР"); // Укажите ваш класс или ID
    
    if (!container.is(e.target) &&            // Если элемент, по которому кликнули, не является нужным div или секцией
        container.has(e.target).length === 0) // ... и не является дочерним элементом контейнера
    {
        container.hide();
    }
});

Этот скрипт скрывает div, если клик происходит вне него.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь