So deaktivieren Sie programmgesteuert das Scrollen von Seiten mit jQuery

163

Mit jQuery möchte ich das Scrollen des Körpers deaktivieren:

Meine Idee ist:

  1. einstellen body{ overflow: hidden;}
  2. Erfassen Sie den Strom scrollTop();/scrollLeft()
  3. Binden Sie an das Body-Scroll-Ereignis und setzen Sie scrollTop / scrollLeft auf den erfassten Wert.

Gibt es einen besseren Weg?


Aktualisieren:

Bitte sehen Sie mein Beispiel und einen Grund dafür unter http://jsbin.com/ikuma4/2/edit

Ich bin mir bewusst, dass jemand denken wird, "warum verwendet er nicht nur position: fixedauf dem Panel?".

Bitte schlagen Sie dies nicht vor, da ich andere Gründe habe.

Hagelholz
quelle
7
"Gibt es einen besseren Weg?" - außer dass sich der Browser normal verhält?
Fenton
22
"melodramatisch"?
Mike Weller
6
Vielleicht programmatisch gemeint? Da es der Firefox Top Rechtschreibkorrekturvorschlag für 'programmatisch' ist
Michael Shimmins
4
Dieser Thread geht \ b \
Cipi
3
@Sohnee Deaktivieren des Bildlaufs! == schlecht
Mansiemans

Antworten:

136

Der einzige Weg, den ich gefunden habe, ist ähnlich dem, was Sie beschrieben haben:

  1. Erfassen Sie die aktuelle Bildlaufposition (horizontale Achse nicht vergessen!).
  2. Setzen Sie den Überlauf auf versteckt (wahrscheinlich möchten Sie den vorherigen Überlaufwert beibehalten).
  3. Scrollen Sie das Dokument mit scrollTo () zur gespeicherten Bildlaufposition.

Wenn Sie dann bereit sind, das Scrollen erneut zuzulassen, machen Sie alles rückgängig.

Bearbeiten: Kein Grund, warum ich Ihnen den Code nicht geben kann, da ich mir die Mühe gemacht habe, ihn auszugraben ...

// 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])
tfe
quelle
2
Bitte sehen Sie unter jsbin.com/ikuma4/2/edit nach und erklären Sie mir einen Grund, warum Ihre besser ist. Vermisse ich etwas (ich frage, da ich keinen Grund für die Länge Ihrer Antwort im Vergleich zu meinem Beispiel sehen kann)
Hailwood
3
Ihr Ansatz funktioniert in IE7 nicht. Das habe ich auch zuerst versucht. Das Problem ist, dass es nicht schnell genug auf das Bildlaufereignis reagiert. Das Dokument kann gescrollt und dann zurückgeschnappt werden, wenn Ihr JS die Bildlaufposition an die gewünschte Stelle zurücksetzt.
tfe
1
Wenn der Körper einen Überlauf von etwas anderem als hätte auto, würde er überschrieben. Ich musste die vorhandene Einstellung beibehalten, damit auch etwas Overhead entsteht.
tfe
Weiß jemand, warum einfaches Styling htmlund bodymit overflow: hiddennicht ausreichen? Am Ende brauchen wir immer noch den Event-Handler.
Kpozin
4
Dies ist eine fantastische Antwort. Lesen Sie diese Antwort , damit es auf Touch-Geräten funktioniert .
Patrick
235

Dadurch wird das Scrollen vollständig deaktiviert:

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

Etwas wiederherstellen:

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

Getestet auf Firefox und Chrome.

Gitaarik
quelle
18
funktioniert wie erwartet. Vielen Dank! Dies sollte die akzeptierte Antwort gewesen sein!
Dave Chen
6
Scrollt immer noch mit der mittleren Maustaste auf Chrom.
Lothar
16
Dies verliert die aktuelle Bildlaufposition. OP erwähnte ausdrücklich die Erfassung der Bildlaufposition, daher gehe ich davon aus, dass er dies benötigte. Wie auch immer, ich benötige es, daher ist dies für mich von begrenztem Nutzen
zerm
7
PS Wenn Sie das weglassen, wird das height: 100%Scrollen an der aktuellen Position ohne Springen effektiv gesperrt - zumindest auf dem neuesten Chrome.
Zerm
2
Dies ist NICHT die richtige Antwort. Die Bildlaufposition wird nicht erfasst
Taylorcressy
43

Versuche dies

$('#element').on('scroll touchmove mousewheel', function(e){
  e.preventDefault();
  e.stopPropagation();
  return false;
})
Cubbiu
quelle
genau das, wonach ich gesucht habe ... fast. Wie auch immer, um es während der Pfeiltasten zu deaktivieren?
Cody
2
@Cody - kombinieren Sie dies mit CSS-Überlauf: versteckt
Darius.V
2
@cubbiu wie man es umkehrt?
Meer
3
Sie können verwenden$('#element').off('scroll touchmove mousewheel');
Arnuschky
1
Tolle Lösung. Obwohl, wie würden Sie nur das bodyScrollen deaktivieren und dennoch das Scrollen in anderen untergeordneten Elementen zulassen, die haben overflow: scroll?
Fizzix
27

Ich stelle nur ein wenig die Lösung von tfe vor . Insbesondere habe ich ein zusätzliches Steuerelement hinzugefügt, um sicherzustellen, dass der Seiteninhalt nicht verschoben wird (auch als Seitenverschiebung bezeichnet ), wenn die Bildlaufleiste auf eingestellt ist hidden.

Zwei Javascript-Funktionen lockScroll()undunlockScroll() kann definiert werden, die jeweils zu sperren und die Seite blättern zu entsperren.

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

wo ich davon ausgegangen bin, dass die <body> keine anfängliche Marge hat.

Beachten Sie, dass die obige Lösung zwar in den meisten praktischen Fällen funktioniert, jedoch nicht endgültig ist, da für Seiten, die beispielsweise einen Header mit enthalten, weitere Anpassungen erforderlich sind position:fixed. Lassen Sie uns mit einem Beispiel auf diesen Sonderfall eingehen. Angenommen, zu haben

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

mit

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

Dann sollte man in Funktionen lockScroll()und Folgendes hinzufügen unlockScroll():

function lockScroll(){
    //Omissis   


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

function unlockScroll(){
    //Omissis   

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

Achten Sie abschließend auf einen möglichen Anfangswert für die Ränder oder Polster.

Jean Valjean
quelle
4
Sie haben einen Fehler in Ihrem Javascript $ body.css ({'margin-right': 0, 'margin-bottom', 0}); sollte $ body.css sein ({'margin-right': 0, 'margin-bottom': 0});
Johansrk
Eigentlich nur marginRightund marginLeft:)
Martijn
25

Sie können diesen Code verwenden:

$("body").css("overflow", "hidden");
mr.soroush
quelle
8
Sie können weiterhin mit der mittleren Maustaste scrollen.
Roger Far
2
Nein, das ist ok und keine Schriftrolle damit!
mr.soroush
Wenn Sie zusätzliches CSS verwenden, können Sie das Scrollen vollständig deaktivieren. Weitere Informationen finden Sie in meiner Antwort.
Gitaarik
21

Versuchen Sie Folgendes, um das Scrollen auszuschalten:

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

zurücksetzen:

$(window).off('scroll');
Patrick DaVader
quelle
Dies war eine fantastische Lösung für das, was ich brauchte.
Terry Carter
@EveryScreamer nein, es lässt den Bildschirm wie verrückt zittern. Versuch, eine Problemumgehung zu finden.
Telarian
5

Ich habe ein jQuery-Plugin geschrieben, um dies zu handhaben: $ .disablescroll .

Es verhindert das Scrollen von Mausrad-, Touchmove- und Tastendruckereignissen, wie z Page Down.

Hier gibt es eine Demo .

Verwendung:

$(window).disablescroll();

// To re-enable scrolling:
$(window).disablescroll("undo");
Josh Harrison
quelle
Ich habe versucht, Ihr Plugin disablescroll () zu verwenden, um das Scrollen vorübergehend zu deaktivieren, wenn Sie das Ereignis Mausrad / Scrollen hören, aber es funktioniert nicht. Gibt es eine Chance, dass Sie einen Weg kennen, um diesen Effekt zu erzielen?
Gelb-Heiliger
@JB Ich kann wahrscheinlich helfen, aber Kommentare sind nicht der beste Ort. Nehmen Sie an diesem Stapelüberlauf-Chat teil und ich werde sehen, was ich tun kann: chat.stackoverflow.com/rooms/55043/disablescroll-usage
Josh Harrison
Es tut mir leid, aber dieses Plugin funktioniert nicht einmal in Ihrer jsfiddle.
Markj
Sie können mir helfen, dies zu überprüfen, indem Sie mir mitteilen, in welchem ​​Browser / auf welcher Plattform es nicht zu funktionieren scheint.
Josh Harrison
5

Sie können eine Funktion anhängen, um Ereignisse zu scrollen und ihr Standardverhalten zu verhindern.

var $window = $(window);

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

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

https://jsfiddle.net/22cLw9em/

dzimi
quelle
1
Das ist die richtige Antwort. Ich weiß nicht, warum es nicht so eingestellt ist
Guilherme Ferreira
Es klappt.
Benötigt
4

Ein Liner zum Deaktivieren des Bildlaufs einschließlich der mittleren Maustaste.

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

edit : jQuery ist sowieso nicht erforderlich, unten wie oben in Vanilla JS (das heißt, keine Frameworks, nur JavaScript):

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

this.documentElement.scrollTop - Standard

this.body.scrollTop - IE-Kompatibilität

Pawel
quelle
4
  • So verstecken Sie die Schriftrolle: $("body").css("overflow", "hidden");
  • So stellen Sie den Bildlauf wieder her: $("body").css("overflow", "initial");
Joan Alberto Aguilar Peña
quelle
3

Kannst du nicht einfach die Körpergröße auf 100% einstellen und den Überlauf verbergen? Siehe http://jsbin.com/ikuma4/13/edit

Adrian Schmidt
quelle
$ ("html"). css ({Höhe: '100%', Überlauf: 'versteckt'}); Es funktioniert einfach, danke Adrian
Alexey
3

Jemand hat diesen Code gepostet, der das Problem hat, dass die Bildlaufposition bei der Wiederherstellung nicht beibehalten wird. Der Grund ist, dass Menschen dazu neigen, es auf HTML und Körper oder nur auf den Körper anzuwenden, aber es sollte nur auf HTML angewendet werden. Auf diese Weise bleibt die Bildlaufposition bei Wiederherstellung erhalten:

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

Etwas wiederherstellen:

$('html').css({
    'overflow': 'auto',
    'height': 'auto'
});
Mescalina
quelle
nicht 'overflow': 'auto',verwenden'overflow': 'initial',
evtuhovdo
2

Dies kann für Ihre Zwecke funktionieren oder nicht, aber Sie können jScrollPane erweitern , um andere Funktionen auszulösen , bevor das Scrollen ausgeführt wird. Ich habe dies gerade erst ein wenig getestet, aber ich kann bestätigen, dass Sie hineinspringen und das Scrollen vollständig verhindern können. Alles was ich getan habe war:

  • Laden Sie die Demo-Zip herunter: http://github.com/vitch/jScrollPane/archives/master
  • Öffnen Sie die Demo "Events" (events.html)
  • Bearbeiten Sie es, um die nicht minimierte Skriptquelle zu verwenden: <script type="text/javascript" src="script/jquery.jscrollpane.js"></script>
  • Fügen Sie in jquery.jscrollpane.js eine "return" ein. in Zeile 666 (günstige Zeilennummer! Falls sich Ihre Version jedoch geringfügig unterscheidet, ist dies die erste Zeile der positionDragY(destY, animate)Funktion

Starten Sie events.html und Sie sehen ein normales Bildlauffeld, das aufgrund Ihrer Codierung nicht gescrollt wird.

Auf diese Weise können Sie die Bildlaufleisten des gesamten Browsers steuern (siehe fullpage_scroll.html).

Vermutlich besteht der nächste Schritt darin, eine andere Funktion aufzurufen, die ausgelöst wird und Ihre Verankerungsmagie ausführt, und dann zu entscheiden, ob Sie mit dem Scrollen fortfahren möchten oder nicht. Sie haben auch API-Aufrufe, um scrollTop und scrollLeft festzulegen.

Wenn Sie weitere Hilfe benötigen, geben Sie an, wo Sie gerade sind!

Hoffe das hat geholfen.

Jeremy Warne
quelle
2

Ich habe hier eine Antwort gegeben, die helfen könnte: eingefügt jQuery simplemodal disable scrolling

Es zeigt, wie Sie die Bildlaufleisten deaktivieren, ohne den Text zu verschieben. Sie können die Teile über simplemodal ignorieren.

mhenry1384
quelle
1

Wenn Sie nur das Scrollen mit der Tastaturnavigation deaktivieren möchten, können Sie das Keydown-Ereignis überschreiben.

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

Versuchen Sie diesen Code:

    $(function() { 
        // ...

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

        // ...
    });
Jopie
quelle
0

Sie können das Fenster mit einem scrollbaren Div abdecken, um das Scrollen des Inhalts auf einer Seite zu verhindern. Durch Ausblenden und Anzeigen können Sie Ihre Schriftrolle sperren / entsperren.

Mach so etwas:

#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();
}
Appex
quelle
7
Bitte verwenden Sie keine Abkürzungen wie "u" und "smth". Nehmen Sie sich Zeit, um die Lesbarkeit zu verbessern.
der Blechmann
0

Für Leute, die Layouts (via margin:0 auto;) zentriert haben , ist hier eine Zusammenstellung der position:fixedLösung zusammen mit @tfe vorgeschlagenen Lösung.

Verwenden Sie diese Lösung, wenn beim Einrasten von Seiten Probleme auftreten (da die Bildlaufleiste angezeigt / ausgeblendet wird).

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

…kombiniert mit…

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

… Und schließlich das CSS für .modal-noscroll

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

Ich wage zu sagen , dass dies eher eine richtige Lösung ist , als alle anderen Lösungen gibt, aber ich habe getestet es nicht , dass gründlich noch ...: P


Bearbeiten: Bitte beachten Sie, dass ich keine Ahnung habe, wie schlecht dies auf einem Touch-Gerät funktionieren könnte (sprich: explodieren).

Matthemattics
quelle
0

Sie können dazu auch DOM verwenden. Angenommen, Sie haben eine Funktion, die Sie wie folgt aufrufen:

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

Und das ist alles! Hoffe das hilft zusätzlich zu all den anderen Antworten!

Brendan
quelle
0

Das habe ich letztendlich getan:

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");
});
Marz
quelle
0

Ich bin mir nicht sicher, ob jemand meine Lösung ausprobiert hat. Dieser funktioniert auf dem gesamten Körper / HTML, kann aber zweifellos auf jedes Element angewendet werden, das ein Bildlaufereignis auslöst.

Setzen und deaktivieren Sie scrollLock einfach nach Bedarf.

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

Hier ist das Beispiel JSFiddle

Hoffe, dieser hilft jemandem.

FossilMFC
quelle
Dieser funktioniert wie es sollte, mit einer Ausnahme. Wenn die Schriftrolle gesperrt ist und ich scrolle, zuckt sie ein wenig, bevor die Schriftrolle tatsächlich gesperrt wird ...
Thomas Teilmann
0

Ich denke, die beste und sauberste Lösung ist:

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

Und mit jQuery:

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

Diese Ereignis-Listener sollten das Scrollen blockieren. Entfernen Sie sie einfach, um das Scrollen wieder zu aktivieren

Tiziano
quelle