95 votes

Comment prévenir la page de défilement pour faire défiler un élément DIV?

J'ai revu et testé les différentes fonctions pour la prévention de la capacité du corps à faire défiler tandis qu'à l'intérieur d'un div et ont combiné une fonction qui devrait fonctionner.

$('.scrollable').mouseenter(function(){
                    $('body').bind('mousewheel DOMMouseScroll', function() {
                        return false
                    });
                    $(this).bind('mousewheel DOMMouseScroll', function() {
                        return true
                    });
                });
                $('.scrollable').mouseleave(function(){
                    $('body').bind('mousewheel DOMMouseScroll', function() {
                        return true
                    });
                });
  • C'est l'arrêt de toutes défilement lorsque que je veux le défilement sera toujours possible à l'intérieur du conteneur
  • Ce n'est également pas la désactivation de la souris sur le congé

Toutes les idées, ou de meilleures façons de faire cela?

167voto

Šime Vidas Points 59994

Mise à jour 2: Ma solution est basée sur la désactivation du navigateur natif de défilement (lorsque le curseur est à l'intérieur de la DIV) et ensuite manuellement le défilement de la DIV en JavaScript (par la définition de ses .scrollTop de la propriété). Une solution de rechange et de l'OMI meilleure approche serait de seulement désactiver de manière sélective le navigateur de défilement afin d'éviter le défilement des pages, mais pas le DIV de défilement. Découvrez: Rudie la réponse ci-dessous qui illustre cette solution.


Ici, vous allez:

$( '.scrollable' ).bind( 'mousewheel DOMMouseScroll', function ( e ) {
    var e0 = e.originalEvent,
        delta = e0.wheelDelta || -e0.detail;

    this.scrollTop += ( delta < 0 ? 1 : -1 ) * 30;
    e.preventDefault();
});

Démonstration en direct: http://jsfiddle.net/XNwbt/458/

Si vous réglez manuellement la position de défilement et puis il suffit de prévenir le comportement par défaut (ce qui serait pour faire défiler la DIV ou à l'ensemble de la page web).

Mise à jour 1: Comme Chris l'a noté dans les commentaires ci-dessous, dans les plus récentes versions de jQuery, le delta de l'information est imbriquée dans l' .originalEvent objet, c'est à dire jQuery ne pas l'exposer dans son objet Événement personnalisée plus, et nous avons à récupérer à partir de la maternelle objet d'Événement à la place.

30voto

wojcikstefan Points 156

Si vous n'avez pas de soins sur la compatibilité avec les anciennes versions IE (< 8), vous pouvez personnaliser un plugin jQuery et ensuite l'appeler sur le débordement de l'élément.

Cette solution a un avantage sur celui Šime Vidas proposé, comme il n'est pas remplacer le comportement de défilement - il à quelques blocs au moment opportun.

$.fn.isolatedScroll = function() {
    this.bind('mousewheel DOMMouseScroll', function (e) {
        var delta = e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail,
            bottomOverflow = this.scrollTop + $(this).outerHeight() - this.scrollHeight >= 0,
            topOverflow = this.scrollTop <= 0;

        if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) {
            e.preventDefault();
        }
    });
    return this;
};

$('.scrollable').isolatedScroll();

21voto

Rudie Points 8975

Je pense qu'il est possible d'annuler la mousescroll événement parfois: http://jsfiddle.net/rudiedirkx/F8qSq/show/

Dans le gestionnaire d'événement, vous aurez besoin de savoir:

  • sens de défilement
    var d = e.wheelDelta || -e.detail Google Chrome utilise wheelDelta, Firefox utilise detail reversedly
  • la position de défilement
    scrollTop pour le haut, scrollHeight - scrollTop - offsetHeight pour le fond

Si vous êtes

  • de défilement, et top = 0, ou
  • le défilement vers le bas, et bottom = 0,

annuler l'événement: e.preventDefault() (et peut-être même e.stopPropagation()).

Je pense que c'est mieux de ne pas remplacer le navigateur de défilement de comportement. Seulement l'annuler, le cas échéant.

C'est probablt pas parfaitement xbrowser, mais il ne peut pas être très dur. Peut-être que Mac double sens de défilement est délicat...

3voto

Ricardo Binns Points 1957

voir si cela vous aider à:

démonstration: jsfiddle

$('#notscroll').bind('mousewheel', function() {
     return false
});

edit:

essayez ceci:

    $("body").delegate("div.scrollable","mouseover mouseout", function(e){
       if(e.type === "mouseover"){
           $('body').bind('mousewheel',function(){
               return false;
           });
       }else if(e.type === "mouseout"){
           $('body').bind('mousewheel',function(){
               return true;
           });
       }
    });

2voto

wrongstars Points 91

Voici ma solution que j'ai utilisé dans les applications.

J'ai désactivé le corps de débordement et a placé l'ensemble de ce site html à l'intérieur du conteneur div. Le site web de conteneurs de dépassement et, par conséquent, l'utilisateur peut faire défiler la page comme prévu.

Ensuite, j'ai créé un frère ou d'une div (#Prévenir) avec un z-index supérieur qui couvre l'ensemble du site. Depuis #Prévenir a un z-index supérieur, il chevauche le site web du conteneur. Quand #Prévenir est visible de la souris n'est plus planant le site web de conteneurs, le défilement n'est pas possible.

Naturellement, vous pouvez placer un autre div, comme votre modal, avec un z-index supérieur que le #de Prévenir dans le balisage. Cela vous permet de créer des fenêtres pop-up qui ne souffrent pas de défilement questions.

Cette solution est préférable car elle permet de ne pas masquer les barres de défilement (saut à affecter). Il ne nécessite pas d'écouteurs d'événement et il est facile à mettre en œuvre. Il fonctionne dans tous les navigateurs, mais avec IE7 et 8, vous avez à jouer autour de (dépend de votre code).

html

<body>
  <div id="YourModal" style="display:none;"></div>
  <div id="Prevent" style="display:none;"></div>
  <div id="WebsiteContainer">
     <div id="Website">
     website goes here...
     </div>
  </div>
</body>

css

body { overflow: hidden; }

#YourModal {
 z-index:200;
 /* modal styles here */
}

#Prevent {
 z-index:100;
 position:absolute;
 left:0px;
 height:100%;
 width:100%;
 background:transparent;
}

#WebsiteContainer {
  z-index:50;
  overflow:auto;
  position: absolute;
  height:100%;
  width:100%;
}
#Website {
  position:relative;
}

jquery/js

function PreventScroll(A) { 
  switch (A) {
    case 'on': $('#Prevent').show(); break;
    case 'off': $('#Prevent').hide(); break;
  }
}

activer/désactiver le défilement

PreventScroll('on'); // prevent scrolling
PreventScroll('off'); // allow scrolling

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