Comment désactiver programmatiquement le défilement de page avec jQuery
en utilisant jQuery, je voudrais désactiver le défilement du corps:
mon idée est de:
- Set
body{ overflow: hidden;}
- Capture du courant
scrollTop();/scrollLeft()
- lier à l'événement de défilement du corps, mettre scrollTop / scrolleft à la valeur capturée.
y a-t-il un meilleur moyen?
mise à 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'est-il pas simplement utiliser position: fixed
sur le panneau?".
S'il vous plaît ne suggérez pas cela car j'ai d'autres raisons.
22 réponses
la seule façon que j'ai trouvée de faire ceci est similaire à ce que vous avez décrit:
- Saisir l'actuelle position de défilement (n'oubliez pas de l'axe horizontal!).
- définit overflow à hidden (probablement pour conserver la valeur précédente de overflow).
- fait défiler le document vers la position de défilement stockée avec scrollTo().
puis quand vous êtes prêt à permettre le scrolling à nouveau, annulez tout cela.
Edit: pas de raison que je ne peux pas vous donner le code depuis que je suis à la peine de 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])
Ce sera complètement désactiver le défilement:
$('html, body').css({
overflow: 'hidden',
height: '100%'
});
la restauration:
$('html, body').css({
overflow: 'auto',
height: 'auto'
});
L'a testé sur Firefox et Chrome.
essayez cette
$('#element').on('scroll touchmove mousewheel', function(e){
e.preventDefault();
e.stopPropagation();
return false;
})
vous pouvez utiliser ce code:
$("body").css("overflow", "hidden");
Je ne fais qu'apporter un petit réglage à la solution par tfe . En particulier, j'ai ajouté un contrôle supplémentaire pour s'assurer qu'il n'y a aucun déplacement du contenu de la page (alias changement de page ) lorsque la barre de défilement est définie à 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 <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 qui comprennent, par exemple, un en-tête avec position:fixed
. Allons dans ce cas particulier avec un exemple. Supposez avoir
<body>
<div id="header">My fixedheader</div>
<!--- OTHER CONTENT -->
</body>
avec
#header{position:fixed; padding:0; margin:0; width:100%}
alors, il faut ajouter le suivant en fonctions lockScroll()
et unlockScroll()
:
function lockScroll(){
//Omissis
$('#header').css('margin-right', marginR);
}
function unlockScroll(){
//Omissis
$('#header').css('margin-right', 0);
}
enfin, prendre soin d'une valeur initiale possible pour les marges ou les capitonnages.
pour désactiver le défilement, essayez ceci:
var current = $(window).scrollTop();
$(window).scroll(function() {
$(window).scrollTop(current);
});
pour réinitialiser:
$(window).off('scroll');
j'ai écrit un plugin jQuery pour gérer ceci: $.disablescroll .
il empêche le défilement à partir de la souris, touchmove, et des événements de pression, tels que Page vers le bas .
il y a un démo ici .
Utilisation:
$(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();
}
une doublure pour désactiver le défilement, y compris le bouton du milieu de la souris.
$(document).scroll(function () { $(document).scrollTop(0); });
edit : il n'y a pas besoin de jQuery de toute façon, ci-dessous même que ci-dessus dans vanilla JS (qui signifie pas de cadres, juste JavaScript):
document.addEventListener('scroll', function () { this.documentElement.scrollTop = 0; this.body.scrollTop = 0; })
this.documentElement.scrollTop-standard
this.corps.compatibilité scrollTop-IE
ne pouvez-vous pas régler la taille du corps à 100% et le débordement caché? Voir http://jsbin.com/ikuma4/13/edit
cela peut ou non fonctionner pour vos besoins, mais vous pouvez étendre jScrollPane pour activer d'autres fonctionnalités avant qu'il ne fasse son défilement. J'ai seulement testé un peu, mais je peux vous confirmer que vous pouvez sauter dans et empêcher le défilement entièrement. Tout ce que j'ai fait, c'est:
- télécharger la démo zip: http://github.com/vitch/jScrollPane/archives/master
- ouvrez la démo" Events" (événement.html)
- éditez-le pour utiliser le script Non-miniaturisé source:
<script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
- dans jquery.jscrollpane.js, insérez un "retour" à la ligne 666 (numéro de ligne de bon augure! mais si votre version diffère légèrement, c'est la première ligne de la fonction
positionDragY(destY, animate)
1519100920"
le Feu des événements.html, et vous verrez une boîte de défilement normalement qui en raison de votre intervention de codage ne fera pas défiler.
You peut contrôler les barres de défilement de l'ensemble du navigateur de cette façon (voir fullpage_scroll.HTML.)
donc, vraisemblablement la prochaine étape est d'ajouter un appel à une autre fonction qui s'éteint et fait votre magie d'ancrage, puis décide de continuer avec le rouleau ou non. Vous avez aussi des appels API pour définir scrollTop et scrollLeft.
si vous voulez plus d'aide, postez où vous vous levez!
Espère que cela a aidé.
j'ai mis 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 autour. Vous pouvez ignorer les parties sur simplemodal.
Quelqu'un a posté ce code, qui a le problème de ne pas conserver la position de défilement une fois restauré. La raison est que les gens ont tendance à l'appliquer à html et le corps ou juste le corps, mais il devrait être appliqué à html seulement. Ainsi, une fois restaurée, la position de défilement sera conservée:
$('html').css({
'overflow': 'hidden',
'height': '100%'
});
la restauration:
$('html').css({
'overflow': 'auto',
'height': 'auto'
});
- Pour Cacher Le Rouleau:
$("body").css("overflow", "hidden");
- Pour Restaurer Scroll:
$("body").css("overflow", "initial");
si vous voulez juste désactiver le défilement avec la navigation au clavier, vous pouvez outrepasser 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);
}
});
// ...
});
vous pouvez masquer la fenêtre avec une div pour empêcher le défilement du contenu sur une page. Et, en se cachant et en montrant, vous pouvez verrouiller / déverrouiller votre rouleau.
Faire quelque chose comme ceci:
#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 gens qui ont des mises en page centrées (via margin:0 auto;
), voici un mash-up de la solution position:fixed
avec @TFE solution proposée.
utilisez cette solution si vous rencontrez page-snapping (en raison de l'affichage de la barre de défilement/Cacher).
// 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, la CSS pour .modal-noscroll
...
.modal-noscroll
{
position: fixed;
overflow-y: scroll;
width: 100%;
}
je voudrais ose le dire c'est plus une bonne correction que toutes les autres solutions, mais je n'ai pas testé que bien encore... :P
Edit: veuillez noter que je n'ai aucune idée à quel point cela pourrait effectuer (lire: coup vers le haut) sur un périphérique tactile.
vous pouvez également utiliser DOM pour ce faire. Dites que vous avez une fonction que vous appelez comme ceci:
function disable_scroll() {
document.body.style.overflow="hidden";
}
et c'est tout! Espérons 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 tout le corps/html mais il ne fait aucun doute qu'il peut être appliqué à n'importe quel élément qui déclenche un événement scroll.
il suffit de régler et de débrancher le cadenas 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 aidera quelqu'un.
je pense que la meilleure solution 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)
})
ceux qui écoutent les événements devraient bloquer le défilement. Il suffit de les supprimer pour réactiver le défilement