Aufruf von element.Fokus() in iframe scrollt übergeordneten Seite auf zufällige position in Safari iOS10

Safari auf iOS 10.1.1 scheint ein bug bei der Einstellung von Fokus auf ein element innerhalb eines iframe.

Wenn wir rufen element.focus() auf ein element innerhalb eines iframe, Safari wird sofort, scrollen Sie in der übergeordneten Seite nach unten und verschieben Sie das fokussierte element off-screen (anstelle von Bildlauf mit dem fokussierten element in der Ansicht).

Jedoch passiert es nur, wenn das element in einen iframe, das ist, größer als der Bildschirm-Höhe (kürzere iframes sind OK).

Also, wenn es zwei Elemente, eine an der Oberseite des iframe und ein weiteres weiter unten auf der Seite, wird der erste Fokus in Ordnung, aber der zweite springt aus dem Bildschirm, wenn wir uns konzentrieren.

Für mich sieht es aus wie Safari ist versuchen, um scroll-element in die Ansicht, aber die Mathematik ist falsch, und Sie am Ende durch scrollen an einer beliebigen position weiter unten auf der Seite. Alles funktioniert OK, in iOS9 also ich denke, das ist ein neuer bug in iOS10.

Ist ein Weg zur Vermeidung der übergeordneten Seite scrollen oder auf eine andere Weise, dies zu vermeiden Fehler?

Ich habe eine one-page Kern repliziert, das Problem auf iOS 10 Geräte oder den Simulator.

Hier ist eine URL, die Sie tatsächlich nutzen können, auf einem Handy: goo.gl/QYi7OE

Hier ein plunker so können Sie prüfen, desktop-Verhalten: https://embed.plnkr.co/d61KtGlzbVtVYdZ4AMqb/

Und einen gist-version, die plunker: https://gist.github.com/Coridyn/86b0c335a3e5bf72e88589953566b358

Hier ist einer lauffähigen version des Kerns (die verkürzte URL, die oben genannten Punkte hier):
https://rawgit.com/Coridyn/86b0c335a3e5bf72e88589953566b358/raw/62a792bfec69b2c8fb02b3e99ff712abda8efecf/ios-iframe-bug.html

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="apple-mobile-web-app-capable" content="yes" />

    <script>
    document.addEventListener('DOMContentLoaded', function(){
        document.querySelector('#frame').srcdoc = document.querySelector('#frameContent').innerHTML;
    });
    </script>
</head>
<body>
    <iframe id="frame" frameborder="1"
        style="width: 100%; height: 1200px;"
        width="100%" height="1200">
    </iframe>

    <!--
    To keep this a one-page example, the content below will be inserted into the iframe using the `srcdoc` attribute.

    The problem occurs in iOS10 regardless of using `srcdoc` or `src` (and regardless of same-domain or cross-domain content).
    -->
    <script id="frameContent" type="text/template">
<div>
    <style>
        .spacer {
            padding-top: 400px;
            padding-bottom: 400px;
        }
        .green-block {
            width: 20px;
            height: 20px;
            background-color: green;
        }
        .red-block {
            width: 20px;
            height: 20px;
            background-color: red;
        }
    </style>

    <div class="green-block" tabindex="0"></div>

    <p>Scroll down and press the 'Focus Green' or 'Focus Red' button.</p>

    <h2>'Focus Green'</h2>
    <p><b>Expected:</b> should set focus on '.green-block' and scroll to the top of the page.</p>
    <p><b>Actual:</b> sets focus but does not scroll page.</p>

    <h2>'Focus Red'</h2>
    <p><b>Expected:</b> should set focus on '.red-block' and not scroll page (because element is already on-screen).</p>
    <p><b>Actual:</b> sets focus and scrolls down to the bottom of the host page.</p>

    <hr/>

    <p class="spacer">1 Filler content to force some visible scrolling 1</p>

    <div class="red-block" tabindex="0"></div>

    <div>
        <button type="button" onclick="document.querySelector('.green-block').focus();">Focus Green</button>
        <p>'Focus Green' should go to top of page, but on iOS10 the view doesn't move.</p>
    </div>
    <div>
        <button type="button" onclick="document.querySelector('.red-block').focus();">Focus Red</button>
        <p>'Focus Red' should stay here, but on iOS10 the view scrolls to the bottom of the page</p>
    </div>

    <p class="spacer">20 Filler content to force some visible scrolling 20</p>
    <p>Bottom of iframe</p>

</div>
    </script>

</body>
</html>

Dinge, die wir gefunden haben:

  • Das Problem tritt auf iOS 10+ sowohl Safari und Chrome
  • Das Problem nicht geschehen auf Safari iOS 9.3.2 (Verhalten entspricht, desktop-browser, wie erwartet)
  • Das problem nur Auftritt, wenn die Konzentration auf nicht-Eingabe-HTML – Elemente wie z.B. DIVs, Überspannt, Anker-tags, etc; Einstellung von Fokus auf INPUT Elemente korrekt funktioniert
  • Desktop Safari funktioniert
  • Es ist die übergeordnete Seite, scrollen, nicht die iframe (Inlineframe ist so bemessen, dass 100% Ihrer Inhalte, um scrollen zu vermeiden innerhalb des Rahmens)
  • Wir haben versucht, Sie anzurufen, preventDefault auf der übergeordneten Seite mit: window.onscroll = (event) => event.preventDefault(); aber das funktioniert nicht, weil die scroll – Ereignis wird nicht stornierbar
  • Die scroll Schadenereignis erhoben werden, auf die übergeordnete Seite zu kommen scheint von Safari/Webkit selbst, weil es keine anderen Funktionen im callstack (bei der Inspektion mit DevTools und Fehler.stack)
  • Ich hab das gleiche Problem Auftritt. Ich bin die Einreichung einer bug-report bei Apple. Auch ich hatte ein problem beim Zugriff auf Ihr plunkr Vorschau auf mein iPhone, also ich habe die Dateien hier: jeremyjon.es/apple-bug-Bericht-iframe-Seite-springen (ich habe auch einen blauen Umriss auf die Konzentration der Elemente, da der Fokus-ring nicht zeigen, auf meinem Handy.)
  • Vielen Dank dafür! Ich hatte eine Menge ärger bekommen eine öffentliche version, die Sie laufen konnte, auf einem iOS-Gerät.
  • Ich habe ein ähnliches Problem, aber wo der Eingabe-cursor scrollt mit den Eltern, den ie aus dem iframe input-Feld. Ich bin auch nicht in der Lage, klicken Sie auf die Tasten, bis auf dem Bildschirm die Tastatur eingefahren ist. Passiert auf Geräte und simulator, ios 11. Hast du weiter mit deinem problem @Sly_cardinal?
  • hast du eine Lösung für dieses?
  • Nein, wir haben keine Lösung gefunden bisher. Unsere einzige Lösung war, um zu erkennen iOS-Geräte, und vermeiden Sie Einstellung von Fokus auf non-input-Elemente (die ich verstehe, ist nicht eine option in vielen Fällen). Ich habe öffnete sich ein Fehler in Ihre tracking-system, aber nichts passierte, es aber doch: bugs.webkit.org/show_bug.cgi?id=164512
  • meine Probleme, hauptsächlich verursacht durch die Verwendung einer fixed position auf dem iframe. Ich drehte mich zu mit absolute position bei der Anzeige eines Formulars. Jetzt funktioniert es akzeptabel. Vielleicht nicht in Bezug auf das problem dieser Frage ist über.

InformationsquelleAutor Sly_cardinal | 2016-11-08



2 Replies
  1. 2

    Ich hatte ein ähnliches Problem mit scrollen springen um auf iOS. Es passiert war, auf allen iOS-Versionen für mich, 8, 9 und 10.

    Testen Sie Ihre plunker in einem echten iOS-10-Gerät nicht die Ursache für das problem für mich. Ich bin nicht sicher, ob ich richtig getestet.

    Können Sie versuchen, diese version von Ihrem plunker auf iOS? https://embed.plnkr.co/NuTgqW/

    Mein workaround für mein Problem war es, sicherzustellen, dass der Körper und html-Tags im iframe-Inhalte hatten einen definierten 100% Höhe und Breite, und ein überlauf-scrollen. Dieser war in der Lage zu zwingen, die iframe-dimension. Es verhindert das scrollen springen.

    Lassen Sie mich wissen, wenn es hilft.

    • Dies funktioniert für mich auch, wir hatten dieses Thema auf die Unternehmen und fixiert es.
    • Dies löste das Problem hatten wir auch, aber es habe noch einen hässlichen Satz von Bildlaufleisten,… gute Sache, wir sind die Migration Weg von unserem iFramed-Lösung hier.
  2. 0

    In meiner situation eine Seite enthalten, die ein iframe mit einer Eingabe. Beim laden der Seite die Eingabe bekam den Fokus. Dies führte zu der übergeordneten Seite geblättert werden, um die position der Eingabe. Es passiert in allen Browsern.

    Lösung: wenn die Seite gestartet, um zu Blättern, legen Sie die scroll-position wieder nach oben.

    Weil das Problem passiert nur einmal habe ich eine Namespace-Ereignis zu löschen, einen listener, sobald die unerwünschte schriftrolle wurde verhindert.

    $(function() {
        if ($('#iframe').length) {
            var namespace = 'myNamespace';
            $(window).on('scroll.' + namespace, function() {
                $(window).scrollTop(0).off('scroll.' + namespace);
            });
        }
    });

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.