不具合の内容を具体的に説明したいけど難しい。画面がガクガクする。画面がチラつく。
ページの body に何か要素が書き込まれて、その要素が大き過ぎてページ全体が一瞬 縮小されて すぐ元に戻る、見た目では、このような動作をしているように見えます。ページの再描画が何度か走っているらしく、Twitter ウィジェットを設置したときと そうでないときでは、ページ表示に かなりのタイムラグが体感できます。
Icons made by Hand Drawn Goods from www.flaticon.com is licensed by CC BY 3.0
検索しても同じような不具合に悩んでいる情報は発見できず。事象の発生はページの viewport 設定に依存するかも知れません。筆者は以下の環境で確認しました。
環境
サイト側 viewport
<meta name="viewport" content="width=device-width" />
端末(OS)とブラウザ
- PC(Windows7)Google Chrome 44.0.2403.157 m
- タブレット(Android 5.1.1)Google Chrome 44.0.2403.133
尚、どちらの端末も Firefox では同様の不具合は確認できません。Chrome のバグでしょうか。
回避方法
以前 記事にした フレンドリー アイフレーム(FiF: Friendly iFrame)を利用しました。
Twitter ウィジェットを呼び出す部分を別の HTML ファイルにしてサーバーにアップロードし、iframe タグで その HTML ファイルを親ページに埋め込みます。こうすると、Twitter ウィジェットが認識するページは iframe の contentWindow.document なので、どんな動作をしても親ページに影響が及びません。
この施策で事象が改善されました。
FiF HTML ファイルの例
<!doctype html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="robots" content="noindex,nofollow" /> <base target="_top"> <style> body, iframe { margin: 0; padding: 0; } </style> </head> <body> <a class="twitter-timeline" href="https://twitter.com/xxxxxxxx" data-widget-id="999999999999999999">ツイッター @xxxxxxxx</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> </div> </body> </html>
FiF の body 内は、ウィジェットの設定画面に表示されるコードをそのまま貼るだけで OK です。
尚、Twitter ウィジェットの UI 言語は、html 要素の lang 属性を見ているようです。
親ページの iframe 要素の例
<div class="twitterWidgetWrapper"> <iframe id="twitterContainer" src="/html/fif_twitter_widget.html" allowtransparency="true" marginwidth="0" marginheight="0" scrolling="no" style="width: 100%; height: 600px;" frameborder="0"></iframe> </div>
twitterWidgetWrapper をレスポンシブにしておけば、Twitter ウィジェットもレスポンシブになります。この例で height は Twitter デフォルトの 600px ですが、パラメーターで変更したときには iframe 要素の height を合わせる必要があります。
試したけど回避できなかった方法
iframe に若干の微妙臭を感じますか。仕方ないです。これしか思い付かなかった。他にも試したのですがダメでした。
- Twitter ウィジェットのラッパー要素を固定幅にして overflow: hidden を設定する
- setTimeout を使って時間差で Twitter ウィジェットを読み込む
- 先に Twitter ウィジェットの JavaScript ライブラリを読み込んでおき あとから twttr.widgets.createTimeline 関数を使ってウィジェットを設置する
iframe にすると余分な get が Web サーバーに来ちゃうし気持ち悪い。わかります。ただ、FiF なら JavaScript で iframe 要素を動的に生成しても大丈夫なので どうしても気になるならお試しください。
ガクガクしちゃうのは筆者固有の問題とは思えないので記事にしてみました。どなたかのお役に立てば幸いです。
tzktkj