event - jquery item clicked
Haga clic en el menĂº exterior para cerrar en jquery (14)
2 opciones que puedes investigar:
- Al mostrar el menú, coloque un gran DIV vacío detrás de él cubriendo el resto de la página y dé un evento de clic para cerrar el menú (y él mismo). Esto es similar a los métodos utilizados con cajas de luz donde al hacer clic en el fondo se cierra la caja de luz
- Al mostrar el menú, adjunte un controlador de evento de clic por única vez en el cuerpo que cierra el menú. Usas ''.one ()'' de jQuery para esto.
Entonces tengo un menú desplegable que se muestra con un clic, según los requisitos del negocio. El menú se vuelve a ocultar después de alejar el mouse de él.
Pero ahora me piden que permanezca en su lugar hasta que el usuario haga clic en cualquier parte del documento. ¿Cómo se puede lograr esto?
Esta es una versión simplificada de lo que tengo ahora:
$(document).ready(function() {
$("ul.opMenu li").click(function(){
$(''#MainOptSubMenu'',this).css(''visibility'', ''visible'');
});
$("ul.opMenu li").mouseleave(function(){
$(''#MainOptSubMenu'',this).css(''visibility'', ''hidden'');
});
});
<ul class="opMenu">
<li id="footwo" class="">
<span id="optImg" style="display: inline-block;"> <img src="http://localhost.vmsinfo.com:8002/insight/images/options-hover2.gif"/> </span>
<ul id="MainOptSubMenu" style="visibility: hidden; top: 25px; border-top: 0px solid rgb(217, 228, 250); background-color: rgb(217, 228, 250); padding-bottom: 15px;">
<li>some</li>
<li>nav</li>
<li>links</li>
</ul>
</li>
</ul>
Intenté algo como esto $(''document[id!=MainOptSubMenu]'').click(function()
pensando que se activaría en cualquier cosa que no fuera el menú, pero no funcionó.
Creo que necesitas algo como esto: http://jsfiddle.net/BeenYoung/BXaqW/3/
$(document).ready(function() {
$("ul.opMenu li").each(function(){
$(this).click(function(){
if($(this).hasClass(''opened'')==false){
$(''.opMenu'').find(''.opened'').removeClass(''opened'').find(''ul'').slideUp();
$(this).addClass(''opened'');
$(this).find("ul").slideDown();
}else{
$(this).removeClass(''opened'');
$(this).find("ul").slideUp();
}
});
});
});
¡Espero que sea útil para ti!
Eche un vistazo al enfoque que utilizó esta pregunta:
¿Cómo puedo detectar un clic fuera de un elemento?
Adjunte un evento de clic al cuerpo del documento que cierra la ventana. Adjunte un evento de clic separado a la ventana que detiene la propagación al cuerpo del documento.
$(''html'').click(function() {
//Hide the menus if visible
});
$(''#menucontainer'').click(function(event){
event.stopPropagation();
});
Encontré una variante de la solución de Grsmto y la solución de Dennis solucionó mi problema.
$(".MainNavContainer").click(function (event) {
//event.preventDefault(); // Might cause problems depending on implementation
event.stopPropagation();
$(document).one(''click'', function (e) {
if(!$(e.target).is(''.MainNavContainer'')) {
// code to hide menus
}
});
});
Encuentro más útil usar mousedown-event en lugar de click-event. El evento click no funciona si el usuario hace clic en otros elementos en la página con click-events. En combinación con el método one () de jQuery se ve así:
$("ul.opMenu li").click(function(event){
//event.stopPropagation(); not required any more
$(''#MainOptSubMenu'').show();
// add one mousedown event to html
$(''html'').one(''mousedown'', function(){
$(''#MainOptSubMenu'').hide();
});
});
// mousedown must not be triggered inside menu
$("ul.opMenu li").bind(''mousedown'', function(evt){
evt.stopPropagation();
});
La respuesta es correcta, pero agregará un oyente que se activará cada vez que se produzca un clic en su página. Para evitar eso, puede agregar el oyente por una sola vez:
$(''a#menu-link'').on(''click'', function(e) {
e.preventDefault();
e.stopPropagation();
$(''#menu'').toggleClass(''open'');
$(document).one(''click'', function closeMenu (e){
if($(''#menu'').has(e.target).length === 0){
$(''#menu'').removeClass(''open'');
} else {
$(document).one(''click'', closeMenu);
}
});
});
Editar: si quiere evitar el stopPropagation()
en el botón inicial puede usar esto
var $menu = $(''#menu'');
$(''a#menu-link'').on(''click'', function(e) {
e.preventDefault();
if (!$menu.hasClass(''active'')) {
$menu.addClass(''active'');
$(document).one(''click'', function closeTooltip(e) {
if ($menu.has(e.target).length === 0 && $(''a#menu-link'').has(e.target).length === 0) {
$menu.removeClass(''active'');
} else if ($menu.hasClass(''active'')) {
$(document).one(''click'', closeTooltip);
}
});
} else {
$menu.removeClass(''active'');
}
});
Las opciones de stopPropagation son malas porque pueden interferir con otros manejadores de eventos, incluidos otros menús que podrían haber unido manipuladores cercanos al elemento html.
Aquí hay una solución simple basada en la respuesta del usuario2989143:
$("html").click(function(event) {
if ($(event.target).closest(''#menu-container, #menu-activator'').length === 0) {
$(''#menu-container'').hide();
}
});
Recientemente me he enfrentado al mismo problema. Escribí el siguiente código:
$(''html'').click(function(e) {
var a = e.target;
if ($(a).parents(''.menu_container'').length === 0) {
$(''.ofSubLevelLinks'').removeClass(''active''); //hide menu item
$(''.menu_container li > img'').hide(); //hide dropdown image, if any
}
});
Me ha funcionado a la perfección.
Si usar un complemento está bien en tu caso, entonces te sugiero el complemento clickoutside de Ben Alman que se encuentra here :
su uso es tan simple como esto:
$(''#menu'').bind(''clickoutside'', function (event) {
$(this).hide();
});
espero que esto ayude.
Use el selector '': visible''. Donde .menuitem es el / los elemento (s) oculto (s) ...
$(''body'').click(function(){
$(''.menuitem:visible'').hide(''fast'');
});
O si ya tiene el elemento .menuitem en una var ...
var menitems = $(''.menuitem'');
$(''body'').click(function(){
menuitems.filter('':visible'').hide(''fast'');
});
Utilizo esta solución con múltiples elementos con el mismo comportamiento en la misma página:
$("html").click(function(event){
var otarget = $(event.target);
if (!otarget.parents(''#id_of element'').length && otarget.attr(''id'')!="id_of element" && !otarget.parents(''#id_of_activator'').length) {
$(''#id_of element'').hide();
}
});
stopPropagation () es una mala idea, esto rompe el comportamiento estándar de muchas cosas, incluidos botones y enlaces.
incluso encontré la misma situación y uno de mis mentores me explicó esta idea.
paso: 1 cuando se hace clic en el botón en el que debemos mostrar el menú desplegable. luego agregue el siguiente nombre de clase "more_wrap_background" a la página activa actual como se muestra a continuación
$(''.ui-page-active'').append("<div class=''more_wrap_background'' id=''more-wrap-bg''> </div>");
paso 2, luego agrega un clic para la etiqueta div como
$(document).on(''click'', ''#more-wrap-bg'', hideDropDown);
donde hideDropDown es la función que se llamará para ocultar el menú desplegable
El paso 3 e importante mientras ocultas el menú desplegable es que eliminas esa clase que agregaste anteriormente como
$(''#more-wrap-bg'').remove();
Estoy eliminando mediante el uso de su id en el código anterior
.more_wrap_background {
top: 0;
padding: 0;
margin: 0;
background: rgba(0, 0, 0, 0.1);
position: fixed;
display: block;
width: 100% !important;
z-index: 999;//should be one less than the drop down menu''s z-index
height: 100% !important;
}
que tal esto?
$(this).mouseleave(function(){
var thisUI = $(this);
$(''html'').click(function(){
thisUI.hide();
$(''html'').unbind(''click'');
});
});
$("html").click( onOutsideClick );
onOutsideClick = function( e )
{
var t = $( e.target );
if ( !(
t.is("#mymenu" ) || //Where #mymenu - is a div container of your menu
t.parents( "#mymenu" ).length > 0
) )
{
//TODO: hide your menu
}
};
Y es mejor configurar el oyente solo cuando el menú esté visible y siempre eliminar el oyente después de que el menú se oculte.