Wie deaktiviere ich das Scrollen auf dem Körper in iOS 13 Safari (wenn als PWA auf dem Startbildschirm gespeichert)?

Lesezeit: 6 Minuten

Benutzeravatar von swift-lynx
Swift-Luchs

Das Problem:

Ich weiß, dass diese Frage ein Dutzend Mal gestellt wurde, aber keine der Lösungen zu diesen Fragen hat bei mir funktioniert.

Ich möchte, dass das Body-Element auf iOS 13 Safari nicht scrollt. Dies bedeutet kein Scrollen und keinen Elastic-Bounce-Effekt (Overflow-Scrolling).

Ich habe zwei Elemente nebeneinander, auf die ich gesetzt habe overflow: scroll;diese sollten scrollen, nur der Körper um sie herum sollte nicht.

Alle Lösungen, die ich ausprobiert habe, funktionieren einfach nicht in progressiven Webapps, die das folgende Tag in ihrem Kopf haben und auf dem Homescreen gespeichert sind.

<meta name="apple-mobile-web-app-capable" content="yes">

Lösungen, die ich ausprobiert habe:

Versuch 1: Festlegen des Überlaufs auf Körper und/oder HTML ausgeblendet. Funktionierte nicht für iOS 13 Safari.

https://stackoverflow.com/a/18037511/10551293

html {  
    position: relative;
    overflow: hidden;
    height: 100%;
}

body {
    position: relative;
    overflow: hidden;
    height: 100%;
}

tut nichts in iOS 13 Safari, funktioniert aber in macOS Safari und Firefox.

Versuch 2: am Körper fixierte Einstellposition. Funktioniert bei mir nicht, denn wenn der Benutzer scrollt, funktioniert der Körper nicht, aber das Scrollen verhindert immer noch, dass meine beiden inneren Elemente scrollen, während der Overflow-Bounce animiert wird.

https://stackoverflow.com/a/47874599/10551293

body {
    position: fixed;
}

legt den Körper nur über das Scrollen der Seite. Das Scrollen (Überlauf-Scrollen) geschieht durch den festen Körper …

Versuch 3: verhindert die Standardeinstellung bei Berührung verschoben. Hat nicht funktioniert (ist eine ältere Lösung …).

https://stackoverflow.com/a/49853392/10551293

document.addEventListener("touchmove", function (e) {
    e.preventDefault();
}, { passive: false });

tut nichts, wie ich sagen kann. Weder in Safari noch in Firefox.

Versuch 4: Verhindern des standardmäßigen Scrollens des Fensters und Zurücksetzen der Scrollposition auf 0. Ist wegen fehlerhafter Animationen nicht realisierbar.

window.addEventListener("scroll", (e) => {
    e.preventDefault();
    window.scrollTo(0, 0);
});

setzt die Scroll-Position auf 0 zurück, aber das Overflow-Scrolling gilt immer noch, was zu einem fehlerhaften Verhalten führt.


Ein Ausschnitt, der es demonstriert:

Um es selbst zu testen, speichern Sie das folgende Snippet als HTML-Datei und speichern Sie es auf dem Startbildschirm auf einem iPad (oder iPad-Simulator). Der Körper wird plötzlich scrollbar, wenn er auf dem Startbildschirm gespeichert wird.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <meta name="apple-mobile-web-app-capable" content="yes">
</head>
<body>
    <style>
        body, html {
            position: relative;
            overflow: hidden;
            height: 100%;
            width: 100%;
        }
        body {
            margin: 0;
            display: flex;
            flex-direction: column;
        }

        nav, footer {
            width: 100%;
            height: 5rem;
            background: blue;
            flex-shrink: 0;
        }

        main {
            display: flex;
            height: 0;
            flex-grow: 1;
            padding: 2rem;
        }

        section {
            width: 50%;
            overflow: scroll;
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        div {
            flex-shrink: 0;
            width: 25%;
            height: 18rem;
            margin: 1rem;
            background: red;
        }
    </style>

    <nav></nav>

    <main>
        <section>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </section>
        
        <section>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </section>
    </main>

    <footer></footer>
</body>
</html>

Keiner von ihnen hat für mich auf akzeptable Weise funktioniert. Wie mache ich das jetzt, damit es in iOS 13 Safari richtig funktioniert (wenn es als PWA auf dem Startbildschirm gespeichert wird)?

  • Ich denke, Sie müssen die Höhe fest einstellen, damit der Überlauf ausgeblendet wird, wie folgt: html { position: relative; overflow: hidden; height: 90vh; }

    – Anshul Gupta

    5. Dezember 2019 um 11:58 Uhr

  • Hat auch nicht funktioniert, das habe ich auch schon probiert…

    – Swift-Luchs

    5. Dezember 2019 um 12:59 Uhr

  • Können Sie eine Geige oder etwas für die Vorschau von Elementen hinzufügen? Ich kann Ihre Elemente nicht abbilden

    – Anshul Gupta

    5. Dezember 2019 um 13:07 Uhr

  • Es war in meiner Frage nicht klar, es funktioniert nur nicht, wenn die Seite als Web-App auf dem Startbildschirm gespeichert ist und wenn sie den folgenden Meta-Tag hat:

    – Swift-Luchs

    5. Dezember 2019 um 13:24 Uhr

  • Und ich habe ein Code-Snippet hinzugefügt.

    – Swift-Luchs

    5. Dezember 2019 um 13:31 Uhr

Ich habe Versuch 2 und Versuch 4 aus der Frage kombiniert. Der feste Körper zeigt kein Überlauf-Scrollen und der Scroll-Reset verhindert die lange Animation des Überlauf-Scrollens im Hintergrund. Es ist wirklich hässlich, aber es funktioniert irgendwie.

body {
  position: fixed;
}
window.addEventListener("scroll", (e) => {
  e.preventDefault();
  window.scrollTo(0, 0);
});

  • Ich brauchte voll: body {position: fixed; left: 0; top: 0; right: 0; bottom: 0;}

    – zbycz

    26. Juni 2021 um 10:30 Uhr


  • Dies ist eine sehr gute Antwort. Es hilft sehr

    – Liangdapang

    27. Juni 2022 um 6:53 Uhr

Blallos Benutzeravatar
Blallo

function unlockScroll () {
    const scrollY = this.body.style.top;
    document.body.style.position = '';
    document.body.style.top = '';
    document.body.style.left="";
    document.body.style.right="";
    window.scrollTo(0, parseInt(scrollY || '0') * -1);
};

function lockScroll () {
    document.body.style.position = 'fixed';
    document.body.style.top = `-${window.scrollY}px`;
    document.body.style.left="0";
    document.body.style.right="0";
};

  • Dies sperrt auch das Scrollen auf meinen beiden inneren Elementen.

    – Swift-Luchs

    11. Dezember 2019 um 12:31 Uhr


  • Ich bestätige diese Antwort

    – Kamran Asgari

    17. Juli 2020 um 14:34 Uhr

  • @swiftlynx hast du deine inneren Elemente überschwemmt?

    – Blalo

    22. Juli 2020 um 10:47 Uhr

  • Dies funktioniert sowohl auf Android 10 (Chrome) als auch auf iOS 13.7 (Safari). Tausend Dank!

    – Miros

    1. Oktober 2020 um 19:39 Uhr

  • Für alle, die das noch brauchen, habe ich auf github eine verbesserte Version mit MIT-Lizenz und sogar einem npm-Paket zur Verfügung gestellt: github.com/8lall0/body-lock. Dies berücksichtigt den vertikalen und horizontalen Überlauf und behält die Bildlaufleisten bei, um den “Sprung” zu verhindern, den eine Seite haben kann, wenn Sie die Bildlaufleiste entfernen, und fügt dem Körper eine Klasse hinzu, wenn Sie zusätzliches Styling benötigen, wenn Sie den Körper sperren.

    – Blalo

    18. Oktober 2021 um 10:07 Uhr

In meinem Fall (App muss gezogen werden, um Elemente anzuordnen) Einstellung Touch-Aktion Zu none gearbeitet, um das Scrollen beim Ziehen bestimmter Elemente zu verhindern.

z.B

draggableElement.css('touch-action', 'none') // disable actions
draggableElement.css('touch-action', 'auto') // restore actions

Fügen Sie einfach eine touch-action:none zum Körper in CSS hinzu:

body{

touch-action:none;

}

https://github.com/willmcpo/body-scroll-lock

Ich kann es im Moment nicht testen, aber das scheint einen Versuch wert zu sein.

Benutzeravatar von Petrolea
Petrolea

Ich hatte zuvor ein ähnliches Problem und bisher hat die Verwendung des folgenden Ansatzes am besten funktioniert:

  • Aktivieren Sie zunächst das Scrollen in Ihrem Inhaltscontainer, indem Sie sich bewerben -webkit-overflow-scrolling: touch

  • Wenden Sie zweitens die folgenden Regeln an:

/* this part makes sure there is nowhere left to scroll */

html {
    position: static;
    overflow-y: hidden;
    height: 100%;
    max-height: 100%;
}

/* all properties don't necessarily need to be applied on both elements,
this is only used to override any existing code */

body {
    overflow: hidden;
    height: 100%;
    max-height: 100%;
}

window.addEventListener('touchend', _ => {
    window.scrollTo(0,0)
});

Dadurch wird der Körper auf 0,0 zurückgesetzt, nachdem der Benutzer den Körper losgelassen hat, sodass der Benutzer sofort nach unten scrollen kann, ohne seltsame Animationen, außer dass er sofort zurückschnappt. Ich habe es mit einer glatten Scroll-Animation versucht, aber es animiert nicht immer schnell genug. Dadurch wird die Bildschirmsperre verhindert, die auftritt, wenn der Körper von der elastischen Sprungrolle auf diesem iPhone aus scrollt und nur ausgelöst wird, wenn der Benutzer den Zug loslässt.

1445210cookie-checkWie deaktiviere ich das Scrollen auf dem Körper in iOS 13 Safari (wenn als PWA auf dem Startbildschirm gespeichert)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy