web-dev-qa-db-fra.com

Comment désactiver par programmation le défilement de page avec jQuery

Avec jQuery, je voudrais désactiver le défilement du corps:

Mon idée est de:

  1. Définir body{ overflow: hidden;} 
  2. Capturez le _scrollTop();/scrollLeft() actuel 
  3. Lier à l'événement de défilement body, définissez scrollTop/scrollLeft sur la valeur capturée.

Y a-t-il un meilleur moyen?


Mettre à jour:

S'il vous plaît voir mon exemple, et une raison pour laquelle, à http://jsbin.com/ikuma4/2/edit

Je sais que quelqu'un se demandera "pourquoi n'utilise-t-il pas simplement position: fixed sur le panneau?".

S'il vous plaît ne suggérez pas cela car j'ai d'autres raisons.

145
Hailwood

La seule façon que j'ai trouvée de faire cela est similaire à ce que vous avez décrit:

  1. Saisissez la position de défilement actuelle (n'oubliez pas l'axe horizontal!).
  2. Définissez overflow sur hidden (vous souhaitez probablement conserver la valeur de dépassement précédente).
  3. Faites défiler le document jusqu'à la position de défilement enregistrée avec scrollTo ().

Ensuite, lorsque vous êtes prêt à autoriser le défilement à nouveau, annulez tout cela.

Edit: aucune raison pour que je ne puisse pas vous donner le code puisque j'ai pris la peine de le creuser ...

// lock scroll position, but retain settings for later
var scrollPosition = [
  self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
  self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
];
var html = jQuery('html'); // it would make more sense to apply this to body, but IE7 won't have that
html.data('scroll-position', scrollPosition);
html.data('previous-overflow', html.css('overflow'));
html.css('overflow', 'hidden');
window.scrollTo(scrollPosition[0], scrollPosition[1]);


// un-lock scroll position
var html = jQuery('html');
var scrollPosition = html.data('scroll-position');
html.css('overflow', html.data('previous-overflow'));
window.scrollTo(scrollPosition[0], scrollPosition[1])
125
tfe

Cela va complètement désactiver le défilement:

$('html, body').css({
    overflow: 'hidden',
    height: '100%'
});

Restaurer:

$('html, body').css({
    overflow: 'auto',
    height: 'auto'
});

Testé sur Firefox et Chrome.

204
gitaarik

essaye ça

$('#element').on('scroll touchmove mousewheel', function(e){
  e.preventDefault();
  e.stopPropagation();
  return false;
})
44
cubbiu

vous pouvez utiliser ce code:

$("body").css("overflow", "hidden");
26
mr.soroush

Je viens de fournir un peu de réglage à la solution par tfe . En particulier, j'ai ajouté un contrôle supplémentaire pour garantir la présence de pas de décalage du contenu de la page} _ (ou changement de page) lorsque la barre de défilement est définie sur hidden.

Deux fonctions Javascript lockScroll() et unlockScroll() peuvent être définies, respectivement, pour verrouiller et déverrouiller le défilement de page.

function lockScroll(){
    $html = $('html'); 
    $body = $('body'); 
    var initWidth = $body.outerWidth();
    var initHeight = $body.outerHeight();

    var scrollPosition = [
        self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
        self.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
    ];
    $html.data('scroll-position', scrollPosition);
    $html.data('previous-overflow', $html.css('overflow'));
    $html.css('overflow', 'hidden');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);   

    var marginR = $body.outerWidth()-initWidth;
    var marginB = $body.outerHeight()-initHeight; 
    $body.css({'margin-right': marginR,'margin-bottom': marginB});
} 

function unlockScroll(){
    $html = $('html');
    $body = $('body');
    $html.css('overflow', $html.data('previous-overflow'));
    var scrollPosition = $html.data('scroll-position');
    window.scrollTo(scrollPosition[0], scrollPosition[1]);    

    $body.css({'margin-right': 0, 'margin-bottom': 0});
}

où j'ai supposé que le <body> n'a pas de marge initiale.

Notez que, bien que la solution ci-dessus fonctionne dans la plupart des cas pratiques, elle n’est pas définitive car elle nécessite une personnalisation supplémentaire pour les pages comprenant, par exemple, un en-tête avec position:fixed. Allons dans ce cas particulier avec un exemple. Supposons avoir

<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>

avec 

#header{position:fixed; padding:0; margin:0; width:100%}

Ensuite, il faut ajouter ce qui suit dans les fonctions lockScroll() et unlockScroll():

function lockScroll(){
    //Omissis   


    $('#header').css('margin-right', marginR);
} 

function unlockScroll(){
    //Omissis   

    $('#header').css('margin-right', 0);
}

Enfin, prenez en compte une valeur initiale possible pour les marges ou les rembourrages.

25
JeanValjean

Pour désactiver le défilement, essayez ceci:

var current = $(window).scrollTop();
$(window).scroll(function() {
    $(window).scrollTop(current);
});

réinitialiser:

$(window).off('scroll');
18
Patrick DaVader

Vous pouvez attacher une fonction pour faire défiler les événements et empêcher son comportement par défaut.

var $window = $(window);

$window.on("mousewheel DOMMouseScroll", onMouseWheel);

function onMouseWheel(e) {
    e.preventDefault();
}

https://jsfiddle.net/22cLw9em/

5
dzimi

J'ai écrit un plugin jQuery pour gérer ceci: $. Disablescroll.

Il empêche le défilement d'événements de molette, de touchmove et de pression de touche, tels que Page Down.

Il y a un démo ici.

Usage:

$(window).disablescroll();

// To re-enable scrolling:
$(window).disablescroll("undo");
5
Josh Harrison

Une doublure pour désactiver le défilement, y compris le bouton central de la souris.

$(document).scroll(function () { $(document).scrollTop(0); });

edit : Il n’est pas nécessaire de recourir à jQuery, en dessous, comme ci-dessus dans Vanilla JS (c’est-à-dire qu’il n’ya pas de framework, mais JavaScript):

document.addEventListener('scroll', function () { this.documentElement.scrollTop = 0; this.body.scrollTop = 0; })

this.documentElement.scrollTop - standard

this.body.scrollTop - Compatibilité IE

4
Pawel

Ne pouvez-vous pas simplement définir la hauteur du corps à 100% et le débordement masqué? Voir http://jsbin.com/ikuma4/13/edit

3
Adrian Schmidt

Je mets une réponse qui pourrait aider ici: jQuery simplemodal disable scrolling

Il montre comment désactiver les barres de défilement sans déplacer le texte. Vous pouvez ignorer les parties concernant le modélodal.

2
mhenry1384

Cela peut fonctionner ou non pour vos besoins, mais vous pouvez également utiliser jScrollPane pour activer d’autres fonctionnalités avant le défilement. Je viens juste de tester cela un peu, mais je peux confirmer que vous pouvez intervenir et empêcher le défilement complètement. Tout ce que j'ai fait était:

  • Téléchargez la démo Zip: http://github.com/vitch/jScrollPane/archives/master
  • Ouvrez la démo "Events" (events.html)
  • Modifiez-le pour utiliser la source de script non minifiée: <script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
  • Dans jquery.jscrollpane.js, insérez un "return;" à la ligne 666 (numéro de ligne propice! mais si votre version diffère légèrement, il s'agit de la première ligne de la fonction positionDragY(destY, animate)

Lancez events.html et vous verrez une boîte de défilement normale qui, en raison de votre intervention de codage, ne défilera pas.

Vous pouvez contrôler l’ensemble des barres de défilement du navigateur (voir fullpage_scroll.html). 

Donc, on peut supposer que l'étape suivante consiste à ajouter un appel à une autre fonction qui se déclenche et effectue votre magie d'ancrage, puis décide de continuer ou non avec le défilement. Vous avez également des appels d'API pour définir scrollTop et scrollLeft.

Si vous voulez plus d’aide, postez où vous voulez!

J'espère que cela a aidé.

2
Jeremy Warne
  • Pour masquer le défilement: $("body").css("overflow", "hidden");
  • Pour restaurer le défilement: $("body").css("overflow", "initial");

Quelqu'un a posté ce code, qui pose le problème de ne pas conserver la position de défilement lors de la restauration. La raison en est que les gens ont tendance à l’appliquer au langage HTML et au corps, ou seulement au corps, mais il devrait être appliqué au HTML uniquement. Ainsi, une fois restauré, la position du défilement sera conservée:

$('html').css({
    'overflow': 'hidden',
    'height': '100%'
});

Restaurer:

$('html').css({
    'overflow': 'auto',
    'height': 'auto'
});
2
Mescalina

Essayez ce code:

    $(function() { 
        // ...

        var $body = $(document);
        $body.bind('scroll', function() {
            if ($body.scrollLeft() !== 0) {
                $body.scrollLeft(0);
            }
        });

        // ...
    });
1
Jopie

Si vous souhaitez simplement désactiver le défilement avec la navigation au clavier, vous pouvez remplacer l'événement keydown.

$(document).on('keydown', function(e){
    e.preventDefault();
    e.stopPropagation();
});
1
sean

Vous pouvez également utiliser DOM pour le faire. Disons que vous avez une fonction que vous appelez comme ceci:

function disable_scroll() {
document.body.style.overflow="hidden";
}

Et c'est tout ce qu'il y a à faire! J'espère que cela aide en plus de toutes les autres réponses!

0
Brendan

C'est ce que j'ai fini par faire:

CoffeeScript:

    $("input").focus ->
        $("html, body").css "overflow-y","hidden"
        $(document).on "scroll.stopped touchmove.stopped mousewheel.stopped", (event) ->
            event.preventDefault()

    $("input").blur ->
        $("html, body").css "overflow-y","auto"
        $(document).off "scroll.stopped touchmove.stopped mousewheel.stopped"

Javascript:

$("input").focus(function() {
 $("html, body").css("overflow-y", "hidden");
 $(document).on("scroll.stopped touchmove.stopped mousewheel.stopped", function(event) {
   return event.preventDefault();
 });
});

$("input").blur(function() {
 $("html, body").css("overflow-y", "auto");
 $(document).off("scroll.stopped touchmove.stopped mousewheel.stopped");
});
0
Marz

Pas sûr si quelqu'un a essayé ma solution. Celui-ci fonctionne sur le corps entier/html mais il ne fait aucun doute qu'il peut être appliqué à n'importe quel élément qui déclenche un événement de défilement.

Il suffit de définir et de désactiver ScrollLock selon vos besoins.

var scrollLock = false;
var scrollMem = {left: 0, top: 0};

$(window).scroll(function(){
    if (scrollLock) {
        window.scrollTo(scrollMem.left, scrollMem.top);
    } else {
        scrollMem = {
            left: self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
            top: self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
        };
    }
});

Voici l'exemple JSFiddle

J'espère que celui-ci aide quelqu'un.

0
FossilMFC

Vous pouvez couvrir la fenêtre avec une div à défilement pour empêcher le défilement du contenu d'une page ..__ Et, en masquant et en affichant, vous pouvez verrouiller/déverrouiller votre défilement.

Faites quelque chose comme ça:

#scrollLock {
    width: 100%;
    height: 100%;
    position: fixed;
    overflow: scroll;
    opacity: 0;
    display:none
}

#scrollLock > div {
    height: 99999px;
}

function scrollLock(){
    $('#scrollLock').scrollTop('10000').show();
}

function scrollUnlock(){
    $('#scrollLock').hide();
}
0
Appex

Je pense que la solution la meilleure et propre est:

window.addEventListener('scroll',() => {
    var x = window.scrollX;
    var y = window.scrollY;
    window.scrollTo(x,y);
});

Et avec jQuery:

$(window).on('scroll',() => {
    var x = window.scrollX;
    var y = window.scrollY;
    window.scrollTo(x,y)
})

Ces écouteurs d’événements doivent bloquer le défilement . Il suffit de les supprimer pour réactiver le défilement.

0
Tiziano

Pour les personnes ayant des dispositions centrées (via margin:0 auto;), voici un mash-up de la solution position:fixed avec la solution proposée par @tfe .

Utilisez cette solution si vous rencontrez des problèmes de capture de page (en raison de la barre de défilement affichant/masquant).

// lock scroll position, but retain settings for later
var scrollPosition = [
    window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
    window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop
];
var $html = $('html'); // bow to the demon known as MSIE(v7)
$html.addClass('modal-noscroll');
$html.data('scroll-position', scrollPosition);
$html.data('margin-top', $html.css('margin-top'));
$html.css('margin-top', -1 * scrollPosition[1]);

…combiné avec…

// un-lock scroll position
var $html = $('html').removeClass('modal-noscroll');
var scrollPosition = $html.data('scroll-position');
var marginTop = $html.data('margin-top');
$html.css('margin-top', marginTop);
window.scrollTo(scrollPosition[0], scrollPosition[1])

… Et enfin, le CSS pour .modal-noscroll

.modal-noscroll
{
    position: fixed;
    overflow-y: scroll;
    width: 100%;
}

J'oserais dire que c'est plus une solution appropriée que n'importe laquelle des autres solutions existantes, mais je ne l'ai pas encore testée qui n'a pas encore été complètement…: P


Edit: s'il vous plaît noter que je n'ai aucune idée de la façon dont cela pourrait effectuer (lire: exploser) sur un périphérique tactile.

0
Matthematics