543 Stimmen

Wie kann man den Bildlauf vorübergehend deaktivieren?

Ich benutze das scrollTo jQuery-Plugin und würde gerne wissen, ob es irgendwie möglich ist, das Scrollen auf dem Fenster-Element durch Javascript vorübergehend zu deaktivieren? Der Grund, warum ich das Scrollen deaktivieren möchte, ist, dass, wenn Sie scrollen, während scrollTo animiert wird, wird es wirklich hässlich ;)

Natürlich könnte ich eine $("body").css("overflow", "hidden"); und dann wieder auf Auto stellen, wenn die Animation aufhört, aber es wäre besser, wenn die Bildlaufleiste weiterhin sichtbar, aber inaktiv wäre.

14 Stimmen

Wenn sie noch angezeigt wird, ist der Benutzer darauf trainiert, zu denken, dass sie funktionieren muss. Wenn es sich nicht bewegt oder nicht reagiert, wird das mentale Modell des Benutzers, wie die Seite funktioniert, durchbrochen und führt zu Verwirrung. Ich würde einfach einen besseren Weg finden, um mit dem Scrollen während der Animation umzugehen, z. B. die Animation zu stoppen.

0 Stimmen

25voto

Josh Harrison Punkte 5812

Bei dieser Lösung wird die aktuelle Bildlaufposition beibehalten, während der Bildlauf deaktiviert ist, im Gegensatz zu anderen Lösungen, bei denen der Benutzer an den Anfang zurückspringt.

Es basiert auf galambalazs' Antwort , aber mit Unterstützung für Touch-Geräte, und als ein einziges Objekt mit Jquery-Plugin-Wrapper refaktorisiert.

Demo hier.

Auf github hier.

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

0 Stimmen

Schön, dass es nützlich ist. NB Ich habe mit einem Link zu dieser Seite im jQuery-Plugin-Format .

0 Stimmen

Es wäre hilfreich, wenn die Taste zum Deaktivieren des Bildlaufs tatsächlich funktionieren würde.

0 Stimmen

@user1672694, es funktioniert hier in Chrome. Was ist Ihr Browser und auf welcher Demo-Seite haben Sie den Fehler gefunden? Gibt es JS-Fehler in der Konsole?

22voto

Văn Quyết Punkte 1969
var winX = null;
var 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;
}

7 Stimmen

Dies ist hier die beste Lösung.

0 Stimmen

@jfunk zustimmen, einfach und prägnant, kleiner Code, perfekt. Dankeschön

0 Stimmen

Für die Typsicherheit würde ich empfehlen, negative Zahlen anstelle von Null zu verwenden

8voto

Rajat Gupta Punkte 24634

Ich war auf der Suche nach einer Lösung für dieses Problem, war aber mit keiner der oben genannten Lösungen zufrieden ( zum Zeitpunkt der Erstellung dieser Antwort ), also habe ich mir diese Lösung ausgedacht

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

0 Stimmen

Ich fand heraus, dass dies bei mir funktionierte, wenn ich Folgendes hinzufügte overflow-y: scroll zum .scrollDisabled Stil. Ansonsten gab es jedes Mal einen kleinen Sprung, wenn die Bildlaufleiste ausgeblendet wurde. Natürlich funktioniert das nur bei mir, weil meine Seite lang genug ist, um selbst auf den größten Bildschirmen eine Bildlaufleiste zu benötigen.

8voto

cotneit Punkte 91

In dieser Antwort wird eine Lösung zur Beseitigung der "Beule" vorgeschlagen, die entsteht, wenn overflow: hidden vorgeschlagen in diese Lösung angewendet wird. Da eine Bearbeitung abgelehnt wurde, hier ist sie:


An die "Beule" entfernen das passiert, wenn overflow: hidden angewendet wird, können Sie die Breite der Bildlaufleiste berechnen und durch margin ersetzen. Hier ist ein Beispiel für die body Element:

const bodyScrollControls = {
  scrollBarWidth: window.innerWidth - document.body.clientWidth,

  disable() {
    document.body.style.marginRight = `${this.scrollBarWidth}px`;
    document.body.style.overflowY = 'hidden';
  },
  enable() {
    document.body.style.marginRight = null;
    document.body.style.overflowY = null;
  },
};

Wenn ein Element bereits über margin-right Es sollte kein Problem sein, eine vorhandene zu erhalten und die Breite des Rollbalkens zu erhöhen.

1 Stimmen

Dies war bei weitem die einfachste Lösung von allen. Ich danke Ihnen. Sie haben mir den Tag gerettet :D

7voto

Hokascha Punkte 1561

Ab Chrome 56 und anderen modernen Browsern müssen Sie Folgendes hinzufügen passive:false zum addEventListener Aufforderung zur Abgabe preventDefault Arbeit. Ich benutze dies, um das Scrollen auf dem Handy zu stoppen:

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X