Pregunta ¿Cómo deshabilitar el desplazamiento temporalmente?


Estoy usando el plugin scrollTo jQuery y me gustaría saber si de alguna manera es posible deshabilitar temporalmente el desplazamiento en el elemento de la ventana a través de Javascript. La razón por la que me gustaría deshabilitar el desplazamiento es que cuando se desplaza mientras scrollTo está animando, se vuelve realmente feo;)

Por supuesto, podría hacer una $("body").css("overflow", "hidden"); y luego vuelva a ponerlo en automático cuando la animación se detenga, pero sería mejor si la barra de desplazamiento aún estuviera visible pero inactiva.


360
2018-01-22 19:23


origen


Respuestas:


los scroll evento no puede ser cancelado Pero puedes hacerlo cancelado estos eventos de interacción:
Ratón  &  Desplazamiento táctil y Botones asociado con el desplazamiento.

[Demostración de trabajo]

// 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 = e || window.event;
  if (e.preventDefault)
      e.preventDefault();
  e.returnValue = false;  
}

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

function disableScroll() {
  if (window.addEventListener) // older FF
      window.addEventListener('DOMMouseScroll', preventDefault, false);
  window.onwheel = preventDefault; // modern standard
  window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
  window.ontouchmove  = preventDefault; // mobile
  document.onkeydown  = preventDefaultForScrollKeys;
}

function enableScroll() {
    if (window.removeEventListener)
        window.removeEventListener('DOMMouseScroll', preventDefault, false);
    window.onmousewheel = document.onmousewheel = null; 
    window.onwheel = null; 
    window.ontouchmove = null;  
    document.onkeydown = null;  
}

622
2018-01-22 19:55



Hazlo simplemente agregando una clase al cuerpo:

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

Agregue la clase y luego elimine cuando desee volver a habilitar el desplazamiento, probado en IE, FF, Safari y Chrome.

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

por dispositivos móviles, deberás manejar el touchmove evento:

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

Y desvincular para volver a habilitar el desplazamiento. Probado en iOS6 y Android 2.3.3

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

376
2017-08-23 10:58



Aquí hay una forma realmente básica de hacerlo:

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

Es un poco nervioso en IE6.


45
2018-01-22 19:29



Esta solución mantendrá la posición de desplazamiento actual mientras se deshabilita el desplazamiento, a diferencia de algunos que llevan al usuario de nuevo a la parte superior.

Está basado en la respuesta de galambalazs, pero con soporte para dispositivos táctiles, y refactorizado como un único objeto con envoltorio de plugin jquery.

Demostración aquí. 

En github aquí.

/**
 * $.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);

23
2018-02-03 17:25



La siguiente solución es JavaScript básico pero 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(){};
}

21
2017-10-03 21:21



Lamento responder una publicación anterior, pero estaba buscando una solución y encontré esta pregunta.

Hay muchas soluciones para este problema para mostrar la barra de desplazamiento, como dar al contenedor un 100% de altura y una overflow-y: scroll estilo.

En mi caso, acabo de crear un div con una barra de desplazamiento que visualizo al agregar overflow: hidden Al cuerpo:

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

El elemento barra de desplazamiento debe tener estos estilos:

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

Esto muestra una barra de desplazamiento gris, espero que ayude a los futuros visitantes.


14
2018-02-29 04:12



De acuerdo con la galambalazs Después de agregar, agregaría compatibilidad con dispositivos táctiles, lo que nos permite tocar, pero no desplazarnos hacia arriba o hacia abajo:

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

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

7
2017-08-23 13:33



Estaba buscando una solución a este problema, pero no estaba satisfecho con ninguna de las soluciones anteriores (al escribir esta respuesta), así que se me ocurrió esta solución ...

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

7
2017-11-09 08:46



Otra solución:

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

De esta manera, siempre tendrá una barra de desplazamiento vertical, pero como la mayoría de mi contenido es más largo que la ventana gráfica, esto está bien para mí. El contenido se centra con un div por separado, pero sin volver a establecer el margen en el cuerpo mi contenido se mantendrá a la izquierda.

Estas son las dos funciones que uso para mostrar mi ventana emergente / modal:

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

Resultado: fondo no desplazable y sin reposicionamiento del contenido debido a la barra de desplazamiento izquierda. Probado con FF actual, Chrome e IE 10.


4
2017-09-26 11:43