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

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

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

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

Ответы [ 76 ]

4 голосов
/ 03 ноября 2017

Вот простое решение с помощью чистого JavaScript. Это актуально с ES6 :

var isMenuClick = false;
var menu = document.getElementById('menuscontainer');
document.addEventListener('click',()=>{
    if(!isMenuClick){
       //Hide the menu here
    }
    //Reset isMenuClick 
    isMenuClick = false;
})
menu.addEventListener('click',()=>{
    isMenuClick = true;
})
4 голосов
/ 31 мая 2013

Решения здесь работают отлично , когда нужно управлять только одним элементом . Однако, если есть несколько элементов, проблема намного сложнее. Трюки с e.stopPropagation () и всеми остальными не будут работать.

Я придумал решение , и, возможно, это не так просто, но лучше, чем ничего. Посмотрите:

$view.on("click", function(e) {

    if(model.isActivated()) return;

        var watchUnclick = function() {
            rootView.one("mouseleave", function() {
                $(document).one("click", function() {
                    model.deactivate();
                });
                rootView.one("mouseenter", function() {
                    watchUnclick();
                });
            });
        };
        watchUnclick();
        model.activate();
    });
4 голосов
/ 27 июля 2017

Вот что я делаю, чтобы решить проблему.

$(window).click(function (event) {
    //To improve performance add a checklike 
    //if(myElement.isClosed) return;
    var isClickedElementChildOfMyBox = isChildOfElement(event,'#id-of-my-element');

    if (isClickedElementChildOfMyBox)
        return;

    //your code to hide the element 
});

var isChildOfElement = function (event, selector) {
    if (event.originalEvent.path) {
        return event.originalEvent.path[0].closest(selector) !== null;
    }

    return event.originalEvent.originalTarget.closest(selector) !== null;
}
4 голосов
/ 12 января 2013

Это должно работать:

$('body').click(function (event) {
    var obj = $(event.target);
    obj = obj['context']; // context : clicked element inside body
    if ($(obj).attr('id') != "menuscontainer" && $('#menuscontainer').is(':visible') == true) {
        //hide menu
    }
});
4 голосов
/ 08 июля 2015

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

// HIDE SEARCH BOX IF CLICKING OUTSIDE
$(document).click(function(event){ 
    // IF NOT CLICKING THE SEARCH BOX OR ITS CONTENTS OR SEARCH ICON 
    if ($("#search-holder").is(":visible") && !$(event.target).is("#search-holder *, #search")) {
        $("#search-holder").fadeOut('fast');
        $("#search").removeClass('active');
    }
});

Он проверяет, является ли поле поиска уже видимым в первую очередь, и в нашем случае он также удаляет активный класс на кнопке поиска скрытия / отображения.

4 голосов
/ 17 июня 2010

Функция:

$(function() {
    $.fn.click_inout = function(clickin_handler, clickout_handler) {
        var item = this;
        var is_me = false;
        item.click(function(event) {
            clickin_handler(event);
            is_me = true;
        });
        $(document).click(function(event) {
            if (is_me) {
                is_me = false;
            } else {
                clickout_handler(event);
            }
        });
        return this;
    }
});

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

this.input = $('<input>')
    .click_inout(
        function(event) { me.ShowTree(event); },
        function() { me.Hide(); }
    )
    .appendTo(this.node);

А функции очень просты:

ShowTree: function(event) {
    this.data_span.show();
}
Hide: function() {
    this.data_span.hide();
}
4 голосов
/ 21 марта 2012

Это моё решение этой проблемы:

$(document).ready(function() {
  $('#user-toggle').click(function(e) {
    $('#user-nav').toggle();
    e.stopPropagation();
  });

  $('body').click(function() {
    $('#user-nav').hide(); 
  });

  $('#user-nav').click(function(e){
    e.stopPropagation();
  });
});
4 голосов
/ 19 ноября 2013

Я закончил тем, что делал что-то вроде этого:

$(document).on('click', 'body, #msg_count_results .close',function() {
    $(document).find('#msg_count_results').remove();
});
$(document).on('click','#msg_count_results',function(e) {
    e.preventDefault();
    return false;
});

У меня есть кнопка закрытия в новом контейнере для удобного пользовательского интерфейса. Мне пришлось использовать return false, чтобы не пройти. Конечно, было бы неплохо иметь A HREF, чтобы отвезти вас куда-нибудь, или вы могли бы вместо этого назвать некоторые вещи ajax. В любом случае, у меня все в порядке. Как раз то, что я хотел.

3 голосов
/ 09 февраля 2017

Я знаю, что есть миллион ответов на этот вопрос, но я всегда был поклонником использования HTML и CSS для выполнения большей части работы. В этом случае z-index и позиционирование. Я нашел самый простой способ сделать это следующим образом:

$("#show-trigger").click(function(){
  $("#element").animate({width: 'toggle'});
  $("#outside-element").show();
});
$("#outside-element").click(function(){
  $("#element").hide();
  $("#outside-element").hide();
});
#outside-element {
  position:fixed;
  width:100%;
  height:100%;
  z-index:1;
  display:none;
}
#element {
  display:none;
  padding:20px;
  background-color:#ccc;
  width:300px;
  z-index:2;
  position:relative;
}
#show-trigger {
  padding:20px;
  background-color:#ccc;
  margin:20px auto;
  z-index:2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="outside-element"></div>
<div id="element">
  <div class="menu-item"><a href="#1">Menu Item 1</a></div>
  <div class="menu-item"><a href="#2">Menu Item 1</a></div>
  <div class="menu-item"><a href="#3">Menu Item 1</a></div>
  <div class="menu-item"><a href="#4">Menu Item 1</a></div>
</div>
<div id="show-trigger">Show Menu</div>

Это создает безопасную среду, поскольку ничего не сработает, если только меню действительно не открыто, а z-индекс не защищает любое содержимое внутри элемента от создания пропусков зажигания при нажатии.

Кроме того, вы не требуете, чтобы jQuery покрывал все ваши базы вызовами распространения, а также очищал все внутренние элементы от пропусков зажигания.

3 голосов
/ 25 февраля 2017
$(document).on("click",function (event)   
 {   
     console.log(event);
   if ($(event.target).closest('.element').length == 0)
     {
    //your code here
      if ($(".element").hasClass("active"))
      {
        $(".element").removeClass("active");
      }
     }
 });

Попробуйте эту кодировку для получения решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...