2009-07-06 25 views
48

Tengo un menú desplegable. Ahora, cuando se baja a varios niveles, me gustaría agregar un tiempo de espera de 2 segundos, antes de que desaparezca, para que el usuario pueda volver a entrar, cuando rompe el .hover() por error.¿Cómo decirle a .hover() que espere?

¿Es posible?

mi código para la diapositiva:

$('.icon').hover(function() { 
     $('li.icon > ul').slideDown('fast'); 
    }, function() { 
     $('li.icon > ul').slideUp('fast'); 
    }); 

Respuesta

74

Esto hará que la segunda función espere 2 segundos (2000 milisegundos) antes de ejecutar:

$('.icon').hover(function() { 
    clearTimeout($(this).data('timeout')); 
    $('li.icon > ul').slideDown('fast'); 
}, function() { 
    var t = setTimeout(function() { 
     $('li.icon > ul').slideUp('fast'); 
    }, 2000); 
    $(this).data('timeout', t); 
}); 

También borra el tiempo de espera cuando el usuario se desplaza hacia atrás para evitar el comportamiento loco

Sin embargo, esta no es una forma muy elegante de hacer esto. Probablemente deberías consultar el plugin hoverIntent, que está diseñado para resolver este problema en particular.

+0

$ (this) .data? ¡Parece que tengo algo que leer! –

+8

+1 por hoverIntent! – alex

+0

Esta debería ser la primera respuesta. – Ronan

1

La idea general es utilizar setTimeout, así:

$('.icon').hover(function() { 
      $('li.icon > ul').slideDown('fast'); 
    }, function() { 
      setTimeout(function() { 
       $('li.icon > ul').slideUp('fast'); 
      }, 2000); 
    }); 

Pero esto puede hacer cosas contrarias a la intuición si el usuario desplaza el ratón y luego desplaza el ratón de nuevo rápidamente, esto no cuenta para despejar el tiempo de espera cuando el usuario pasa sobre él de nuevo. Eso requeriría un estado adicional.

42

personalmente me gusta el "hoverIntent" plugin:

http://cherne.net/brian/resources/jquery.hoverIntent.html

de la página: hoverIntent es un plugin que intenta determinar la intención del usuario ... como una bola de cristal, solamente con el ratón ¡movimiento! Funciona como (y se derivó de) el vuelo estacionario integrado de jQuery. Sin embargo, en lugar de llamar inmediatamente a la función onMouseOver, espera hasta que el mouse del usuario se desacelere lo suficiente antes de realizar la llamada.

¿Por qué? Para retrasar o evitar el disparo accidental de animaciones o llamadas ajax. Los tiempos de espera simples funcionan para áreas pequeñas, pero si su área objetivo es grande, puede ejecutarse independientemente de la intención.

var config = {  
sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)  
interval: 200, // number = milliseconds for onMouseOver polling interval  
over: makeTall, // function = onMouseOver callback (REQUIRED)  
timeout: 500, // number = milliseconds delay before onMouseOut  
out: makeShort // function = onMouseOut callback (REQUIRED) 
}; 
$("#demo3 li").hoverIntent(config) 

Opciones de configuración

sensibilidad: Si el ratón viaja menos de este número de píxeles entre los intervalos de sondeo, entonces la función "sobre" se llamará. Con el umbral de sensibilidad mínimo de 1, el mouse no debe moverse entre los intervalos de sondeo. Con umbrales de sensibilidad más altos, es más probable que reciba un falso positivo. Sensibilidad predeterminada: 7

intervalo: El número de milisegundos transcurren entre la lectura/comparación de las coordenadas del mouse. Cuando el mouse del usuario ingresa primero al elemento, se registran sus coordenadas. Lo más pronto que se puede llamar a la función "sobre" es después de un único intervalo de sondeo. Establecer el intervalo de sondeo más alto aumentará la demora antes de la primera posible "sobre" llamada, pero también aumenta el tiempo hasta el próximo punto de comparación. Intervalo predeterminado: 100

sobre: ​​ Requerido.La función a la que desea llamar en MooOver. Su función recibe los mismos objetos "este" y "evento" que de jQuery.

tiempo de espera: Un simple retraso, en milisegundos, antes de llamar a la función "salir". Si el usuario retrocede el elemento antes de que expire el tiempo de espera, no se llamará a la función "out" (ni se llamará a la función "over"). Esto es principalmente para proteger contra las trayectorias de mouse descuidado/humano que temporalmente (y sin querer) sacar al usuario del elemento objetivo ... dándoles tiempo para regresar. Tiempo de espera predeterminado: 0

out: Requerido. La función a la que le gustaría llamar en MoverOut. Su función recibe los mismos objetos "este" y "evento" que de jQuery. Nota, hoverIntent solo llamará a la función "salir" si se ha llamado a la función "sobre" en la misma ejecución.

+0

Lo usé por muchos años hasta que me di cuenta de que era una ** exageración ** para casos como la pregunta. Los ejemplos de código manual en este hilo funcionan bien. –

1
$('.icon').on("mouseenter mouseleave","li.icon > ul",function(e){ 
    var $this = $(this); 
    if (e.type === 'mouseenter') { 
     clearTimeout($this.data('timeout')); 
     $this.slideDown('fast'); 
    }else{ // is mouseleave: 
     $this.data('timeout', setTimeout(function(){ 
      $this.slideUp('fast'); 
     },2000)); 
    } 
}); 
1

A continuación se detendrá el deslizamiento de activación de 2 segundos:

$('.icon').hover(function() { 
    $('li.icon > ul').delay(2000).slideDown('fast'); 
}, function() { 
    $('li.icon > ul').slideUp('fast'); 
}); 
+0

Creo que esto logra básicamente lo contrario: la acción de estacionario no se activa de inmediato, pero es necesario alternar durante al menos 2 segundos para que ocurra cualquier cosa. Sigue siendo útil, pero no es exactamente una respuesta a la pregunta. ¿Me equivoco? –

0

Creo que este es el código de su necesidad:

jQuery(document).ready(function($) { 
    var navTimers = []; 
    $('.icon').hover(function() { 
      var id = jQuery.data(this); 
      var $this = $(this); 
      navTimers[id] = setTimeout(function() { 
       $this.children('ul').slideDown('fast'); 
       navTimers[id] = ""; 
      }, 300); 
     }, 
     function() { 
      var id = jQuery.data(this); 
      if (navTimers[id] != "") { 
       clearTimeout(navTimers[id]); 
      } else { 
       $(this).children("ul").slideUp('fast'); 
      } 
     } 
    ); 
}); 
0

o simplemente podría utilizar transición: todos 2s facilidad de entrada y salida. asegúrese de agregar -webkit, -moz y -o para diferentes navegadores.

0

me gustaría añadir a Paolo Bergantino que se puede hacer esto sin la attribut datos:

var timer; 
$('.icon').hover(function() { 
    clearTimeout(timer); 
    $('li.icon > ul').slideDown('fast'); 
}, function() { 
    timer = setTimeout(function() { 
     $('li.icon > ul').slideUp('fast'); 
    }, 2000); 
}); 
0
var timer; 

var delay = 200; 

$('#hoverelement').hover(function() { 

    on mouse hover, start a timeout 

    timer = setTimeout(function() { 

     Do your stuff here 

    }, delay); 

}, function() { 

    Do mouse leaving function stuff here  

    clearTimeout(timer); 
}); 

// editar: Código instert

Cuestiones relacionadas