Retarder l'événement de survol jquery?

93

Je voudrais retarder un événement de survol dans jquery. Je lis un fichier lorsque l'utilisateur survole un lien ou une étiquette. Je ne veux pas que cet événement se produise immédiatement au cas où l'utilisateur déplace simplement la souris sur l'écran. Existe-t-il un moyen de retarder le déclenchement de l'événement?

Je vous remercie.

Exemple de code:

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

MISE À JOUR: (14/01/09) Après avoir ajouté le plugin HoverIntent, le code ci-dessus a été modifié comme suit pour l'implémenter. Très simple à mettre en œuvre.

$(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
la source
1
Merci d'avoir fourni l'utilisation de hoverIntent
JavaKungFu

Réponses:

91

Utilisez le plugin hoverIntent pour jquery: http://cherne.net/brian/resources/jquery.hoverIntent.html

C'est absolument parfait pour ce que vous décrivez et je l'ai utilisé sur presque tous les projets qui nécessitaient l'activation de menus par la souris, etc.

Il y a un piège à cette approche, certaines interfaces sont dépourvues d'état de «survol», par exemple. navigateurs mobiles comme safari sur l'iphone. Vous cachez peut-être une partie importante de l'interface ou de la navigation sans aucun moyen de l'ouvrir sur un tel appareil. Vous pouvez contourner cela avec des CSS spécifiques à l'appareil.

Roborourke
la source
Ou ce plugin fonctionne aussi comme un charme github.com/john-terenzio/jQuery-Hover-Delay
mica
50

Vous devez vérifier une minuterie en survol. S'il n'existe pas (c'est-à-dire qu'il s'agit du premier survol), créez-le. S'il existe (c'est-à-dire que ce n'est pas le premier survol), tuez-le et redémarrez-le. Réglez la charge utile du minuteur sur votre code.

$(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
    });
});

Je parie que jQuery a une fonction qui résume tout cela pour vous.

Edit : Ah oui, le plugin jQuery à la rescousse

Croissant frais
la source
9
Merci quand même pour une solution sans plugin!
Jrgns
4
J'ai ajouté un clearTimeout (timer); timer = nul; côté souris, mais cela a parfaitement fonctionné et a évité YAP (encore un autre plugin)
Andiih
@Andiih Super appel, et merci de m'avoir présenté l'acronyme "YAP".
Jon
vous voulez probablement dire debounce ()
Vitim.us
11

Tout à fait d'accord que hoverIntent est la meilleure solution, mais si vous êtes un malheureux qui travaille sur un site Web avec un long et long processus d'approbation des plugins jQuery, voici une solution rapide et sale qui a bien fonctionné pour moi:

$('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);
    }
});

Celui-ci est juste pour étendre un <li> si la souris est dessus depuis plus de 300 ms.

Matthew Millman
la source
Merci, j'ai trouvé cela plus utile que les autres réponses.
Ray
6

Vous pouvez utiliser un appel setTimeout () avec un clearTimeout () sur l'événement mouseout.

Dan Monego
la source
1

En 2016, la solution de Crescent Fresh n'a pas fonctionné comme prévu pour moi, alors j'ai trouvé ceci:

$(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 toile
la source
-2

Ma solution est simple. Délai d'ouverture du menu si l'utilisateur garde la souris sur obj pendant plus de 300 ms:

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
la source