¿Retrasar el evento de desplazamiento de jquery?

93

Me gustaría retrasar un evento de desplazamiento en jquery. Estoy leyendo de un archivo cuando el usuario se desplaza sobre un enlace o etiqueta. No quiero que este evento ocurra inmediatamente en caso de que el usuario simplemente mueva el mouse por la pantalla. ¿Hay alguna forma de retrasar el disparo del evento?

Gracias.

Código de ejemplo:

$(function() {
    $('#container a').hover(function() {
        $('<div id="fileinfo" />').load('ReadTextFileX.aspx',
            {filename:'file.txt'},
            function() {
                $(this).appendTo('#info');
            }
         );
    },
        function() { $('#info').remove(); }
    });
});

ACTUALIZACIÓN: (14/1/09) Después de agregar el complemento HoverIntent, el código anterior se cambió al siguiente para implementarlo. Muy sencillo de implementar.

$(function() {
    hiConfig = {
        sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)
        interval: 200, // number = milliseconds for onMouseOver polling interval
        timeout: 200, // number = milliseconds delay before onMouseOut
        over: function() {
            $('<div id="fileinfo" />').load('ReadTextFileX.aspx', {filename:'file.txt'},
                function() {
                   $(this).appendTo('#info');
                }
             );
        }, // function = onMouseOver callback (REQUIRED)
        out: function() { $('#info').remove();  } // function = onMouseOut callback (REQUIRED)
    }
    $('#container a').hoverIntent(hiConfig)
}
Brettski
fuente
1
Gracias por proporcionar el uso de hoverIntent
JavaKungFu

Respuestas:

91

Utilice el complemento hoverIntent para jquery: http://cherne.net/brian/resources/jquery.hoverIntent.html

Es absolutamente perfecto para lo que describe y lo he usado en casi todos los proyectos que requerían la activación del mouse sobre los menús, etc.

Hay un problema en este enfoque, algunas interfaces carecen de un estado de 'desplazamiento', por ejemplo. navegadores móviles como safari en el iphone. Es posible que esté ocultando una parte importante de la interfaz o navegación sin forma de abrirla en un dispositivo de este tipo. Puede solucionar esto con CSS específico del dispositivo.

roborourke
fuente
O este complemento también funciona como un encanto github.com/john-terenzio/jQuery-Hover-Delay
mica
50

Debes verificar un temporizador al pasar el mouse. Si no existe (es decir, este es el primer hover), créelo. Si existe (es decir, este no es el primer hover), mátelo y reinícielo. Establezca la carga útil del temporizador en su código.

$(function() {
    var timer;

    $('#container a').hover(function() {
        if(timer) {
            clearTimeout(timer);
            timer = null
        }
        timer = setTimeout(function() {
            $('<div id="fileinfo" />').load('ReadTextFileX.aspx',
                {filename:'file.txt'},
                function() {
                    $(this).appendTo('#info');
                }
            );
        }, 500)
    },
    // mouse out
    });
});

Apuesto a que jQuery tiene una función que resuelve todo esto para ti.

Editar : Ah, sí, el complemento jQuery al rescate

Creciente fresco
fuente
9
¡Gracias de todos modos por una solución sin complementos!
Jrgns
4
Agregué un clearTimeout (temporizador); temporizador = nulo; en el lado del mouseout, pero eso funcionó perfectamente y evitó YAP (otro complemento)
Andiih
@Andiih Excelente llamada y gracias por presentarme el acrónimo "YAP".
Jon
probablemente te refieres a debounce ()
Vitim.us
11

Estoy totalmente de acuerdo en que hoverIntent es la mejor solución, pero si eres un desgraciado que trabaja en un sitio web con un proceso largo y prolongado para la aprobación de los complementos de jQuery, aquí tienes una solución rápida y sucia que funcionó bien para mí:

$('li.contracted').hover(function () {
    var expanding = $(this);
    var timer = window.setTimeout(function () {
        expanding.data('timerid', null);

            ... do stuff

    }, 300);
    //store ID of newly created timer in DOM object
    expanding.data('timerid', timer);
}, function () {
    var timerid = $(this).data('timerid');
    if (timerid != null) {
        //mouse out, didn't timeout. Kill previously started timer
        window.clearTimeout(timerid);
    }
});

Este es solo para expandir un <li> si el mouse ha estado en él por más de 300ms.

Matthew Millman
fuente
Gracias, encontré esto más útil que las otras respuestas.
Ray
6

Puede usar una llamada setTimeout () con un clearTimeout () en el evento mouseout.

Dan Monego
fuente
1

En 2016, la solución de Crescent Fresh no funcionó como se esperaba para mí, así que se me ocurrió esto:

$(selector).hover(function() {
    hovered = true;
    setTimeout(function() {
        if(hovered) {
            //do stuff
        }
    }, 300); //you can pass references as 3rd, 4th etc. arguments after the delay

}, function() {
    hovered = false;
});
La web
fuente
-2

Mi solución es sencilla. Retrase el menú abierto si el usuario mantiene el mouseenter en obj durante más de 300ms:

var sleep = 0;
$('#category li').mouseenter(function() {
    sleep = 1;
    $('#category li').mouseleave(function() {
        sleep = 0;
    });
    var ob = $(this);
    setTimeout(function() {                         
        if(sleep) {
            // [...] Example:
            $('#'+ob.attr('rel')).show();
        }
    }, 300);
});
onekamil
fuente