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

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

Mon idée est de:

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

Y a-t-il une meilleure façon?


Mettre à jour:

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

Je suis conscient que quelqu’un va penser “pourquoi n’utilise-t-il pas seulement la position: fixed sur le panneau?”.

Merci de ne pas le suggérer car j’ai d’autres raisons.

Le seul moyen que j’ai trouvé pour le faire est similaire à ce que vous avez décrit:

  1. Prenez la position de défilement actuelle (n’oubliez pas l’axe horizontal!).
  2. Définissez le débordement sur caché (voulez probablement conserver la valeur de débordement précédente).
  3. Faites défiler le document vers la position de défilement stockée avec scrollTo ().

Ensuite, lorsque vous êtes prêt à faire défiler à nouveau, défaites tout cela.

Edit: aucune raison je ne peux pas vous donner le code depuis que j’ai eu la peine de le chercher …

 // 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]) 

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.

essaye ça

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

vous pouvez utiliser ce code:

 $("body").css("overflow", "hidden"); 

Je viens de donner un petit coup de pouce à la solution par tfe . En particulier, j’ai ajouté un contrôle supplémentaire pour garantir que le contenu de la page (aka changement de page ) ne change pas 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 la 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 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 qui incluent, par exemple, un en-tête avec position:fixed . Allons dans ce cas particulier avec un exemple. Supposons avoir

     

avec

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

Ensuite, il faut append les éléments suivants dans les fonctions lockScroll() et unlockScroll() :

 function lockScroll(){ //Omissis $('#header').css('margin-right', marginR); } function unlockScroll(){ //Omissis $('#header').css('margin-right', 0); } 

Enfin, veillez à une valeur initiale possible pour les marges ou les paddings.

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

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

réinitialiser:

 $(window).off('scroll'); 

J’ai écrit un plugin jQuery pour gérer ceci: $ .disablescroll .

Il empêche le défilement à partir des événements de la molette de la souris, de la touche tactile et de la pression de touche, tels que Page suivante .

Il y a une démo ici .

Usage:

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

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/

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’y a pas besoin de jQuery de toute façon, ci-dessous comme ci-dessus dans JS vanilla (cela signifie pas de frameworks, juste du JavaScript):

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

this.documentElement.scrollTop – standard

this.body.scrollTop – Compatibilité IE

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

Cela peut ou peut ne pas fonctionner pour vos besoins, mais vous pouvez étendre jScrollPane pour lancer d’autres fonctionnalités avant de faire son défilement. Je viens juste de le tester un peu, mais je peux confirmer que vous pouvez intervenir et empêcher le défilement entièrement. Tout ce que j’ai fait était:

  • Téléchargez le zip de démonstration: 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:
  • 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 positionDragY(destY, animate)

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

Vous pouvez contrôler les barres de défilement de tout le navigateur de cette façon (voir fullpage_scroll.html).

Donc, la prochaine étape est probablement d’append un appel à une autre fonction qui se déclenche et fait votre magie d’ancrage, puis décide de continuer ou non le parchemin. Vous avez également des appels API pour définir scrollTop et scrollLeft.

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

J’espère que cela a aidé.

Je mets une réponse qui pourrait aider ici: jQuery simplemodal désactiver le défilement

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

Quelqu’un a posté ce code, qui a 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 HTML et au corps ou seulement au corps, mais cela devrait être appliqué uniquement au HTML. De cette façon, une fois restaurée, la position de défilement sera conservée:

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

Restaurer:

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

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

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

Essayez ce code:

  $(function() { // ... var $body = $(document); $body.bind('scroll', function() { if ($body.scrollLeft() !== 0) { $body.scrollLeft(0); } }); // ... }); 
  • Pour masquer le défilement: $("body").css("overflow", "hidden");
  • Pour restaurer Scroll: $("body").css("overflow", "initial");

Vous pouvez masquer la fenêtre avec un div déroulant pour empêcher le défilement du contenu sur une page. Et en se cachant et en montrant, vous pouvez verrouiller / déverrouiller votre parchemin.

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

Pour les personnes qui ont des mises en page centrées (via la margin:0 auto; ), voici un mélange de la solution position:fixed solution position:fixed solution proposée par @tfe .

Utilisez cette solution si vous rencontrez une capture de page (en raison de la barre de défilement affichée / masquée).

 // 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%; } 

Je me risquerais à dire que cette solution est plus appropriée que toutes les autres solutions, mais je ne l’ai pas encore testée à fond…: P


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

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!

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"); }); 

Je ne sais pas 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é à tout élément qui déclenche un événement de défilement.

Il suffit de définir et de désélectionner 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.

Je pense que la meilleure solution est la suivante:

 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 permettre le défilement