CSS
JavaScript
HTML5
iOS
iframe

スマホサイトなどでiframe要素をスクロールさせる方法

スマホサイトなどでiframe要素をスクロールさせる方法です。

iOS/Androidのiframe動作

両OSのiframe動作を確認したところ、iOS:Safari上では、iframeが正常に動かず、
要素がすべて表示されてしまった。

調べたところ、他にも同じことで困っている人がいるみたく、
解決方法があったので、実際に試してみました。

参考:

Scroll IFRAMEs on iOS
iphoneでiframeをスクロールさせる

iframeサンプル

とりあえず、iframeが正常に動かないhtmlと動くhtmlを作成しました。

ソースはこちら
iframe-no-scroll関連は動かないほうです。
iframe-scroll関連は動くほうです。

どこかのWebサーバにあげてスマホで見てください。
githubのキャラクターとgithubの説明(wikipedia参照)を載せたhtmlです。

動かないほう

htmlページにiframeを追加する親要素を記述し、
<div id="iframe-no-scroll" style="width:100%; height:200px;"></div>
javascript内の処理でiframe要素を作成し、親要素に追加するような動きになってます。

キャプチャ

noscroll.png

動くほう

動かない方と同様の作りですが、javascript内で行っているiframe要素の作成処理が異なっていて、iframe要素の1階層上にラッパーのdivをかましています。

iframe-wrapper.html
// iframeラッパー要素作成
var _iframeWrapper = document.createElement('div');
_iframeWrapper.className = 'iframe-wrapper';
_iframeWrapper.style.width = "100%";
_iframeWrapper.style.height = "100%";    

_iframeWrapper.appendChild(_iframe);

そして、そのラッパーのdivを親要素に追加するような動きになってます。
_iframeScroll.appendChild(_iframeWrapper);

後、ラッパーの動作をcss上で定義しています。

iframe-wrapper.css
.iframe-wrapper { 
    -webkit-overflow-scrolling: touch;
    overflow: auto;
};

-webkit-overflow-scrolling: touchは、慣性スクロールをできるようにする設定ぽいです。慣性スクロールは、スッってやったらページもスってなるイメージですが、合っているか不明です。

参考:

スマートフォンでページの一部を慣性スクロールできるようにする-webkit-overflow-scrolling

overflow: auto;は、要素からはみ出た部分の表示の仕方を設定するもので、
autoにすると、ブラウザに依存する設定になるみたいです。

参考:

overflow・・・・・はみ出た内容の表示方法を指定する

キャプチャ

scroll.png

結果

うまくできました。

ただ、Androidだと普通にiframeが動くので、javascirpt内で処理を分けたほうがいいです。

iOS判定処理です。

isIos.js
var isIod = function(){
var ua = window.navigator.userAgent.toLowerCase();
if (ua && ua.indexOf('iphone') === -1 && ua.indexOf('ipod') === -1 && ua.indexOf('ipad') === -1) {
return true;
}
return false;
};

後、そもそもなんで動かないかは、よくわかりません。
調べる元気があればソースを見てみます。
今後OSのアップデートで対応されるかもしれないですね。

Tips

この検証をやった際に色々htmlの勉強になったので、Tipsをあげときます。

iframeのsrcとsrcdoc

iframeのソースの指定方法には、src以外にsrcdocというものがあります。
結構便利で、iframeのソースを直接記述することができます。
今回も使ってます。

iframe-srcdoc.html
var desc = "テキスト・・・"
_iframe.src = "data:text/html;charset=utf-8," + desc;

もちろん、htmlも記述可能です。
後、ひっそり使っているdata:text/html;ですが、データURIスキームというもので、
text/html以外のmimeタイプを指定すると色々できて便利です。

iframeのソース置く場所がないけど、iframeで表示しないといけないという、
特殊な状況に置かれた場合はこれを使ってみるといいと思います。

appendChildの実行順序による表示順番

iOS(iPhone4S,iOS8.1,safari)で、javascript内で作成した要素をappendするときに、appendされる順番が早いほうがz−index的に下に配置されてしまい、別の要素がappendされると、かぶさってしまう現象が発生しました。

確かに自然な動きに見えますが、
AndroidのChromeとデフォルトブラウザ、iOSのChromeは逆の動きをしていました。
しっかり検証していないので、なんともいえませんが、そんなことがありました。

androidデフォルトブラウザ(Android 4.4.1, Xperia SOL25)の文字表示

javascript内でaタグの要素を作成し、他の要素をaタグにappnedしたところ、
文字の下に勝手に下線が引かれる現象が発生しました。

原因はよくわかりませんが、display:inline-blockで直りました。

以上です。