it-swarm.com.de

so zeigen Sie einen iFrame in Mobile Safari richtig an

Ich versuche, einen iframe in meiner mobilen Webanwendung anzuzeigen, ich habe jedoch Probleme, die Größe des iframe auf die Abmessungen des iPhone-Bildschirms zu beschränken. Die Attribute height und width des iframe-Elements scheinen seltsam keine Auswirkung zu haben. Wenn Sie es mit einem div umgeben, können Sie es einschränken, aber dann kann ich nicht innerhalb des iframe scrollen.

Hat sich schon jemand mit iframes in Mobile Safari beschäftigt? Irgendwelche Ideen, wo man anfangen soll?

52
Matt Diamond

Ja, Sie können den Iframe selbst nicht mit Höhe und Breite einschränken. Du solltest ein Div umsetzen. Wenn Sie den Inhalt im Iframe steuern, können Sie einige JS in den Iframe-Inhalt einfügen, der den übergeordneten Befehl anweist, das Div zu scrollen, wenn das Berührungsereignis empfangen wird. 

so was:

Die JS:

setTimeout(function () {
var startY = 0;
var startX = 0;
var b = document.body;
b.addEventListener('touchstart', function (event) {
    parent.window.scrollTo(0, 1);
    startY = event.targetTouches[0].pageY;
    startX = event.targetTouches[0].pageX;
});
b.addEventListener('touchmove', function (event) {
    event.preventDefault();
    var posy = event.targetTouches[0].pageY;
    var h = parent.document.getElementById("scroller");
    var sty = h.scrollTop;

    var posx = event.targetTouches[0].pageX;
    var stx = h.scrollLeft;
    h.scrollTop = sty - (posy - startY);
    h.scrollLeft = stx - (posx - startX);
    startY = posy;
    startX = posx;
});
}, 1000);

Das HTML:

<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="url" />
</div>

Wenn Sie den iframe-Inhalt nicht steuern, können Sie eine Überlagerung über den iframe auf ähnliche Weise verwenden. Sie können jedoch nicht mit dem iframe-Inhalt interagieren, außer um ihn zu scrollen Links im iframe.

Früher konnte man mit zwei Fingern innerhalb eines Iframes scrollen, aber das funktioniert nicht mehr.

Update: iOS 6 hat diese Lösung für uns gebrochen.Ich habe versucht, ein neues Update zu bekommen, aber bisher hat nichts funktioniert. Darüber hinaus ist es nicht mehr möglich, Javascript auf dem Gerät zu debuggen, da Remote Web Inspector eingeführt wurde, für dessen Verwendung ein Mac erforderlich ist.

20
Case

Wenn der iFrame-Inhalt nicht Ihrer ist, funktioniert die Lösung unten nicht.

Bei Android müssen Sie lediglich den iframe mit einer DIV umgeben und die Höhe des div auf document.documentElement.clientHeight einstellen. IOS ist jedoch ein anderes Tier. Obwohl ich die Lösung von Sharon noch nicht ausprobiert habe, scheint sie eine gute Lösung zu sein. Ich habe eine einfachere Lösung gefunden, aber sie funktioniert nur mit IOS 5. +.

Umgeben Sie Ihr iframe-Element mit einem DIV (nennen wir es Scroller), stellen Sie die Höhe des DIV ein und stellen Sie sicher, dass das neue DIV das folgende Styling hat:

$('#scroller').css({'overflow' : 'auto', '-webkit-overflow-scrolling' : 'touch'});

Dies allein wird funktionieren, aber Sie werden feststellen, dass in den meisten Implementierungen der Inhalt im Iframe beim Scrollen leer wird und im Grunde unbrauchbar wird. Ich verstehe, dass dieses Verhalten bereits seit iOS 5.0 als Fehler an Apple gemeldet wurde. Um dieses Problem zu umgehen, suchen Sie das body-Element im iframe und fügen Sie -webkit-transform ',' translate3d (0, 0, 0) wie folgt hinzu:

$('#contentIframe').contents().find('body').css('-webkit-transform', 'translate3d(0, 0, 0)');

Wenn Ihre App oder Ihr iframe sehr viel Speicher benötigt, erhalten Sie möglicherweise einen Bildlauf, für den Sie möglicherweise die Lösung von Sharon verwenden müssen.

11
Tmac

Dies funktioniert nur, wenn Sie sowohl die Außenseite als auch die Iframe-Seite steuern.

Machen Sie die iframe auf der Außenseite nicht mehr rollbar.

<iframe src="" height=200 scrolling=no></iframe>

Fügen Sie dies auf der iframe-Seite hinzu.

<!doctype html>
...
<style>
html, body {height:100%; overflow:hidden}
body {overflow:auto; -webkit-overflow-scrolling:touch}
</style>

Dies funktioniert, weil moderne Browser html verwenden, um die Höhe zu bestimmen. Wir geben also nur eine feste Höhe an und machen aus body einen scrollbaren Knoten.

10
Kernel James

Ich habe @ Sharons Code in das Folgende zusammengefügt, der auf dem iPad mit zwei Fingern durchlaufen wird. Das einzige, was Sie ändern müssen, damit es funktioniert, ist das src-Attribut im iframe (ich habe ein PDF -Dokument verwendet).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Pdf Scrolling in mobile Safari</title>
</head>
<body>
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" id="iframe" src="data/testdocument.pdf" />
</div>
<script type="text/javascript">
    setTimeout(function () {
        var startY = 0;
        var startX = 0;
        var b = document.body;
        b.addEventListener('touchstart', function (event) {
            parent.window.scrollTo(0, 1);
            startY = event.targetTouches[0].pageY;
            startX = event.targetTouches[0].pageX;
        });
        b.addEventListener('touchmove', function (event) {
            event.preventDefault();
            var posy = event.targetTouches[0].pageY;
            var h = parent.document.getElementById("scroller");
            var sty = h.scrollTop;

            var posx = event.targetTouches[0].pageX;
            var stx = h.scrollLeft;
            h.scrollTop = sty - (posy - startY);
            h.scrollLeft = stx - (posx - startX);
            startY = posy;
            startX = posx;
        });
    }, 1000);
    </script>
</body>
</html>
4
Eric Pohl
<div id="scroller" style="height: 400px; width: 100%; overflow: auto;">
<iframe height="100%" id="iframe" scrolling="no" width="100%" src="url" />
</div>

Ich baue meine erste Website und dies hat mir geholfen, diese Funktion für alle Websites zu nutzen, für die ich iframe embededding verwende. 

Vielen Dank!

3
Krossyomind

Sharons Methode funktionierte für mich, wenn jedoch ein Link im Iframe gefolgt wird und dann die Zurück-Schaltfläche des Browsers gedrückt wird, wird die zwischengespeicherte Version der Seite geladen und der Iframe ist nicht mehr scrollbar. Um dies zu überwinden, habe ich etwas Code verwendet, um die Seite wie folgt zu aktualisieren:

if ('ontouchstart' in document.documentElement)
     {
        document.getElementById('Scrolling').src = document.getElementById('SCrolling').src;
    }
1
Phil Green

Scrollen Sie nicht auf der IFrame-Seite oder deren Inhalt, blättern Sie nicht auf der übergeordneten Seite. Wenn Sie den IFrame-Inhalt steuern, können Sie die Bibliothek iframe-resizer verwenden, um das iframe-Element selbst in ein richtiges Blockebenenelement mit einer natürlichen/korrekten/nativen Höhe zu verwandeln. Versuchen Sie auch nicht, Ihren iframe (fest, absolut) auf der übergeordneten Seite zu positionieren oder einen iframe in einem modalen Fenster darzustellen, insbesondere wenn er Formelemente enthält.

Ich vermute auch, dass iOS Safari ein nicht standardmäßiges Verhalten aufweist, das die Höhe Ihres Iframes auf seine natürliche Höhe ausdehnt, ähnlich wie die iframe-resizer-Bibliothek für Desktop-Browser, die anscheinend reaktionsfähigen Iframe-Inhalt auf der Höhe 0px oder 150px oder einem anderen darstellen nicht nützliche Vorgabe. Wenn Sie die Breite einschränken müssen, versuchen Sie es mit einem max-width-Stil im iframe.

0
spaceRace

Ich habe folgendes implementiert und es funktioniert gut. Grundsätzlich stelle ich die Körpermaße entsprechend der Größe des iFrame-Inhalts ein. Das bedeutet, dass unser Nicht-iFrame-Menü vom Bildschirm gescrollt werden kann. Andernfalls können unsere Websites mit iPad und iPhone verwendet werden. "workbox" ist die ID unseres iFrame.

// Configure for scrolling peculiarities of iPad and iPhone

if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
{
    document.body.style.width = "100%";
    document.body.style.height = "100%";
    $("#workbox").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
        iframeWidth = $("#workbox").contents().width();
        if (iframeWidth > 400)
           document.body.style.width = (iframeWidth + 182) + 'px';

        iframeHeight = $("#workbox").contents().height();
        if (iframeHeight>200)
            document.body.style.height = iframeHeight + 'px';
     });
}
0
MSchimpf

Ich habe ausschließlich den Code von MSchimpf und Ahmad verwendet und Anpassungen vorgenommen, um den iframe in einem div zu haben. Daher sollten auf meiner Seite Kopf- und Fußzeilen für den Zurück-Button und das Branding bleiben. Aktualisierter Code:

<script type="text/javascript">
    $("#webview").bind('pagebeforeshow', function(event){
        $("#iframe").attr('src',cwebview);
    });

    if (navigator.userAgent.indexOf('iPhone') != -1 || navigator.userAgent.indexOf('iPad') != -1)
    {
        $("#webview-content").css("width","100%");
        $("#webview-content").css("height","100%");
        $("#iframe").load(function (){ // Wait until iFrame content is loaded before checking dimensions of the content
            iframeWidth = $("#iframe").contents().width();
            if (iframeWidth > 400)
               $("#webview-content").css("width",(iframeWidth + 182) + 'px');

            iframeHeight = $("#iframe").contents().height();
            if (iframeHeight>200)
                $("#webview-content").css("height",iframeHeight + 'px');
         });
    }       
</script>  

und die HTML

<div class="header" data-role="header" data-position="fixed">
</div>

<div id="webview-content" data-role="content" style="height:380px;">
    <iframe id="iframe"></iframe>   
</div><!-- /content -->

<div class="footer" data-role="footer" data-position="fixed">
</div><!-- /footer -->   
0
dgig