Come disabilitare a livello di codice lo scorrimento delle pagine con jQuery


163

Usando jQuery, vorrei disabilitare lo scorrimento del corpo:

La mia idea è di:

  1. Impostato body{ overflow: hidden;}
  2. Cattura la corrente scrollTop();/scrollLeft()
  3. Associa all'evento di scorrimento del corpo, imposta scrollTop / scrollLeft sul valore acquisito.

C'è un modo migliore?


Aggiornare:

Consulta il mio esempio e un motivo per cui su http://jsbin.com/ikuma4/2/edit

Sono consapevole che qualcuno penserà "perché non usa solo position: fixedsul pannello?".

Per favore, non suggerire questo perché ho altri motivi.


7
"C'è un modo migliore?" - a parte lasciare che il browser si comporti normalmente?
Fenton,

22
"melodrammatico"?
Mike Weller,

6
Forse significava programmaticamente? Dal momento che è il miglior suggerimento per la correzione ortografica di Firefox per "programmaticamente"
Michael Shimmins,

4
Questo thread sta andando \ b \
Cipi

3
@Sohnee disabilitazione scorrimento! == cattivo
Mansiemans

Risposte:


136

L'unico modo che ho trovato per fare questo è simile a quello che hai descritto:

  1. Prendi la posizione di scorrimento corrente (non dimenticare l'asse orizzontale!).
  2. Imposta l'overflow su nascosto (probabilmente desideri conservare il valore di overflow precedente).
  3. Scorrere il documento fino alla posizione di scorrimento memorizzata con scrollTo ().

Quindi quando sei pronto per consentire di nuovo lo scorrimento, annulla tutto.

Modifica: nessun motivo per cui non posso darti il ​​codice da quando ho avuto il disturbo di scavarlo ...

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

2
per favore vedi jsbin.com/ikuma4/2/edit e spiegami qual è il motivo per cui il tuo è migliore? mi sto perdendo qualcosa (chiedo perché non riesco a vedere alcun motivo per la lunghezza della tua risposta rispetto al mio esempio)
Hailwood

3
Il tuo approccio non funziona in IE7. L'ho provato anche io per primo. Il problema è che non reagisce abbastanza rapidamente all'evento scroll. Permette al documento di scorrere, quindi lo ritrae quando JS ripristina la posizione di scorrimento nel punto desiderato.
martedì

1
Inoltre, se il corpo avesse un overflow di qualcosa di diverso da quello auto, verrebbe sovrascritto. Avevo bisogno di preservare l'impostazione esistente, in modo da aggiungere anche un certo sovraccarico.
martedì

Qualcuno sa perché lo stile semplice htmle bodycon overflow: hiddenè insufficiente? Finiamo ancora per aver bisogno del gestore dell'evento.
Kpozin,

4
Questa è una risposta fantastica E per farlo funzionare su dispositivi touch, dai un'occhiata a questa risposta.
Patrick,

235

Questo disabiliterà completamente lo scorrimento:

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

Ripristinare:

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

Testato su Firefox e Chrome.


18
funziona come previsto. Grazie! Questa avrebbe dovuto essere la risposta accettata!
Dave Chen,

6
Scorre ancora con il pulsante centrale del mouse su Chrome.
Lothar,

16
Ciò perde la posizione di scorrimento corrente. OP ha esplicitamente menzionato l'acquisizione della posizione di scorrimento, quindi presumo che lo richiedesse. Ad ogni modo, lo richiedo, quindi questo mi è di utilità limitata
zerm,

7
PS L'omissione dell'opzione height: 100%blocca efficacemente lo scorrimento nella posizione corrente senza saltare, almeno su Chrome.
zerm,

2
Questa NON è la risposta corretta. La posizione di scorrimento non viene acquisita
taylorcressy

43

prova questo

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

proprio quello che stavo cercando ... quasi. Comunque disabilitarlo durante i tasti freccia?
Cody,

2
@Cody - combina questo con overflow css: nascosto
Darius.V

2
@cubbiu come invertirlo?
Meer,

3
Puoi usare$('#element').off('scroll touchmove mousewheel');
arnuschky il

1
Ottima soluzione Anche se come disabiliteresti lo bodyscorrimento ma permetteresti lo scorrimento all'interno di altri elementi figlio che hanno overflow: scroll?
Fizzix,

27

Fornisco solo un po 'di sintonia con la soluzione di tfe . In particolare, ho aggiunto un ulteriore controllo per garantire che non vi sia alcuno spostamento del contenuto della pagina (aka spostamento della pagina ) quando la barra di scorrimento è impostata suhidden .

Due funzioni Javascript lockScroll()e unlockScroll()possono essere definite, rispettivamente, per bloccare e sbloccare lo scorrimento della pagina.

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

dove ho pensato che il <body> non abbia margine iniziale.

Si noti che, sebbene la soluzione di cui sopra funzioni nella maggior parte dei casi pratici, non è definitiva poiché necessita di ulteriori personalizzazioni per le pagine che includono, ad esempio, un'intestazione con position:fixed. Andiamo in questo caso speciale con un esempio. Supponiamo di avere

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

con

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

Quindi, si dovrebbe aggiungere quanto segue in funzioni lockScroll()e unlockScroll():

function lockScroll(){
    //Omissis   


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

function unlockScroll(){
    //Omissis   

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

Infine, prenditi cura di un possibile valore iniziale per i margini o le imbottiture.


4
Hai un errore nel tuo javascript $ body.css ({'margin-right': 0, 'margin-bottom', 0}); dovrebbe essere $ body.css ({'margin-right': 0, 'margin-bottom': 0});
Johansrk,

In realtà, basta usare marginRighte marginLeft:)
Martijn

25

puoi usare questo codice:

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

8
Puoi comunque usare il pulsante centrale del mouse per scorrere.
Roger Far,

2
No, va bene e non scorrere con questo!
sig.Soroush,

Se usi alcuni CSS extra che PUOI disabilitare completamente lo scorrimento, vedi la mia risposta per maggiori dettagli.
Gitaarik,

21

Per disattivare lo scorrimento provare questo:

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

resettare:

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

Questa è stata una soluzione fantastica per ciò di cui avevo bisogno.
Terry Carter,

@EveryScreamer no, fa tremare lo schermo come un matto. Prova di trovare una soluzione alternativa.
Telarian

5

Ho scritto un plugin jQuery per gestire questo: $ .disablescroll .

Impedisce lo scorrimento da eventi con rotellina del mouse, touchmove e pressione dei tasti, ad esempio Page Down .

C'è una demo qui .

Uso:

$(window).disablescroll();

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

Ho provato a utilizzare il plug-in disablescroll () per disabilitare temporaneamente lo scorrimento quando si sente l'evento mouswheel / scroll, ma non funziona. Qualche possibilità conosci un modo per ottenere questo effetto?
giallo-santo,

@JB Probabilmente posso aiutare, ma i commenti non sono il posto migliore. Unisciti a me in questa chat di overflow dello stack e vedrò cosa posso fare: chat.stackoverflow.com/rooms/55043/disablescroll-usage
Josh Harrison

Mi dispiace, ma questo plugin non funziona nemmeno nel tuo jsfiddle.
markj,

Puoi aiutarmi a ispezionarlo dicendomi in quale browser / piattaforma non sembra funzionare per favore?
Josh Harrison,

5

È possibile associare una funzione per scorrere gli eventi e impedirne il comportamento predefinito.

var $window = $(window);

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

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

https://jsfiddle.net/22cLw9em/


1
Questa è la risposta esatta. Non so perché non sia impostato così
Guilherme Ferreira,

Funziona. È sufficiente che il codice di ripristino sia inviato per corrispondere alla risposta di Patricks
Hastig Zusammenstellen,

4

Una riga per disabilitare lo scorrimento incluso il pulsante centrale del mouse.

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

modifica : JQuery non è comunque necessario, sotto lo stesso di sopra in Vanilla JS (ciò significa che non ci sono framework, solo JavaScript):

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

this.documentElement.scrollTop - standard

this.body.scrollTop - Compatibilità IE


4
  • Per nascondere lo scorrimento: $("body").css("overflow", "hidden");
  • Per ripristinare lo scorrimento: $("body").css("overflow", "initial");


3

Qualcuno ha pubblicato questo codice, che ha il problema di non conservare la posizione di scorrimento quando ripristinato. Il motivo è che le persone tendono ad applicarlo a HTML e corpo o solo al corpo, ma dovrebbe essere applicato solo a HTML. In questo modo una volta ripristinata la posizione di scorrimento verrà mantenuta:

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

Ripristinare:

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

non 'overflow': 'auto',usare'overflow': 'initial',
evtuhovdo

2

Questo potrebbe non funzionare per i tuoi scopi, ma puoi estendere jScrollPane per attivare altre funzionalità prima che esegua lo scorrimento. Ho appena provato questo un po ', ma posso confermare che puoi saltare e impedire completamente lo scorrimento. Tutto quello che ho fatto è stato:

  • Scarica la demo zip: http://github.com/vitch/jScrollPane/archives/master
  • Apri la demo "Eventi" (events.html)
  • Modificalo per utilizzare la fonte di script non minimizzata: <script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
  • All'interno di jquery.jscrollpane.js, inserisci un "return;" alla riga 666 (numero di riga di buon auspicio! ma nel caso in cui la versione differisca leggermente, questa è la prima riga della positionDragY(destY, animate)funzione

Accendi events.html e vedrai una casella normalmente scorrevole che a causa del tuo intervento di codifica non scorrerà.

Puoi controllare le barre di scorrimento dell'intero browser in questo modo (vedi fullpage_scroll.html).

Quindi, presumibilmente, il prossimo passo è aggiungere una chiamata ad un'altra funzione che si spegne e fa la tua magia di ancoraggio, quindi decide se continuare con lo scorrimento o meno. Hai anche ricevuto chiamate API per impostare scrollTop e scrollLeft.

Se vuoi più aiuto, pubblica dove vuoi!

Spero che questo abbia aiutato.



1

Se vuoi solo disabilitare lo scorrimento con la navigazione da tastiera, puoi ignorare l'evento keydown.

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

1

Prova questo codice:

    $(function() { 
        // ...

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

        // ...
    });

0

Puoi nascondere la finestra con un div scorrevole per impedire lo scorrimento del contenuto in una pagina. Inoltre, nascondendo e mostrando, è possibile bloccare / sbloccare lo scorrimento.

Fai qualcosa del genere:

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

7
Si prega di non utilizzare abbreviazioni come "u" e "smth". Prenditi il ​​tempo necessario per scrivere correttamente, per leggibilità.
Tin Man,

0

Per le persone che hanno centrato i layout (via margin:0 auto;), ecco un mash-up della position:fixedsoluzione insieme alla soluzione proposta da @tfe .

Utilizzare questa soluzione se si verifica lo snap alla pagina (a causa della barra di scorrimento che mostra / nasconde).

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

…combinata con…

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

... e infine, il CSS per .modal-noscroll...

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

Mi permetto di dire che questo è più di una vera e propria correzione rispetto a qualsiasi delle altre soluzioni là fuori, ma non ho provato che bene ancora ...: P


Modifica: tieni presente che non ho idea di quanto male possa funzionare (leggi: esplosione) su un dispositivo touch.


0

Puoi anche usare DOM per farlo. Supponi di avere una funzione che chiami in questo modo:

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

E questo è tutto quello che c'è da fare! Spero che questo aiuti oltre a tutte le altre risposte!


0

Questo è quello che ho finito per fare:

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

Non sono sicuro che qualcuno abbia provato la mia soluzione. Questo funziona su tutto il corpo / html ma senza dubbio può essere applicato a qualsiasi elemento che genera un evento scroll.

Basta impostare e deselezionare scrollLock di cui hai bisogno.

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

Ecco l'esempio JSFiddle

Spero che questo aiuti qualcuno.


Questo funziona come dovrebbe, con una sola eccezione. Quando lo scorrimento è bloccato, e io scorro, si contrae un po ', prima di bloccare effettivamente lo scorrimento ...
Thomas Teilmann,

0

Penso che la soluzione migliore e pulita sia:

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

E con jQuery:

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

Quel listener di eventi dovrebbe bloccare lo scorrimento. Basta rimuoverli per riattivare lo scorrimento

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.