web-dev-qa-db-ja.com

モバイルサファリでiFrameを適切に表示する方法

モバイルWebアプリケーションでiframeを表示しようとしていますが、iframeのサイズをiPhone画面のサイズに制限するのに問題があります。奇妙なことに、iframe要素の高さと幅の属性は効果がないようです。それをdivで囲むと何とか制約されますが、iframe内でスクロールできません。

モバイルサファリでiframeに取り組んだことはありますか?どこから始めるべきですか?

54
Matt Diamond

ええ、iframe自体を高さと幅で制限することはできません。周囲にdivを配置する必要があります。 iframe内のコンテンツを制御する場合、iframeコンテンツ内にJSを配置して、タッチイベントが受信されたときにdivをスクロールするように親に伝えることができます。

このような:

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

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>

Iframeコンテンツを制御しない場合は、同様の方法でiframeの上にオーバーレイを使用できますが、スクロールする以外にiframeコンテンツを操作することはできません。たとえば、クリックすることはできませんiframe内のリンク。

以前は、2本の指を使用してiframe内をスクロールできましたが、それはもう機能しません。

更新:iOS 6はこのソリューションを壊しました。私はそれに対する新しい修正を取得しようとしましたが、何もしませんでしたまだ働いています。また、Macを使用する必要があるRemote Web Inspectorが導入されたため、デバイスでjavascriptをデバッグすることはできなくなりました。

20
Case

IFrameコンテンツがあなたのものでない場合、以下のソリューションは機能しません。

Androidを使用すると、iframeをDIVで囲み、divの高さをdocument.documentElement.clientHeightに設定するだけです。しかし、IOSは別の動物です。私はまだSharonのソリューションを試していませんが、良いソリューションのようです。より簡単な解決策を見つけましたが、IOS 5. +でのみ機能します。

Iframe要素をDIVで囲み(スクローラーと呼びます)、DIVの高さを設定し、新しいDIVに次のスタイルが設定されていることを確認します。

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

これだけでも機能しますが、ほとんどの実装では、スクロールするとiframeのコンテンツが空白になり、基本的には役に立たないことがわかります。私の理解では、この動作はiOS 5.0でAppleのバグとして報告されているということです。この問題を回避するには、iframeでbody要素を見つけて、-webkit-transform '、' translate3d(0、0、0)を次のように追加します。

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

アプリまたはiframeのメモリ使用量が多い場合は、シャロンのソリューションを使用する必要があるかもしれないヒッチスクロールを取得する可能性があります。

11
Tmac

これは、外部ページとiframeページの両方を制御する場合にのみ機能します。

外側のページで、iframeをスクロール不可にします。

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

Iframeページで、これを追加します。

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

これが機能するのは、最新のブラウザーがhtmlを使用して高さを決定するためです。そのため、固定高さを指定し、bodyをスクロール可能なノードに変更します。

11
Kernel James

私は@Sharonのコードを次のようにまとめました。これはiPadで2本指のスクロールを使用して動作します。動作させるために変更する必要があるのは、iframeのsrc属性のみです(PDFドキュメントを使用しました)。

<!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>

私は最初のサイトを構築していますが、これにより、iframe埋め込みを使用するすべてのサイトでこれが機能するようになりました。

ありがとう!

3
Krossyomind

Sharonの方法はうまくいきましたが、iframe内のリンクをたどってブラウザの戻るボタンを押すと、ページのキャッシュバージョンがロードされ、iframeはスクロールできなくなります。これを克服するために、次のようにいくつかのコードを使用してページを更新しました。

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

IFrameページまたはそのコンテンツをスクロールせず、親ページをスクロールします。 IFrameコンテンツを制御する場合は、 iframe-resizer ライブラリを使用して、iframe要素自体を適切なブロックレベル要素に変換し、自然/正しい/ネイティブの高さを使用できます。また、iframeを親ページに配置(固定、絶対)したり、フォーム要素がある場合は特に、モーダルウィンドウにiframeを表示したりしないでください。

また、iOS Safariには、iframe-resizerライブラリがデスクトップブラウザで行うように、iframeの高さを自然な高さに拡張する非標準の動作があり、レスポンシブなiframeコンテンツを高さ0pxまたは150pxまたは他の場所でレンダリングするようです有用なデフォルトではありません。幅を制限する必要がある場合は、iframe内でmax-widthスタイルを試してください。

0
spaceRace

以下を実装しましたが、うまくいきます。基本的に、iFrameコンテンツのサイズに応じてボディの寸法を設定します。これは、iFrame以外のメニューを画面外にスクロールできることを意味しますが、そうでない場合は、iPadおよびiPhoneでサイトが機能します。 「ワークボックス」は、iFrameのIDです。

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

純粋にMSchimpfとAhmadのコードを使用して、div内にiframeを配置できるように調整を行ったため、ページの戻るボタンとブランド設定用のヘッダーとフッターを保持しました。更新されたコード:

<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>  

そして、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