iframe(スクロールバー無し+クロスドメイン)のページ内リンク
あまり…ほとんど需要が無いと思いますが、以前詰まった
iframeのページ内リンクについて書きます。
あるwebサービスで別途作成したhtmlコンテンツを表示させるためにiframeを使用しました。
その際にhtmlコンテンツでページ内リンクが効かないという問題が発生しました。
iframeにスクロールバーがあれば通常の方法でページ内リンクができるのですが、
1枚のページであるように見せるため、スクロールバーを表示させることはできません。
また、クロスドメインの場合、親子間でオブジェクトの操作ができないようです(XSRF防止のため)
色々試した結果、javascriptのpostMessage(子 – htmlコンテンツ)とaddEventListener(親 – 元のwebサービス)の組み合わせで実現できました。
子から親にpostMessageでスクロール先のY座標を通知
↓
親がaddEventListenerで登録したコールバック先でスクロール処理
kodomo.html(子)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<html> <head> <script type="text/javascript"> $(document).ready(function(){ // 親フレームにスクロール(=ページ内リンク)する命令を送る $(".PageNaiLink").click(function(){ var parentFrame = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined); var target = $(this).attr("href"); if(typeof parentFrame != "undefined"){ // 【メインの処理】 // messageイベントで処理を識別する文字列(この場合は'page_nai_link')と飛び先のy座標を送る // ※この場合、リンク元のタグのhref属性は'#リンク先'のみ parentFrame.postMessage( "page_nai_link" + $(target).offset().top, "*"); }else{ // エラー処理 } }); }); </script> </head> <body> <!-- ページ内リンク --> <a class="PageNaiLink" href="#link1">ページ内リンク1へ</a><br /> <a class="PageNaiLink" href="#linl2">ページ内リンク2へ</a><br /> <a class="PageNaiLink" href="#link3">ページ内リンク3へ</a><br /> <a class="PageNaiLink" href="#link4">ページ内リンク4へ</a><br /> <!-- ページ内リンク end --> <div style="height:200px;"></div><!-- 余白 --> <a id="link1"></a>リンク1 <div style="height:200px;"></div><!-- 余白 --> <a id="link2"></a>リンク2 <div style="height:200px;"></div><!-- 余白 --> <a id="link3"></a>リンク3 <div style="height:200px;"></div><!-- 余白 --> <a id="link4"></a>リンク4 </body> </html> |
oya.html(親)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<html> <head> <script type="text/javascript"> // messageイベントのコールバック関数を登録します。 window.addEventListener("message", receiveSize, false); function receiveSize(e) { // 【メインの処理】 // messageイベントは一つしか無いので、複数の処理で使いまわすことになります。 // そのため、kodomo.htmlから送信する文字列内に処理内容を識別できる文字列(この場合は'page_nai_link')を // 付けています if( typeof e.data == "string" && 0 == e.data.indexOf("page_nai_link") ){ var scrollVal = parseInt(e.data.replace('page_nai_link', '')); $('html,body').scrollTop(scrollVal); } } </script> </head> <body> <!-- 別途作成したコンテンツを表示(スクロールバー無し・異なるドメイン) --> <iframe src="http://betsu.domain.com/kodomo.html" id="" height="950" style="border:0" /> </body> </html> |