postMessageを簡単に
frame間でJavaScript操作するのにpostMessageするのだけど、なんで今回使ったかというとローカルに置いた静的HTMLで使いたかったので。この場合、オリジンが無いのでChromeとかSafariはセキュリティエラーで引っかかってしまう。
下準備
使うのは、jQueryでpostMessageをやり取りするBen AlmanさんのjQuery postMessage
あと、jQuery.param()でシリアライズしたのを元に戻すのに、これを使った
汎用のメッセージレシーバを作る
とりあえず、こんな感じ
messageReceiver.js
var setMessageReceiver; (function($){ setMessageReceiver = function(callbacks) { var data,param,retval ; var target_url = arguments[1] || "*"; $.receiveMessage(function(e) { data = $.deserialize(e.data); if (data.method){ param = data.param || {}; if (typeof(callbacks[data.method]) == "function"){ retval = callbacks[data.method].call(this, param); if (data.retval){ $.postMessage({ method: data.method+'Return', param: retval }, target_url, e.source); } } } }); } })(jQuery);
フレームにレシーバーを設置
さっきのsetMessageReceiver関数を使って、callbackする関数を決めて設置。
例えば、こんな感じ。
<script> setMessageReceiver({ getRootpath: function(param){ return param.a + param.b; } }); </script>
postMessageする
さっきのレシーバーを仕掛けたフレームに対して、こんな感じで。
jQuery.postMessage({method: 'getRootpath', param:{a: 1, b:2}, retval:true}, '*', parent);
第一引数は、レシーバーのcallback関数の指定。param要素でパラメータと、retvalをtrueにすることで再度向こうからこっちにpostMessageしてくれる。
postMessageで返り値がある場合
ということは、postMessageしたフレーム側にもレシーバーを作らないといけない。その場合、postMessageしたmethod名に"Return"を付けたものでcallbackされる。
つまり、先ほどのpostMessageの例だと、
setMessageReceiver({ getRootpathReturn: function(retval){ /* ここにretvalを使った処理 */ } });
となる。
この場合、callbackとなるのでグローバル変数を使ってproxyするかEventListenするしかないのだけど、EventListenがよくわからず。https://developer.mozilla.org/ja/docs/DOM/window.postMessage とかみると、
jQuery(window).bind('message', callback);
とかでいけそうなんだけどなー。