Как я могу обнаружить щелчок за пределами элемента? - PullRequest
2251 голосов
/ 30 сентября 2008

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

Возможно ли что-то подобное с jQuery?

$("#menuscontainer").clickOutsideThisElement(function() {
    // Hide the menus
});

Ответы [ 76 ]

8 голосов
/ 10 января 2011

Использование:

var go = false;
$(document).click(function(){
    if(go){
        $('#divID').hide();
        go = false;
    }
})

$("#divID").mouseover(function(){
    go = false;
});

$("#divID").mouseout(function (){
    go = true;
});

$("btnID").click( function(){
    if($("#divID:visible").length==1)
        $("#divID").hide(); // Toggle
    $("#divID").show();
});
8 голосов
/ 14 августа 2009

Если вы пишете сценарии для IE и FF 3. * и хотите просто узнать, произошел ли щелчок в определенной области окна, вы также можете использовать что-то вроде:

this.outsideElementClick = function(objEvent, objElement){   
var objCurrentElement = objEvent.target || objEvent.srcElement;
var blnInsideX = false;
var blnInsideY = false;

if (objCurrentElement.getBoundingClientRect().left >= objElement.getBoundingClientRect().left && objCurrentElement.getBoundingClientRect().right <= objElement.getBoundingClientRect().right)
    blnInsideX = true;

if (objCurrentElement.getBoundingClientRect().top >= objElement.getBoundingClientRect().top && objCurrentElement.getBoundingClientRect().bottom <= objElement.getBoundingClientRect().bottom)
    blnInsideY = true;

if (blnInsideX && blnInsideY)
    return false;
else
    return true;}
8 голосов
/ 05 июня 2013

Вместо использования прерывания потока, размытия / фокусировки или любой другой хитрой техники, просто сопоставьте поток событий с родством элемента:

$(document).on("click.menu-outside", function(event){
    // Test if target and it's parent aren't #menuscontainer
    // That means the click event occur on other branch of document tree
    if(!$(event.target).parents().andSelf().is("#menuscontainer")){
        // Click outisde #menuscontainer
        // Hide the menus (but test if menus aren't already hidden)
    }
});

Чтобы удалить щелчок вне прослушивателя событий, просто:

$(document).off("click.menu-outside");
6 голосов
/ 03 мая 2012

Подключите прослушиватель событий щелчка к документу. Внутри прослушивателя событий вы можете посмотреть на объект события , в частности, event.target , чтобы увидеть, какой элемент был нажат:

$(document).click(function(e){
    if ($(e.target).closest("#menuscontainer").length == 0) {
        // .closest can help you determine if the element 
        // or one of its ancestors is #menuscontainer
        console.log("hide");
    }
});
5 голосов
/ 20 сентября 2011
$(document).click(function() {
    $(".overlay-window").hide();
});
$(".overlay-window").click(function() {
    return false;
});

Если вы щелкнете по документу, скройте заданный элемент, если только вы не щелкнете по тому же элементу.

5 голосов
/ 26 июля 2015

Upvote для самого популярного ответа, но добавьте

&& (e.target != $('html').get(0)) // ignore the scrollbar

так, щелчок на полосе прокрутки не [скрывает или что-то еще] ваш целевой элемент.

5 голосов
/ 06 декабря 2011

Я сделал это так в YUI 3:

// Detect the click anywhere other than the overlay element to close it.
Y.one(document).on('click', function (e) {
    if (e.target.ancestor('#overlay') === null && e.target.get('id') != 'show' && overlay.get('visible') == true) {
        overlay.hide();
    }
});

Я проверяю, не является ли предок контейнером элемента виджета,
если целью не является то, что открыть виджет / элемент,
если виджет / элемент, который я хочу закрыть, уже открыт (не так уж важно).

5 голосов
/ 14 января 2018

Я использовал приведенный ниже скрипт и сделал с помощью jQuery.

jQuery(document).click(function(e) {
    var target = e.target; //target div recorded
    if (!jQuery(target).is('#tobehide') ) {
        jQuery(this).fadeOut(); //if the click element is not the above id will hide
    }
})

Ниже найдите код HTML

<div class="main-container">
<div> Hello I am the title</div>
<div class="tobehide">I will hide when you click outside of me</div>
</div>

Вы можете прочитать учебник здесь

5 голосов
/ 18 июля 2017

Если кому-то интересно, вот решение javascript (es6):

window.addEventListener('mouseup', e => {
        if (e.target != yourDiv && e.target.parentNode != yourDiv) {
            yourDiv.classList.remove('show-menu');
            //or yourDiv.style.display = 'none';
        }
    })

и es5, на всякий случай:

window.addEventListener('mouseup', function (e) {
if (e.target != yourDiv && e.target.parentNode != yourDiv) {
    yourDiv.classList.remove('show-menu'); 
    //or yourDiv.style.display = 'none';
}

});

5 голосов
/ 21 апреля 2016

Для более легкого использования и более выразительного кода я создал для этого плагин jQuery:

$('div.my-element').clickOut(function(target) { 
    //do something here... 
});

Примечание: target - это элемент, на который пользователь фактически нажал. Но обратный вызов все еще выполняется в контексте исходного элемента, поэтому вы можете использовать this , как и следовало ожидать в обратном вызове jQuery.

Plugin:

$.fn.clickOut = function (parent, fn) {
    var context = this;
    fn = (typeof parent === 'function') ? parent : fn;
    parent = (parent instanceof jQuery) ? parent : $(document);

    context.each(function () {
        var that = this;
        parent.on('click', function (e) {
            var clicked = $(e.target);
            if (!clicked.is(that) && !clicked.parents().is(that)) {
                if (typeof fn === 'function') {
                    fn.call(that, clicked);
                }
            }
        });

    });
    return context;
};

По умолчанию прослушиватель событий щелчка помещается в документ. Однако, если вы хотите ограничить область прослушивания событий, вы можете передать объект jQuery, представляющий родительский элемент уровня, который будет верхним родителем, на котором будут прослушиваться щелчки. Это предотвращает ненужные прослушиватели событий уровня документа. Очевидно, что это не будет работать, если предоставленный родительский элемент не является родителем вашего исходного элемента.

Используйте вот так:

$('div.my-element').clickOut($('div.my-parent'), function(target) { 
    //do something here...
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...