54 votes

jQuery désactive le défilement lorsque la souris passe sur une div absolue

J'essaie de désactiver la fonction de défilement de la souris de la fenêtre lorsque la souris survole le div - de sorte que seul le défilement du div soit activé - et lorsque la souris s'éloigne du div - le défilement de la fenêtre est à nouveau appliqué. Le div est positionné de manière absolue.

J'ai vu ce message utiliser jquery pour désactiver la fonction de la roulette de la souris lorsque le curseur de la souris se trouve à l'intérieur d'une div ? mais il ne semble pas apporter de réponse - d'où ma question.

Je suppose qu'il s'agirait de quelque chose comme ceci (si seulement ces méthodes existaient) :

$('#container').hover(function() {
     $(window).scroll().disable();
     $(this).scroll().enable();
}, function() {
     $(window).scroll().enable();
});

1 votes

J'ai du mal à comprendre votre question, n'est-ce pas le comportement par défaut ? Lorsque vous survolez une "div" et que vous avez "overflow:scroll", cela fait simplement défiler la "div", et non la fenêtre, ou essayez-vous de faire en sorte que, par exemple, lorsque le défilement est terminé, la fenêtre ne défile toujours pas ?

1 votes

Je soupçonne qu'il cherche exactement ce que vous décrivez. Sa div positionnée de manière absolue défile, mais lorsqu'elle finit de défiler, il ne veut pas que la fenêtre principale défile. C'est un problème que je rencontre souvent lorsque j'édite des articles sous Wordpress. Tout sort de l'écran. Lorsque l'on travaille dans un éditeur, il est bon que le travail reste en place !

0 votes

Oui - c'est exactement ce que je voulais dire - merci @mrtsherman pour cet éclaircissement.

99voto

mrtsherman Points 19573

Cette question étant très répandue, j'ai décidé de faire le point sur les réponses proposées et de vous indiquer celle qui vous conviendrait le mieux. Trois solutions uniques sont proposées. Deux viennent d'Amos et une de moi-même. Cependant, chacune fonctionne différemment.

  1. Amos - Set overflow:hidden sur le corps. C'est simple et cela fonctionne très bien. Mais les barres de défilement de la fenêtre principale clignotent.
  2. Amos - Utilisez le javascript pour désactiver la roulette de la souris. C'est idéal si vous n'avez pas besoin de la roulette de la souris.
  3. Cette réponse - Utilisez javascript pour faire défiler uniquement l'élément sur lequel vous vous trouvez. C'est la meilleure réponse si votre div interne doit défiler, mais que vous ne voulez pas que d'autres divs défilent. L'exemple du fiddle illustre cette solution.

http://jsfiddle.net/eXQf3/371/

Le code fonctionne comme suit :

  • Attrape l'événement de défilement sur l'élément courant
  • Annuler l'événement de défilement
  • Défilement manuel de l'élément courant uniquement

    $('#abs').bind('mousewheel DOMMouseScroll', function(e) { var scrollTo = null;

    if (e.type == 'mousewheel') {
        scrollTo = (e.originalEvent.wheelDelta * -1);
    }
    else if (e.type == 'DOMMouseScroll') {
        scrollTo = 40 * e.originalEvent.detail;
    }
    
    if (scrollTo) {
        e.preventDefault();
        $(this).scrollTop(scrollTo + $(this).scrollTop());
    }

    });​

Changelog :

  • Support FF
  • scrollTo null check pour revenir au comportement par défaut en cas d'imprévu
  • prise en charge de jQuery 1.7.

2 votes

@kunigami - J'ai compris ce qui n'allait pas et j'ai mis à jour ma réponse. e.wheelDelta a été supprimée dans jQuery 1.7 et je dois donc y accéder par l'intermédiaire de orginalEvent au lieu de cela. bugs.jquery.com/ticket/10676

0 votes

Voici une solution similaire, utilisant des événements JS purs plutôt que des événements jQuery : stackoverflow.com/questions/9256213/

3 votes

@mrtsherman Tout d'abord, merci pour la réponse, mais ne copiez pas le paster de jsFiddle. Le code ci-dessus causera un Unexpected token ILLEGAL dans webkit qui a quelques caractères invalides (et malheureusement invisibles).voir stackoverflow.com/questions/4404526/ .

31voto

amosrivera Points 11654

Vous ne pouvez pas désactiver le défilement des fenêtres, mais il existe une solution simple :

//set the overflow to hidden to make scrollbars disappear
$('#container').hover(function() {
    $("body").css("overflow","hidden");
}, function() {
     $("body").css("overflow","auto");
});

Voir la démo : http://jsfiddle.net/9Htjw/


MISE À JOUR

Vous pouvez cependant désactiver la molette de la souris.

$('#container').hover(function() {
    $(document).bind('mousewheel DOMMouseScroll',function(){ 
        stopWheel(); 
    });
}, function() {
    $(document).unbind('mousewheel DOMMouseScroll');
});

function stopWheel(e){
    if(!e){ /* IE7, IE8, Chrome, Safari */ 
        e = window.event; 
    }
    if(e.preventDefault) { /* Chrome, Safari, Firefox */ 
        e.preventDefault(); 
    } 
    e.returnValue = false; /* IE7, IE8 */
}

Source : http://solidlystated.com/scripting/javascript-disable-mouse-wheel/

Démonstration : http://jsfiddle.net/9Htjw/4/

0 votes

Il fonctionne bien mais il y a un problème lorsque l'arrière-plan de la div est transparent.

3voto

rocky Points 1674

Mrtsherman : si vous liez l'événement de cette manière, le code d'amosrivera fonctionne également pour firefox :

    var elem = document.getElementById ("container");
    if (elem.addEventListener) {    
        elem.addEventListener ("mousewheel", stopWheel, false);
        elem.addEventListener ("DOMMouseScroll", stopWheel, false);
    }
    else {
        if (elem.attachEvent) { 
            elem.attachEvent ("onmousewheel", stopWheel);
        }
    }

1voto

Lasithds Points 9

J'ai utilisé nicescroll sur ma page, aucune méthode n'a fonctionné. Je me suis rendu compte que le nicescroller appelait l'événement scroll et j'ai dû désactiver temporairement le nicescroll lors du survol de l'élément.

Solution : Désactiver temporairement le nicescroll lors du survol d'un élément

$('body').on('mouseover', '#element', function() {
    $('body, html').css('overflow', 'auto').getNiceScroll().remove();
}).on('mouseout', '#element', function() {
    $('body, html').css('overflow', 'hidden').niceScroll();
});

0voto

MjolTonir Points 21

Ce que j'essaie de faire avec mon code est le suivant :

  • Vérifier si la div est survolée ou survolée par la souris

  • Obtenir la direction du défilement

  • Comparer le ScrollTop avec la hauteur du conteneur et empêcher tout nouveau défilement lorsque le maximum ou le minimum est atteint (jusqu'à ce que la souris soit sortie).

    var hovered_over = false;
    var hovered_control;          
    function onCrtlMouseEnter(crtl) {      //Had same thing used for mutliple controls 
        hovered_over = true;       //could be replaced with $(control).onmouseenter(); etc
        hovered_control = crtl;    //you name it
    }
    function onCrtlMouseLeave(crtl) {
        hovered_over = false;
        hovered_control = null;
    }
    
    $(document).on("mousewheel",function(e)
    {
       if (hovered_over == true) {                            
            var control = $(hovered_control);                 //get control
            var direction = e.originalEvent.wheelDeltaY;      //get direction of scroll
            if (direction < 0) {
                if ((control.scrollHeight - control.clientHeight) == control.scrollTop) {
                    return false;              //reached max downwards scroll... prevent;
                }
            }
            else if (direction > 0) {
                if (control.scrollTop == 0) {
                    return false;              //reached max upwards scroll... prevent;
                }
            }
        }
    });

http://jsfiddle.net/Miotonir/4uw0vra5/1/

Ce n'est probablement pas le code le plus propre et il peut être amélioré facilement, mais cela fonctionne pour moi. (control.scrollHeight - control.clientHeight) Cette partie est un peu douteuse pour moi, mais vous devriez quand même avoir une idée de la façon d'aborder le problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X