日記
らんきん5!に他サイト埋め込み機能をつけてみたEdit

YouTubeとかでFlashサイトとかでEmbedタグとかを吐いてくれる感じのやつ。

らんきん5!の場合はHTMLコンテンツなんで、iframeで埋め込むんだろうなーということで、ひとまずiframeで埋め込むコードを書いてみた。

うーん、iframeのサイズを指定しないと不格好だ。

じゃあ、javascriptでiframeをリサイズしてみるか。

と思ったけど、iframe内のコンテンツにはクロスドメインアクセスの制限がかかるから、iframe内のjavascriptでコンテンツサイズを取得しても、iframeタグを持つ外側DOMとは直接やりとりできない(他サイト貼り付けだから、基本iframe内外は別ドメイン)。

iframeのスクロールバーの状態とか見て、スクロールが必要かどうかを取得して、そこからiframe内コンテンツのサイズを逆算してみようとか思ったんだけど、スクロールバーとかも基本はiframe内扱いっぽいね。

じゃあ、外側HTMLの方でjavascriptでiframeタグをはき出しつつ、サイズ情報を動的に追加すればいいんじゃないか、とか考えたんだけど、コンテンツ表示サイズ情報がiframe内にあるんだから、サイズ変更JavaScriptコードが内外どちらにあろうと、クロスドメインの壁を越える何らかの方法がないとどうともならないのね。

じゃあクロスドメインとは関係ない、サーバーAPIとしてコンテンツのサイズ情報を取得できるものを用意して、JSONPとかで情報を取得すればいいんじゃね。

と思ったけれども、よく考えたらHTMLコンテンツの表示サイズなんて、ブラウザ側の仕様・設定によって違ってくるから、サーバーサイドAPIとしてコンテンツ表示サイズなんて取得できるわけないよね。まあ雰囲気だけの情報なら取得できなくもないけどさ。

困ったなーと思ってググってみたところ、クロスドメイン通信できるwindow.postMessageというのがあるらしい。それを使ってiframe内の別ドメインから通知を受けて、iframe外でサイズ変更している例があった。

最初window.postMessageで送るデータは、javascriptオブジェクトにしていたんだけど、chrome、firefox、safariとかはそれでも通るのに、IE9だとstringしか通してくれなかったんで、JSONで送って受信側でobjectに戻すようにした。

あと、最初は$(document).readyでのみメッセージを通知していたけど、iframeをwidth: 100%で生成しているんで、ブラウザウィンドウのリサイズによって、HTMLコンテンツの表示サイズは変わりうるから、$(window).resizeでもメッセージ通知した方がいいんだよね。

ってことで、主要なブラウザではだいたい動くようになった。

貼り付けができるのは、質問と回答。たとえば、最近好きなマンガは?という質問ページに行くと、「貼り付け!」というボタンがあるのでそれをクリックすると、以下のような貼り付け用JavaScriptコードが表示される。

[sourcecode language="javascript"]


[/sourcecode]
このコードをHTMLとして埋め込むと、以下のように表示される。

回答の場合も同様に、「貼り付け!」ボタンを押すと、

[sourcecode language="javascript"]


[/sourcecode]

というコードが表示されるんで、それを貼り付けると以下のように表示される。

ここ数年、スパムまみれになった1470.netの惨状をメンテする気になれずに、個人でWebサービスを構築したりするのをほとんどやらないでいた。

その間いろんな新しい技術に対しては、一応ドキュメントなんかは眺めて、雰囲気はだいたいつかんでみてはいるものの、まじめに使ってみるようなことはほとんどせず、実際に自分の手を動かしたらいろんな発見があるものだよね、ってことをすっかり忘れてしまっていた。

今回のたったこれだけのことでも、実際に手を動かすとやっぱりいろいろと発見があるし、特にサンプルコードレベル以上の一通りの機能がそろったサイトを構築してみると、さらにいろんな発見があったりする。

やっぱりいろんな技術に対しては、何となくドキュメントをながめて理解した気分になるだけでなく、実際にそれを使ったミニサービスくらいは作ってみた方がいいね。

というわけで、らんきん5!にはここ数年の遅れを取り戻すために、思いついたことはいろいろ試して盛り込んでいくつもり。

Published At2012-01-16 16:52Updated At2012-01-16 16:52