libro
www.tuyano.com
JavaScriptによるHTML5プログラミング入門

Web Messagingによるメッセージ通信 (4/4)

作成:2012-04-30 11:08
更新:2012-04-30 11:08

■MessageChannelを使ってメッセージ通信をする

では、MessageChannelを利用したメッセージ通信を行なってみましょう。先ほどのindex.htmlとinline.htmlを修正して利用してみます。下のリスト欄のようにコードを書き換えてください。

ここでは、index.htmlに4つのinline.htmlを埋め込んでいます。そして入力フィールドに適当にテキストを書いて、ボタンをクリックしましょう。入力したテキストと、メッセージの送信回数をカウントした値がそれぞれのインラインウインドウへと送られます。そして再度index.htmlへとメッセージが戻されてきます。

実際にやってみるとわかりますが、1つ目のインラインウインドウから戻されたメッセージでは「onMessage1」が、2つ目のインラインウインドウからのメッセージでは「onMessage2」が、同様に3,4番目のものでは「onMessage3」「onMessage4」が、それぞれ呼び出されるようになっていることがわかります。

まず、送信するindex.html側を見てみましょう。document.querySelectorAll('iframe');ですべてのインラインフレームのDOMオブジェクトを取得し、それをfor構文で繰り返し処理しています。
var channel = new MessageChannel();
繰り返し内では、まずnew MessageChannelでオブジェクトを作成し、それからport1onmessageを設定します。
channel.port1.addEventListener('message',funcs[i]);
ここで、オブジェクトごとにことなるonmessageイベント用関数を設定しておきます。そして、ポートをstartし、作成したMessageChannelのポート2を引数に指定してpostMessageを行います。
channel.port1.start();
iframes[i].contentWindow.postMessage("" + counter++ + ":" +
    val ,'http://localhost/',[channel.port2]);
これで、MessageChannelを指定してメッセージを送信しました。では、それを受けるinline.html側はどうなっているでしょうか。
msg = 'message:' + event.data;
document.querySelector('#msg').innerHTML = msg;
まず、event.dataから送信されてきた値を取り出し、メッセージを表示しています。これは同じですね。違ってくるのは、メッセージを返信するところです。
var obj = event.ports[0];
obj.postMessage(msg);
MessageEventの「ports」からMessagePortオブジェクトを取り出します。そしてこのオブジェクトの「postMessage」を呼び出して値を送信します。

実際にサンプルを動かしてみると、4つのインラインフレームにメッセージをまとめて送っていますが、返送されたメッセージの処理は、それぞれ異なるメソッドで処理されていることがわかります。これなら、「このメッセージはどのウインドウからのものだっけ?」と悩むことはありませんね!

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

※index.html

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<title>タイトル</title>
	<style>
	h1 { font-size: 14pt; padding: 1px 10px;
		border-style: solid; border-width: 0px 0px 2px 7px; border-color:red; }
	body { background: #FFEECC; }
	article { background: white; margin: 10px;  padding: 10px;}
	</style>
	<script type="text/javascript">
	var counter = 0;
	var funcs = new Array(onMessage1, onMessage2,onMessage3,onMessage4);
		
	function doAction(){
		var val = document.querySelector('#input').value;
		var iframes = document.querySelectorAll('iframe');
		for(var i = 0;i < iframes.length;i++){
			var channel = new MessageChannel();
			try {
				channel.port1.addEventListener('message',funcs[i]);
			} catch(e){}
			channel.port1.start();
			iframes[i].contentWindow.postMessage("" + counter++ + ":" + 
				val ,'http://localhost/',[channel.port2]);
		}
		document.querySelector('#msg').innerHTML = "※送信しました。<br>";
	}
	
	function onMessage1(event){
		document.querySelector('#msg').innerHTML += "result from Channel 1: " + 
			event.data + "<br>";
	}
	function onMessage2(event){
		document.querySelector('#msg').innerHTML += "チャンネル2から、" + 
			event.data  + " って返ってきた。<br>";
	}
	function onMessage3(event){
		document.querySelector('#msg').innerHTML += "<b>[CHANNEL  3]</b> " +
			 event.data + "<br>";
	}
	function onMessage4(event){
		document.querySelector('#msg').innerHTML += "最後の4チャンは「" + 
			event.data  + " 」だってさ<br>";
	}

	</script>
 </head>
 <body>
	<header>
		<h1>WebMessaging Sample</h1>
	</header>
	<article>
		<p id="msg">Web Messaging</p>
		<input type="text" id="input">
		<button onclick="doAction();">click</button>
		<hr>
		<iframe src="inline.html" id="inframe1" frameborder="1px" 
			width="250px" height="150px"></iframe>
		<iframe src="inline.html" id="inframe2" frameborder="1px" 
			width="250px" height="150px"></iframe>
			<br>
		<iframe src="inline.html" id="inframe3" frameborder="1px" 
			width="250px" height="150px"></iframe>
		<iframe src="inline.html" id="inframe4" frameborder="1px" 
			width="250px" height="150px"></iframe>
	</article>
</body>
</html>


※inline.html

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<title>インライン表示</title>
	<style>
	h1 { font-size: 14pt;  padding: 1px 10px;
		border-style: solid; border-width: 0px 0px 2px 7px; border-color:blue; }
	body { background: #DDEEFF; }
	article { background: white; margin: 10px; padding: 10px; }
	</style>
	<script type="text/javascript">
	window.addEventListener('message', function(event){
		var msg = 'message:' + event.data;
		document.querySelector('#msg').innerHTML = msg;
		var obj = event.ports[0];
		obj.postMessage(msg);
	});
	</script>
 </head>
 <body>
	<header>
		<h1>Inline page</h1>
	</header>
	<article>
		<p id="msg">web messaging</p>
	</article>
</body>
</html>

※関連コンテンツ

「JavaScriptによるHTML5プログラミング入門」に戻る