こんにちは,太田です。前々回はJSONP,前回はXMLHttpRequestについて解説しました。今回は,ここまでの12回で取り上げた内容を使って簡単なアプリケーションを作成してみます。
アプリケーションの設計
第9回で取り上げたTwitter検索を行うJavaScriptをベースに,簡易Twitter検索クライアントを実装してみましょう。
機能は以下のとおりです。
- 任意のキーワードで検索
- 60秒おきに自動で新しい検索結果を取得
- @ユーザー名はTwitterにリンク
- URLと思われるところはリンクに
- ハッシュタグをクリックしたときはそのハッシュタグで検索
- 短縮されたURLを展開
なお,機能的にはIE 6~8もほかのブラウザと同等の実装にしますが,見た目について(具体的には角丸)はIEでは再現しません。
検索の骨組み
まずは任意のキーワードで検索する部分を見ていきましょう。まずはHTMLです。
検索フォームのHTML
<form id="searchform">
<input type="search" id="searchvalue" value="JavaScript">
<select id="searchlang">
<option value="all">all</option>
<option value="ja">ja</option>
</select>
<input type="submit" value="検索">
</form>
続いて,JavaScriptです。
検索フォームのJavaScript
var searchform = document.getElementById('searchform');
var searchvalue= document.getElementById('searchvalue');
var searchlang = document.getElementById('searchlang');
var timer = document.getElementById('timer');
var lang = '';
var TwitterAPI = 'http://search.twitter.com/search.json';
function getJSONP(query){
var script = document.createElement('script');
script.src = TwitterAPI + query;
document.body.appendChild(script);
}
searchform.onsubmit = function(){
lang = searchlang.value;
getJSONP('?callback=TwitterCallback&lang='+lang+'&q=' +
encodeURIComponent(searchvalue.value));
return false; // submitをキャンセル(ページ遷移させない)
};
フォームのsubmitを使用している点がポイントで,これによりキーワードの入力後Enter(Return)したときにsubmit(検索)することができますし,(今回は実装していませんが)JavaScriptを無効にしていた場合にサーバー側で検索するように対応することも容易になっています。
なお,submitイベントの処理はaddEvent関数を定義して次のようにしてもよいでしょう。
submitイベントの処理
var addEvent = (document.addEventListener) ?
function(node,type,handler){
node.addEventListener(type,handler,false);
}
: function(node,type,handler){
node.attachEvent('on' + type, function(evt){
handler.call(node, evt);
});
};
addEvent(searchform,'submit',function(evt){
lang = searchlang.value;
getJSONP('?callback=TwitterCallback&lang='+lang+'&q=' +
encodeURIComponent(searchvalue.value));
// submitをキャンセル(ページ遷移させない)
if (evt.preventDefault) {
evt.preventDefault();
} else {
evt.returnValue = false;
}
});
今回のようなシンプルなアプリケーションではaddEventListener,attachEventを使うメリットは特にないので,onsubmitのシンプルな記述がよいかもしれません。
タイムラインの実装
続いて,JSONPのコールバック部分を実装していきます。まず,検索結果を表示するためのHTMLです。
タイムラインの骨組み
<div id="search-result" class="twsrrlt"></div>
<div id="timer"></div>
<ul id="search-tmpl" style="display:none;">
<li>
<a class="usr" target="_blank">
<img width="48" height="48"><br>
<span></span>
</a>
<p class="entry"></p>
<div class="time">
<a class="source" target="_blank"></a>
<a class="username" target="_blank"></a>
<a class="timelink" target="_blank"></a>
</div>
</li>
</ul>
id="search-result" が検索結果を表示する入れ物で,id="search-tmpl" はテンプレートです。このあたりは第9回とほとんど同じです。
さてコールバックの処理ですが,今回は「60秒おきに自動で新しい検索結果を取得」という処理を行うので,元の結果を残したまま追加するパターンを用意します。
コールバックの処理
var tmpl = document.getElementById('search-tmpl').
getElementsByTagName('li')[0];
var timeline = document.getElementById('search-result');
var tree;
var prev_result;
function TwitterCallback(data){
if (prev_result){
// 前回の結果に継ぎ足す場合
write_timeline(data);
} else {
clear();
write_timeline(data);
start_timer();
}
prev_result = data;
}
function clear(){
if(tree){
timeline.removeChild(tree);
tree = null;
}
}
prev_resultという変数にJSONPで取得したデータを保持しておき,そのデータがあるときはclearせずにタイムラインの追加処理だけ行うようにしています。また,prev_resultがnullのときはtimerを起動するようにしています。
自動更新の実装
先にstart_timerの中を見てみましょう。
start_timerの処理
var TIME = 60, timerID;
function start_timer(){
var time = TIME;
timerID = setInterval(function(){
time--;
timer.innerHTML = time;
if(time === 0){
time = TIME;
if (prev_result){
getJSONP(prev_result.refresh_url +
'&callback=TwitterCallback&lang='+lang);
}
}
}, 1000);
}
setIntervalで1秒おきにカウントダウンを行い,0になったときにカウント用の変数を元の値に戻し,JSONPで次の結果を取得しています。
なお,timerIDとprev_resultは先程のonsubmitにおいてリセットするようにします。
submitイベントの処理#2
searchform.onsubmit=function(){
prev_result = null;
clearInterval(timerID);
lang = searchlang.value;
getJSONP('?callback=TwitterCallback&lang='+lang+'&q=' +
encodeURIComponent(searchvalue.value));
// submitをキャンセル(ページ遷移させない)
return false;
};

