Come disabilitare temporaneamente lo scorrimento?


435

Sto usando il plugin scrollTo jQuery e vorrei sapere se è possibile disabilitare temporaneamente lo scorrimento dell'elemento della finestra tramite Javascript? Il motivo per cui mi piacerebbe disabilitare lo scorrimento è che quando si scorre mentre scrollTo si sta animando, diventa davvero brutto;)

Certo, potrei fare un $("body").css("overflow", "hidden");e poi rimetterlo in automatico quando l'animazione si ferma, ma sarebbe meglio se la barra di scorrimento fosse ancora visibile ma inattiva.


12
Se continua a mostrare, l'utente viene addestrato a pensare che deve funzionare. Se la dose non si sposta o la dose non risponde, interromperà il modello mentale degli utenti su come funziona la pagina e causerà confusione. Vorrei solo trovare un modo migliore di gestire lo scorrimento durante l'animazione, come ad esempio interrompere l'animazione.
Marcus Whybrow,

Risposte:


731

L' scrollevento non può essere cancellato. Ma puoi farlo annullando questi eventi di interazione:
mouse e touch scroll e pulsanti associati allo scorrimento.

[ Demo funzionante ]

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};

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

function preventDefaultForScrollKeys(e) {
  if (keys[e.keyCode]) {
    preventDefault(e);
    return false;
  }
}

// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () { supportsPassive = true; } 
  }));
} catch(e) {}

var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';

// call this to Disable
function disableScroll() {
  window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
  window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
  window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
  window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}

// call this to Enable
function enableScroll() {
  window.removeEventListener('DOMMouseScroll', preventDefault, false);
  window.removeEventListener(wheelEvent, preventDefault, wheelOpt); 
  window.removeEventListener('touchmove', preventDefault, wheelOpt);
  window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}

AGGIORNAMENTO: fisso Chrome desktop e moderni browser mobili con ascoltatori passivi


114
Suggerimento per altri sviluppatori bloccati in questa trappola: assicurati di rimuovere tutte le chiamate "e.stopPropagation ()" da altri tentativi di jQuery di interrompere lo scorrimento, perché non solo non funziona, ma impedisce all'evento di passare a questo codice che funziona. Spero che i miei 30 minuti sprecati aiuteranno a risparmiare qualcun altro tempo :)
Dirk van Bergen,

4
È possibile aggiungere 32 (spazio) all'array di chiavi disabilitate (mostra nei commenti sul codice).
gblazex,

14
Posso scorrere come faccio sempre: usando il tasto centrale e muovendo il mouse ... Quindi questo trucco non influenzerà utenti come me;)
Denis V

11
La barra di scorrimento non è disabilitata.
verismo,

8
Questo non funziona più su Chrome
PerrierCitror il

428

Fallo semplicemente aggiungendo una classe al corpo:

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

Aggiungi la classe quindi rimuovi quando desideri riattivare lo scorrimento, testato in IE, FF, Safari e Chrome.

$('body').addClass('stop-scrolling')

Per i dispositivi mobili , dovrai gestire l' touchmoveevento:

$('body').bind('touchmove', function(e){e.preventDefault()})

E rilassati per riattivare lo scorrimento. Testato su iOS6 e Android 2.3.3

$('body').unbind('touchmove')

4
Fatto! Devi gestire l' touchmoveevento, come con $('body').bind('touchmove', function(e){e.preventDefault()}). Modificata questa risposta per includere questa soluzione mobile.
MusikAnimal

3
Bene, devi solo assicurarti che qualsiasi scorrimento interno possa funzionare nel modale per il dispositivo touch. Potrebbe fare una sovrapposizione appena sotto il modale e impedire il touchmove predefinito sulla sovrapposizione anziché sul corpo.
ciao

63
Mentre questa soluzione funziona, ha l'effetto (potenzialmente) indesiderato di tornare all'inizio della pagina.
Matt,

3
Questo non ha funzionato per me a meno che il mio selettore non fosse$('body,html')
PickYourPoison il

22
Questa soluzione funziona ma la barra di scorrimento scompare e crea un effetto 'bump' (sotto il sistema operativo della finestra) quando applichi questa classe al corpo (ad esempio)
Georgio

57

Ecco un modo davvero semplice per farlo:

window.onscroll = function () { window.scrollTo(0, 0); };

È un po 'nervoso in IE6.


14
Non proprio una disabilitazione, più come uno schiocco di default quando si tenta di scorrere.
Marcus Whybrow,

11
@Marcus Buono come sarà con un evento che non è cancellabile.
sdleihssirhc,

3
Anche se non lo disabilita per davvero, lo simula e questo è abbastanza buono per me.
Chris Bier,

11
IMHO - la migliore risposta qui. Inoltre, non è necessario bloccarlo su (0, 0), basta usare la posizione di scorrimento corrente.
YemSalat,

4
Ma come possiamo riattivarlo?
Cibernetico,

41

La seguente soluzione è JavaScript semplice ma puro (no jQuery):

function disableScrolling(){
    var x=window.scrollX;
    var y=window.scrollY;
    window.onscroll=function(){window.scrollTo(x, y);};
}

function enableScrolling(){
    window.onscroll=function(){};
}

3
Jumpy in Safari 7.1 e IE 11. Più recenti Chrome, Firefox, Opera ok.
Timo Kähkönen,

Ancora un po 'nervoso sul nuovissimo Chrome
Jason Allshorn il

Funziona bene, in Safari, Chrome, ma sfarfallato in IE
Bhuvan Arora

Se questa soluzione non funziona per alcuni browser, questo è un problema con i browser
Oto Shavadze,

Come accennato in un'altra risposta, scroll-behavior: smoothquesto borks. Inoltre, non sono d'accordo con Oto nel dire che è colpa del browser. Fondamentalmente stai assumendo che qualcosa accadrà all'istante quando in realtà è asincrono
Matt Fletcher

25

Questa soluzione manterrà la posizione di scorrimento corrente mentre lo scorrimento è disabilitato, a differenza di alcuni che riportano l'utente all'inizio.

Si basa sulla risposta di galambalazs , ma con il supporto per i dispositivi touch e refactored come un singolo oggetto con il wrapper del plugin jquery.

Demo qui.

Su github qui.

/**
 * $.disablescroll
 * Author: Josh Harrison - aloof.co
 *
 * Disables scroll events from mousewheels, touchmoves and keypresses.
 * Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
 */

;(function($) {

    "use strict";

    var instance, proto;

    function UserScrollDisabler($container, options) {
        // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
        // left: 37, up: 38, right: 39, down: 40
        this.opts = $.extend({
            handleKeys : true,
            scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
        }, options);

        this.$container = $container;
        this.$document = $(document);
        this.lockToScrollPos = [0, 0];

        this.disable();
    }

    proto = UserScrollDisabler.prototype;

    proto.disable = function() {
        var t = this;

        t.lockToScrollPos = [
            t.$container.scrollLeft(),
            t.$container.scrollTop()
        ];

        t.$container.on(
            "mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
            t._handleWheel
        );

        t.$container.on("scroll.disablescroll", function() {
            t._handleScrollbar.call(t);
        });

        if(t.opts.handleKeys) {
            t.$document.on("keydown.disablescroll", function(event) {
                t._handleKeydown.call(t, event);
            });
        }
    };

    proto.undo = function() {
        var t = this;
        t.$container.off(".disablescroll");
        if(t.opts.handleKeys) {
            t.$document.off(".disablescroll");
        }
    };

    proto._handleWheel = function(event) {
        event.preventDefault();
    };

    proto._handleScrollbar = function() {
        this.$container.scrollLeft(this.lockToScrollPos[0]);
        this.$container.scrollTop(this.lockToScrollPos[1]);
    };

    proto._handleKeydown = function(event) {
        for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
            if (event.keyCode === this.opts.scrollEventKeys[i]) {
                event.preventDefault();
                return;
            }
        }
    };


    // Plugin wrapper for object
    $.fn.disablescroll = function(method) {

        // If calling for the first time, instantiate the object and save
        // reference. The plugin can therefore only be instantiated once per
        // page. You can pass options object in through the method parameter.
        if( ! instance && (typeof method === "object" || ! method)) {
            instance = new UserScrollDisabler(this, method);
        }

        // Instance already created, and a method is being explicitly called,
        // e.g. .disablescroll('undo');
        else if(instance && instance[method]) {
            instance[method].call(instance);
        }

    };

    // Global access
    window.UserScrollDisabler = UserScrollDisabler;

})(jQuery);

Sono contento che sia utile. NB Ho modificato con un link a questo in formato plug-in jQuery .
Josh Harrison,

Potrebbe essere d'aiuto se il pulsante di scorrimento disabilita effettivamente funzionasse
cameronjonesweb

@ user1672694, funziona qui in Chrome. Qual è il tuo browser e su quale pagina demo hai trovato il bug? Eventuali errori JS nella console?
Josh Harrison,

Su Chrome (38, Windows 7), posso ancora scorrere facendo clic e tenendo premuto il pulsante centrale, quindi trascinando.
Sethi,

1
Si prega di ignorare, ho scoperto che legare ha mousewheelfunzionato un incanto
Adamj

17

Mi dispiace rispondere a un vecchio post ma stavo cercando una soluzione e ho trovato questa domanda.

Esistono molte soluzioni alternative per questo problema per visualizzare ancora la barra di scorrimento, come dare al contenitore un'altezza del 100% e un overflow-y: scroll stile.

Nel mio caso ho appena creato un div con una barra di scorrimento che visualizzo mentre aggiungo overflow: hiddenal corpo:

function disableScroll() {
    document.getElementById('scrollbar').style.display = 'block';
    document.body.style.overflow = 'hidden';
}

La barra di scorrimento dell'elemento deve avere questi stili:

overflow-y: scroll; top: 0; right: 0; display: none; height: 100%; position: fixed;

Questo mostra una barra di scorrimento grigia, spero che aiuti i futuri visitatori.


8

Stavo cercando una soluzione a questo problema, ma non ero soddisfatto delle soluzioni di cui sopra (al momento di scrivere questa risposta ), quindi ho trovato questa soluzione ..

CSS

.scrollDisabled {   
    position: fixed;
    margin-top: 0;// override by JS to use acc to curr $(window).scrollTop()
    width: 100%;
}

JS

var y_offsetWhenScrollDisabled=0;

function disableScrollOnBody(){
    y_offsetWhenScrollDisabled= $(window).scrollTop();
    $('body').addClass('scrollDisabled').css('margin-top', -y_offsetWhenScrollDisabled);
}
function enableScrollOnBody(){
    $('body').removeClass('scrollDisabled').css('margin-top', 0);
    $(window).scrollTop(y_offsetWhenScrollDisabled);
}

Ho scoperto che ha funzionato per me se ho aggiunto overflow-y: scrollallo .scrollDisabledstile. Altrimenti, c'è stato un piccolo salto mentre la barra di scorrimento si nascondeva ogni volta. Certo, questo funziona solo per me perché la mia pagina è abbastanza lunga da richiedere una barra di scorrimento anche sui display più grandi.
Andrew Miner,

7

Secondo il post di galambalaz aggiungerei il supporto per i dispositivi touch, permettendoci di toccare ma senza scorrere verso l'alto o verso il basso:

function disable_scroll() {
   ...
   document.ontouchmove = function(e){ 
        e.preventDefault(); 
   }
}

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}

3
Sei sicuro che sia una risposta, non solo un commento di un'altra risposta?
IvanH,

6

A partire da Chrome 56 e altri browser moderni, devi aggiungere passive:falsealla addEventListenerchiamata per preventDefaultfunzionare. Quindi lo uso per interrompere lo scorrimento su dispositivo mobile:

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

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}

5

No, non andrei con la gestione degli eventi perché:

  • non tutti gli eventi sono garantiti per raggiungere il corpo,

  • selezionando il testo e spostandolo verso il basso si scorre effettivamente il documento,

  • se nella fase dell'evento il distacco di sth va storto sei condannato.

L'ho morso facendo un'azione copia-incolla con un'area di testo nascosta e indovinate un po ', la pagina scorre ogni volta che faccio una copia perché internamente devo selezionare l'area di testo prima di chiamare document.execCommand('copy').

Ad ogni modo è così che mi accorgo setTimeout():

document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);

Un momentum lampeggiante esiste quando le barre di scorrimento scompaiono momentaneamente, ma è accettabile.


4

A seconda di ciò che si desidera ottenere con lo scorrimento rimosso, è possibile semplicemente correggere l'elemento da cui si desidera rimuovere lo scorrimento (al clic o qualsiasi altro trigger che si desidera disattivare temporaneamente lo scorrimento)

Stavo cercando una soluzione "temp no scroll" e per i miei bisogni, questo ha risolto

fare una lezione

.fixed{
    position: fixed;
}

poi con Jquery

var someTrigger = $('#trigger'); //a trigger button
var contentContainer = $('#content'); //element I want to temporarily remove scroll from

contentContainer.addClass('notfixed'); //make sure that the element has the "notfixed" class

//Something to trigger the fixed positioning. In this case we chose a button.
someTrigger.on('click', function(){

    if(contentContainer.hasClass('notfixed')){
        contentContainer.removeClass('notfixed').addClass('fixed');

    }else if(contentContainer.hasClass('fixed')){
        contentContainer.removeClass('fixed').addClass('notfixed');
    };
});

Ho scoperto che si trattava di una soluzione abbastanza semplice che funziona bene su tutti i browser e consente anche un semplice utilizzo su dispositivi portatili (ad esempio iPhone, tablet ecc.). Poiché l'elemento è temporaneamente risolto, non c'è scorrimento :)

NOTA! A seconda del posizionamento dell'elemento "contentContainer", potrebbe essere necessario regolarlo da sinistra. Che può essere fatto facilmente aggiungendo un valore css a sinistra a quell'elemento quando la classe fissa è attiva

contentContainer.css({
    'left': $(window).width() - contentContainer.width()/2 //This would result in a value that is the windows entire width minus the element we want to "center" divided by two (since it's only pushed from one side)
});

4

Un'altra soluzione:

body {
    overflow-y: scroll;
    width: 100%;
    margin: 0 auto;
}

In questo modo hai sempre una barra di scorrimento verticale, ma poiché la maggior parte dei miei contenuti è più lunga della finestra, per me va bene. Il contenuto è centrato con un div separato, ma senza impostare nuovamente il margine nel corpo il mio contenuto rimarrebbe a sinistra.

Queste sono le due funzioni che utilizzo per mostrare il mio popup / modale:

var popup_bodyTop = 0;
var popup_bodyLeft = 0;

function popupShow(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');

    // remember current scroll-position
    // because when setting/unsetting position: fixed to body
    // the body would scroll to 0,0
    popup_bodyLeft = $(document).scrollLeft();
    popup_bodyTop  = $(document).scrollTop();

    // invert position
    var x = - popup_bodyLeft;
    var y = - popup_bodyTop;

    $('body').css('position', 'fixed');
    $('body').css('top', y.toString() +'px');
    $('body').css('left', x.toString() +'px');
}

function popupHide(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');
    $('body').css('position', '');
    $('html, body').scrollTop(popup_bodyTop);
    $('html, body').scrollLeft(popup_bodyLeft);
}

Risultato: sfondo non scorrevole e nessun riposizionamento del contenuto grazie alla barra di scorrimento sinistra. Testato con FF, Chrome e IE 10 attuali.


Questo ha funzionato per me e il problema di scorrere verso l'alto dopo aver utilizzato position: fixed. Grazie!
Annia Martinez,

3

Cosa ne pensi di questo? (Se stai usando jQuery)

var $window = $(window);
var $body = $(window.document.body);

window.onscroll = function() {
    var overlay = $body.children(".ui-widget-overlay").first();

    // Check if the overlay is visible and restore the previous scroll state
    if (overlay.is(":visible")) {
        var scrollPos = $body.data("scroll-pos") || { x: 0, y: 0 };
        window.scrollTo(scrollPos.x, scrollPos.y);
    }
    else {
        // Just store the scroll state
        $body.data("scroll-pos", { x: $window.scrollLeft(), y: $window.scrollTop() });
    }
};

un po 'nervoso, ma questo funziona per IE 7 (il client lo usa). altre soluzioni no.
niki b,

3

Sto usando showModalDialog , per mostrare la pagina secondaria come finestra di dialogo modale.

per nascondere le barre di scorrimento della finestra principale:

document.body.style.overflow = "hidden";

e quando si chiude la finestra di dialogo modale, mostrando le barre di scorrimento della finestra principale:

document.body.style.overflow = "scroll";

per accedere agli elementi nella finestra principale dalla finestra di dialogo:

parent.document.getElementById('dialog-close').click();

solo per chiunque cerchi showModalDialog : (dopo la riga 29 del codice originale)

document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.body.style.overflow = "hidden";//****
document.getElementById('dialog-close').addEventListener('click', function(e) {
    e.preventDefault();
    document.body.style.overflow = "scroll";//****
    dialog.close();
});

Questo ha funzionato per me in React in cui jQuery è inesistente e in cui React non ha accesso per gestire lo stato del tag body.
Jon,

3

Annullare l'evento come nella risposta accettata è un metodo orribile secondo me: /

Invece ho usato di position: fixed; top: -scrollTop();seguito.

Demo: https://jsfiddle.net/w9w9hthy/5/

Dal mio progetto popup jQuery: https://github.com/seahorsepip/jPopup

//Freeze page content scrolling
function freeze() {
    if($("html").css("position") != "fixed") {
        var top = $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop();
        if(window.innerWidth > $("html").width()) {
            $("html").css("overflow-y", "scroll");
        }
        $("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top});
    }
}

//Unfreeze page content scrolling
function unfreeze() {
    if($("html").css("position") == "fixed") {
        $("html").css("position", "static");
        $("html, body").scrollTop(-parseInt($("html").css("top")));
        $("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""});
    }
}

Questo codice prende in considerazione i problemi di larghezza, altezza, barra di scorrimento e pagejump.

Possibili problemi risolti con il codice sopra:

  • larghezza, quando l'impostazione della posizione fissa, la larghezza dell'elemento html può essere inferiore al 100%
  • altezza, come sopra
  • barra di scorrimento, quando si imposta la posizione fissa il contenuto della pagina non ha più una barra di scorrimento anche quando aveva una barra di scorrimento prima di provocare un salto di pagina orizzontale
  • pagejump, quando l'impostazione della posizione è stata riparata, lo scrolling della pagina non è più efficace con conseguente salto verticale della pagina

Se qualcuno ha qualche miglioramento al codice di congelamento / sblocco della pagina precedente, fammi sapere in modo da poter aggiungere tali miglioramenti al mio progetto.


3
var winX = null, winY = null;
window.addEventListener('scroll', function () {
    if (winX !== null && winY !== null) {
        window.scrollTo(winX, winY);
    }
});
function disableWindowScroll() {
    winX = window.scrollX;
    winY = window.scrollY;
};
function enableWindowScroll() {
    winX = null;
    winY = null;
};

1
Questa è la soluzione migliore qui.
jfunk il

@jfunk d'accordo, semplice e conciso, piccolo codice, perfetto. Grazie
Florent Roques

2

Ho lo stesso problema, di seguito è il modo in cui lo gestisco.

/* file.js */
var body = document.getElementsByTagName('body')[0];
//if window dont scroll
body.classList.add("no-scroll");
//if window scroll
body.classList.remove("no-scroll");

/* file.css */
.no-scroll{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

spero che questo aiuto.


1

Basandomi sulla risposta di Cheyenne Forbes, e quella che ho trovato qui tramite fcalderan: basta disabilitare lo scroll non nasconderlo? e per risolvere il problema di scomparsa della barra di scorrimento di Hallodom

CSS:

.preventscroll{
    position: fixed;
    overflow-y:scroll;
}

JS:

whatever.onclick = function(){
    $('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
    $('body').removeClass('preventscroll');
}

Questo codice ti porta in cima alla pagina, ma penso che il codice di fcalderan abbia una soluzione alternativa.


1

So che questa è una vecchia domanda, ma ho dovuto fare qualcosa di molto simile, e dopo un po 'di tempo cercando una risposta e provando approcci diversi, ho finito per usare una soluzione molto semplice.

Il mio problema era molto simile, quasi identico, l'unica differenza è che non dovevo davvero mostrare la barra di scorrimento - dovevo solo assicurarmi che la sua larghezza fosse ancora utilizzata, quindi la larghezza della pagina non cambierebbe mentre il mio overlay era visualizzato .

Quando inizio a far scorrere il mio overlay sullo schermo, faccio:

$('body').addClass('stop-scrolling').css('margin-right', 8);

e dopo aver fatto scorrere il mio overlay dallo schermo faccio:

$('body').removeClass('stop-scrolling').css('margin-right', 0);

IMPORTANTE: funziona perfettamente perché il mio overlay è posizionato absolute, right: 0pxquando visible.


1

Il metodo più semplice è:

$("body").css("overflow", "hidden"); // Remove the scroll bar temporarily

Per annullarlo:

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

Facile da implementare, ma l'unico aspetto negativo è:

  • La pagina salterà un po 'a sinistra se è allineata al centro (in orizzontale).

Ciò è dovuto alla rimozione della barra di scorrimento e alla visualizzazione della finestra leggermente più ampia.


1
che ripristinerà la posizione di scorrimento
Angelo David Calderaro Pacciott,

@AngelDavidCalderaroPacciott No, la posizione di scorrimento rimarrà alla stessa altezza / distanza.
Daan,

@Daan ripristina la posizione di scorrimento su Chrome
Tom,

@Tom L'ho appena controllato, lo fa solo in alcune occasioni (quando l'altezza del corpo non è relativa ai suoi figli). Prova invece bodya cambiare htmlinvece.
Daan,

Scommetto che non hai controllato la tua soluzione in Iphone perché overflow:hiddennon funziona lì
Shuvo

1

Ecco la mia soluzione per interrompere lo scorrimento (no jQuery). Lo uso per disabilitare lo scorrimento quando appare il menu laterale.

<button onClick="noscroll()" style="position:fixed; padding: 8px 16px;">Disable/Enable scroll</button>
<script>
var noscroll_var;
function noscroll(){
  if(noscroll_var){
    document.getElementsByTagName("html")[0].style.overflowY = "";
    document.body.style.paddingRight = "0";
    noscroll_var = false
  }else{
    document.getElementsByTagName("html")[0].setAttribute('style', 'overflow-y: hidden !important');
    document.body.style.paddingRight = "17px";
    noscroll_var = true
  }
}/*noscroll()*/
</script>

<!-- Just to fill the page -->
<script>
  for(var i=0; i <= 80; i++){
    document.write(i + "<hr>")
  }
</script>

Ho messo 17 px di imbottitura a destra per compensare la scomparsa della barra di scorrimento. Ma questo è anche problematico, principalmente per i browser mobili. Risolto ottenendo la larghezza della barra secondo questo .

Tutti insieme in questa penna.



1

Questa è la soluzione più semplice che ho ottenuto finora. E credimi, ho provato tutti gli altri e questo è il più semplice. Funziona alla grande sui dispositivi Windows , che spingono la pagina da destra per avere spazio per la barra di scorrimento del sistema e i dispositivi IOS che non richiedono spazio per le loro barre di scorrimento nei browser. Quindi, usando questo non sarà necessario aggiungere il padding a destra in modo che la pagina non sfarfallio quando si nasconde il trabocco del corpo o HTML con CSS .

La soluzione è piuttosto semplice se ci pensi. L'idea è di dare a window.scrollTop () la stessa posizione esatta nel momento in cui viene aperto un popup. Cambia anche quella posizione quando la finestra si ridimensiona (quando la posizione di scorrimento cambia una volta che succede).

Quindi eccoci qui ...

Innanzitutto, crea la variabile che ti farà sapere che il popup è aperto e chiamalo stopWindowScroll . Se non lo facciamo, otterrai un errore di una variabile non definita sulla tua pagina e la imposti a 0 - come non attiva.

$(document).ready(function(){
    stopWindowScroll = 0;
});

Ora consente di rendere la funzione popup aperta che strega può essere qualsiasi funzione nel codice che attiva qualsiasi popup che si sta utilizzando come plug-in o personalizzato. In questo caso sarà un semplice popup personalizzato con una semplice funzione di documento al clic.

$(document).on('click','.open-popup', function(){
    // Saving the scroll position once opening the popup.
    stopWindowScrollPosition = $(window).scrollTop();
    // Setting the stopWindowScroll to 1 to know the popup is open.
    stopWindowScroll = 1;
    // Displaying your popup.
    $('.your-popup').fadeIn(300);
});

Quindi la prossima cosa che facciamo è creare la funzione popup vicino, che ripeto ancora, può essere qualsiasi funzione che hai già creato o che stai usando in un plugin. L'importante è che abbiamo bisogno di quelle 2 funzioni per impostare la variabile stopWindowScroll su 1 o 0 per sapere quando è aperta o chiusa.

$(document).on('click','.open-popup', function(){
    // Setting the stopWindowScroll to 0 to know the popup is closed.
    stopWindowScroll = 0;
    // Hiding your popup
    $('.your-popup').fadeOut(300);
});

Quindi, consente di creare la funzione window.scroll in modo da poter impedire lo scorrimento quando lo stopWindowScroll sopra menzionato è impostato su 1 - come attivo.

$(window).scroll(function(){
    if(stopWindowScroll == 1) {
         // Giving the window scrollTop() function the position on which
         // the popup was opened, this way it will stay in its place.
         $(window).scrollTop(stopWindowScrollPosition);
    }
});

Questo è tutto. Nessun CSS richiesto per farlo funzionare tranne i tuoi stili per la pagina. Questo ha funzionato come un incantesimo per me e spero che aiuti te e gli altri.

Ecco un esempio funzionante su JSFiddle:

Esempio di violino JS

Fammi sapere se ti è stato d'aiuto. Saluti.


1

Memorizza la lunghezza di scorrimento in una variabile globale e ripristinala quando necessario!

var sctollTop_length = 0;

function scroll_pause(){
  sctollTop_length = $(window).scrollTop();
  $("body").css("overflow", "hidden");
}

function scroll_resume(){
  $("body").css("overflow", "auto");
  $(window).scrollTop(sctollTop_length);
}

1

Questo codice funzionerà su Chrome 56 e versioni successive (la risposta originale non funziona più su Chrome).

Uso DomUtils.enableScroll() per abilitare lo scorrimento.

Utilizzare DomUtils.disableScroll()per disabilitare lo scorrimento.

class DomUtils {
  // left: 37, up: 38, right: 39, down: 40,
  // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
  static keys = { 37: 1, 38: 1, 39: 1, 40: 1 };

  static preventDefault(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;
  }

  static preventDefaultForScrollKeys(e) {
    if (DomUtils.keys[e.keyCode]) {
      DomUtils.preventDefault(e);
      return false;
    }
  }

  static disableScroll() {
    document.addEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Disable scrolling in Chrome
    document.addEventListener('keydown', DomUtils.preventDefaultForScrollKeys, {
      passive: false,
    });
  }

  static enableScroll() {
    document.removeEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Enable scrolling in Chrome
    document.removeEventListener(
      'keydown',
      DomUtils.preventDefaultForScrollKeys,
      {
        passive: false,
      }
    ); // Enable scrolling in Chrome
  }
}

1

Per evitare il salto, questo è quello che ho usato

export function toggleBodyScroll(disable) {
  if (!window.tempScrollTop) {
    window.tempScrollTop = window.pageYOffset; 
    // save the current position in a global variable so I can access again later

  }
  if (disable) {
    document.body.classList.add('disable-scroll');
    document.body.style.top = `-${window.tempScrollTop}px`;
  } else {
    document.body.classList.remove('disable-scroll');
    document.body.style.top = `0px`;
    window.scrollTo({top: window.tempScrollTop});
    window.tempScrollTop = 0;
  }
}

e nel mio css

.disable-scroll {
  height: 100%;
  overflow: hidden;
  width: 100%;
  position: fixed;
}

0

Ho trovato questa risposta su un altro sito :

Disabilita scorrimento:

$( ".popup").live({
    popupbeforeposition: function(event, ui) {
    $("body").on("touchmove", false);
}
});

Dopo aver chiuso il popup di rilascio, scorrere:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});

Questo sembra fermare solo lo scorrimento del tocco, ma lo scorrimento del mouse, i tasti freccia, i tasti su e giù della pagina, ecc. Funzioneranno comunque. -1
markasoftware il

Questi "eventi" sono per lo scorrimento del tocco, basta sostituire qualsiasi evento di cui hai bisogno.
pennstump,

1
inoltre, questo sembra essere usato in qualche altra situazione molto specifica. popupbeforeposition? Per cosa dovrebbe essere? Che cosa ha a che fare con la disabilitazione temporanea dello scorrimento? Almeno renderlo rilevante per questa situazione. Sembra che tu l'abbia copiato direttamente da un sito Web.
markasoftware il

0

la soluzione di galambalazs è fantastica! Ha funzionato perfettamente per me sia su Chrome che su Firefox. E può anche essere esteso per impedire qualsiasi evento predefinito dalla finestra del browser. Diciamo che stai facendo un'app sulla tela. Potresti farlo:

var events = {
  preventDefault: function(e) {
    e = e || window.event;
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false;  
  },

  //spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
  //left: 37, up: 38, right: 39, down: 40
  keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
  keydown: function(e) {
    for (var i = events.keys.length; i--;) {
      if (e.keyCode === events.keys[i]) {
        events.preventDefault(e);
        return;
      }
    }
  },

  wheel: function(e) {
    events.preventDefault(e);
  },

  disable: function() {
    if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = events.wheel;
    document.onkeydown = helpers.events.keydown;
  },

  enable: function() {
    if (window.removeEventListener) {
      window.removeEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = document.onkeydown = null;  
  }
}

E quindi sulla tua app diciamo che elaborerai i tuoi eventi, come mouse, tastiera, eventi touch e così via ... Potresti disabilitare gli eventi predefiniti quando il mouse entra nell'area di disegno e riattivarli quando il mouse esce:

function setMouseEvents(canvas) {
  var useCapture = false;

  //Mouse enter event
  canvas.addEventListener('mouseenter', function(event) {
    events.disable();
  }, useCapture);

  //Mouse leave event
  canvas.addEventListener('mouseleave', function(event) {
    events.enable();
  }, useCapture);
}

Puoi anche disabilitare il menu del tasto destro con questo trucco:

function disableRightClickMenu(canvas) {
  var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
  my_gradient.addColorStop(0, "white");
  my_gradient.addColorStop(1, "white");
  canvas.context.fillStyle = my_gradient;
  canvas.context.fillRect(0, 0, canvas.width, canvas.height);
  canvas.oncontextmenu = function() { return false; };
}

0

Ho avuto un problema di animazione simile su schermi mobili ma non su laptop, quando provavo ad animare un div usando il comando animato di jquery. Così ho deciso di utilizzare un timer che ripristinava la posizione di scorrimento della finestra così frequentemente che ad occhio nudo il documento appariva statico. Questa soluzione ha funzionato perfettamente su un dispositivo mobile di piccolo schermo come Samsung Galaxy-2 o iPhone-5.

Logica principale di questo approccio : il timer per impostare la posizione di scorrimento della finestra sulla posizione di scorrimento originale deve essere avviato prima del comando animate jquery, quindi quando l'animazione è completata dobbiamo cancellare questo timer ( original scroll positionè la posizione appena prima che inizi l'animazione).

Con mia piacevole sorpresa ho scoperto che il documento sembrava effettivamente statico durante la durata dell'animazione se l'intervallo del timer era 1 millisecond, che era quello a cui stavo mirando.

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
    window.scrollTo(xPosition, yPosition);
}, 1);

//animate the element emt
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //when animation completes, we stop the timer
    clearInterval(restoreTimer);
});

Un'altra soluzione che ha funzionato : in base alla risposta di Mohammad Anini in questo post per abilitare / disabilitare lo scorrimento, ho anche scoperto che una versione modificata del codice come sotto funzionava.

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//disable scrolling
window.onscroll = function() {
    window.scrollTo(xPosition, yPosition);
};

//animate and enable scrolling when animation is completed
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //enable scrolling when animation is done
    window.onscroll = function() {};
});

0

Una soluzione semplice che ha funzionato per me (disabilitando temporaneamente lo scorrimento delle finestre).

Basato su questo violino: http://jsfiddle.net/dh834zgw/1/

il frammento seguente (usando jquery) disabiliterà lo scorrimento della finestra:

 var curScrollTop = $(window).scrollTop();
 $('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

E nel tuo css:

html.noscroll{
    position: fixed;
    width: 100%;
    top:0;
    left: 0;
    height: 100%;
    overflow-y: scroll !important;
    z-index: 10;
 }

Ora, quando rimuovi il modale, non dimenticare di rimuovere la classe noscroll dal tag html:

$('html').toggleClass('noscroll');
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.