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

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

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

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

Ответы [ 76 ]

0 голосов
/ 29 октября 2014
$("body > div:not(#dvid)").click(function (e) {
    //your code
}); 
0 голосов
/ 28 января 2016

$('html').click(function() {
//Hide the menus if visible
});

$('#menucontainer').click(function(event){
    event.stopPropagation();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
 <button id='#menucontainer'>Ok</button> 
</html>
0 голосов
/ 11 апреля 2016

Подписаться фаза захвата клика для обработки клика по элементам, которые вызывают preventDefault.
Перезапустите его на элементе документа, используя другое имя click-anywhere.

document.addEventListener('click', function (event) {
  event = $.event.fix(event);
  event.type = 'click-anywhere';
  $document.trigger(event);
}, true);

Тогда, где вам нужно щелкнуть за пределами функциональности, подпишитесь на событие click-anywhere на document и проверьте, был ли щелчок за пределами интересующего вас элемента:

$(document).on('click-anywhere', function (event) {
  if (!$(event.target).closest('#smth').length) {
    // Do anything you need here
  }
});

Некоторые заметки:

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

  • Эта функция может быть включена в специальный плагин, который вызывает некоторый обратный вызов при внешнем щелчке.

  • Вы не можете подписаться на этап захвата, используя сам jQuery.

  • Вам не нужно загружать документ для подписки, поскольку подписка включена на document, даже не на body, поэтому она всегда существует независимо от размещения сценария и состояния загрузки.

0 голосов
/ 01 мая 2014

Это переключит меню Nav, когда вы нажимаете на элемент или выключаете его.

$(document).on('click', function(e) {
    var elem = $(e.target).closest('#menu'),
    box = $(e.target).closest('#nav');
 if (elem.length) {
    e.preventDefault();
    $('#nav').toggle();
  } else if (!box.length) {
    $('#nav').hide();
 }
});



<li id="menu"><a></a></li>
<ul id="nav" >  //Nav will toggle when you Click on Menu(it can be an icon in this example)
        <li class="page"><a>Page1</a></li>
        <li class="page"><a>Pag2</a></li>
        <li class="page"><a>Page3</a></li>            
        <li class="page"><a>Page4</a></li>
</ul>
0 голосов
/ 12 мая 2016
$(document).on('click.menu.hide', function(e){
  if ( !$(e.target).closest('#my_menu').length ) {
    $('#my_menu').find('ul').toggleClass('active', false);
  }
});

$(document).on('click.menu.show', '#my_menu li', function(e){
  $(this).find('ul').toggleClass('active');
});
div {
  float: left;
}

ul {
  padding: 0;
  position: relative;
}
ul li {
  padding: 5px 25px 5px 10px;
  border: 1px solid silver;
  cursor: pointer;
  list-style: none;
  margin-top: -1px;
  white-space: nowrap;
}
ul li ul:before {
  margin-right: -20px;
  position: absolute;
  top: -17px;
  right: 0;
  content: "\25BC";
}
ul li ul li {
  visibility: hidden;
  height: 0;
  padding-top: 0;
  padding-bottom: 0;
  border-width: 0 0 1px 0;
}
ul li ul li:last-child {
  border: none;
}
ul li ul.active:before {
  content: "\25B2";
}
ul li ul.active li {
  display: list-item;
  visibility: visible;
  height: inherit;
  padding: 5px 25px 5px 10px;
}
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div>
  <ul id="my_menu">
    <li>Menu 1
      <ul>
        <li>subMenu 1</li>
        <li>subMenu 2</li>
        <li>subMenu 3</li>
        <li>subMenu 4</li>
      </ul>
    </li>
    <li>Menu 2
      <ul>
        <li>subMenu 1</li>
        <li>subMenu 2</li>
        <li>subMenu 3</li>
        <li>subMenu 4</li>
      </ul>
    </li>
    <li>Menu 3</li>
    <li>Menu 4</li>
    <li>Menu 5</li>
    <li>Menu 6</li>
  </ul>
</div>

Вот версия jsbin http://jsbin.com/xopacadeni/edit?html,css,js,output

0 голосов
/ 14 декабря 2012

Просто предупреждение, что с помощью этого:

$('html').click(function() {
  // Hide the menus if visible
});

$('#menucontainer').click(function(event){
  event.stopPropagation();
});

Это препятствует нормальной работе драйвера Ruby on Rails UJS. Например, link_to 'click', '/url', :method => :delete не будет работать.

Это может быть обходной путь:

$('html').click(function() {
  // Hide the menus if visible
});

$('#menucontainer').click(function(event){
  if (!$(event.target).data('method')) {
    event.stopPropagation();
  }
});
0 голосов
/ 10 июня 2014

Стандартный HTML:

Окружите меню <label> и получите изменения состояния фокуса.

http://jsfiddle.net/bK3gL/

Плюс: вы можете развернуть меню с помощью Tab .

0 голосов
/ 13 марта 2014

Вы можете установить tabindex для элемента DOM . Это вызовет событие размытия, когда пользователь щелкнет за пределами элемента DOM.

Демо

<div tabindex="1">
    Focus me
</div>

document.querySelector("div").onblur = function(){
   console.log('clicked outside')
}
document.querySelector("div").onfocus = function(){
   console.log('clicked inside')
}
0 голосов
/ 09 декабря 2017

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

document.body.onclick = function() { undisp_menu(); };
var menu_on = 0;

function menu_trigger(event){

    if (menu_on == 0)
    {
        // otherwise u will call the undisp on body when 
        // click on the button
        event.stopPropagation(); 

        disp_menu();
    }

    else{
        undisp_menu();
    }

}


function disp_menu(){

    menu_on = 1;
    var e = document.getElementsByClassName("menu")[0];
    e.className = "menu on";

}

function undisp_menu(){

    menu_on = 0;
    var e = document.getElementsByClassName("menu")[0];
    e.className = "menu";

}

не забудьте это для кнопки

<div class="button" onclick="menu_trigger(event)">

<div class="menu">

и css:

.menu{
    display: none;
}

.on {
    display: inline-block;
}
0 голосов
/ 07 марта 2016

Попробуйте это:

$('html').click(function(e) {
  if($(e.target).parents('#menuscontainer').length == 0) {
    $('#menuscontainer').hide();
  }
});

https://jsfiddle.net/4cj4jxy0/

Но учтите, что это не может работать, если событие щелчка не достигает тега html. (Возможно, другие элементы имеют stopPropagation()).

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