第5回:twitter の JavaScript Badge を改造する

しつこく twitter ネタでまいります。
前回の記事で JavaScript の Badge がちゃんと動くようになりました。これで CSS を使えば自由にレイアウトできるようにはなったんだけど、もうちょっと詳しくコードを分析する事でより柔軟なカスタマイズができるようになりたいところ。

ってか、自分で使うにはもう一つなので本気で自分が作るようのカスタマイズをしてみます。

1)まずは、標準の JavaScript Badge +日付バグの修正の内容をおさらい

Badge は twitter にログインしたあと、上メニューの Badge にあります。
http://twitter.com/account/badge

それを改造したのが前回の記事です。

<script type="text/javascript">
function relative_time(time_value) {
  time_values = time_value.split(" ");
  time_value = time_values[1]+" "+time_values[2]+", "+time_values[5]+" "+time_values[3];
  var parsed_date = Date.parse(time_value);
  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
  delta = delta + (relative_to.getTimezoneOffset()*60);
  if(delta < 60) {
    return 'less than a minute ago';
  } else if(delta < 120) {
    return 'about a minute ago';
  } else if(delta < (45*60)) {
    return (parseInt(delta / 60)).toString() + ' minutes ago';
  } else if(delta < (90*60)) {
    return 'about an hour ago';
  } else if(delta < (24*60*60)) {
    return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
  } else if(delta < (48*60*60)) {
    return '1 day ago';
  } else {
    return (parseInt(delta / 86400)).toString() + ' days ago';
  }
}

function twitterCallback(obj) {
var id = obj[0].user.id;
document.getElementById('my_twitter_status').innerHTML = obj[0].text;
document.getElementById('my_twitter_status_time').innerHTML = relative_time(obj[0].created_at);
}
</script>
<span id="my_twitter_status"></span> <span id="my_twitter_status_time"></span>
<script type="text/javascript" src="http://www.twitter.com/statuses/user_timeline/{YourID}.json?callback=twitterCallback&count=1"></script>

色の付いているところが前回のカスタマイズ分です。
それ以外はデフォルトなので詳しく分析してみましょう。


・relative_time(time_value)関数

 引数で渡された発言日時をもとに表示用文字列を生成しています。

・twitterCallback(obj)関数

 script タグで JSON 呼び出しをした後のコールバック関数です。
 引数 obj には JSON 形式で発言データがセットされます。
 渡された発言データを getElementById で指定した HTML オブジェクトに流し込んでいます。

・<span id="my_twitter_status"></span> <span id="my_twitter_status_time"></span>

 twitterCallback 関数で取得した発言データを表示するための HTML オブジェクトです。

・<script type="text/javascript" src="http://www.twitter.com/statuses/user_timeline/4296581.json?callback=twitterCallback&count=1"></script>
 scriptタグにより JSONP を呼び出しています。
 呼び出しのURLの詳細は下記の通り(あくまで動作結果からの推測です)
 ◇4296581.json:4296581はyagerのIDなのでそれぞれ自分のIDに読み替えて下さい。
 ◇callback=twitterCallback:コールバックする関数を指定しています。(って事は別の関数も指定できるの?)まあ、そのままで。
 ◇count=1:JSONが返す発言データの数です。意外と知られていませんが1以上を指定するとちゃんと複数件返ってきます。


2)複数の発言を表示したい

「What are you doing?」と聞かれているので今現在のステータスを1件表示できれば良いっちゃ良いんだけど、何件か表示して発言の流れも追えたらな…と思ったのでやってみます。

まず、1)で分析した通り、JSONP の呼び出しパラメータである count によって、callback 関数に返す発言データの数を変更できます。例として5件の発言データを取得しましょう。

<script type="text/javascript" src="http://www.twitter.com/statuses/user_timeline/4296581.json?callback=twitterCallback&count=5"></script>

これで twitterCallback には obj.length=5 の配列になっているJSONオブジェクトがセットされます。
で、デフォルトでは下記のように1件だけを取得するようになっているのですが、

function twitterCallback(obj) {
var id = obj[0].user.id;
document.getElementById('my_twitter_status').innerHTML = obj[0].text;
document.getElementById('my_twitter_status_time').innerHTML = relative_time(obj[0].created_at);
}

これをちゃんと件数分表示するために配列をループで回して展開します。
下の例ではリスト形式に並べる感じにしています。

function twitterCallback(obj) {
var t = document.getElementById('twitter');
t.innerHTML += '<ul>';
for ( i=0; i<obj.length; i++) {
t.innerHTML += '<li>'+obj[i].text+' : '+relative_time(obj[i].created_at)+'</li>';
}
t.innerHTML += '</ul>';
}

・・・

<div id="twitter"></div>

表示するとこんな感じになります。

・なんじゃらほい : less than minutes ago
・どんな感じに表示されるの? : about 3 minutes ago
・えっ? : about 5 minutes ago
・出社しましたー : about 3 hours ago
・帰宅 : about 12 hours ago


3)外部 JS ファイルにまとめよう

ごちゃごちゃ長いので JS ファイルにまとめちゃいましょう。

・twitter.js

function relative_time(time_value) {
time_values = time_value.split(" ");
time_value = time_values[1]+" "+time_values[2]+", "+time_values[5]+" "+time_values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset()*60);
if(delta < 60) {
return 'less than a minute ago';
} else if(delta < 120) {
return 'about a minute ago';
} else if(delta < (45*60)) {
return (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
return 'about an hour ago';
} else if(delta < (24*60*60)) {
return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
return '1 day ago';
} else {
return (parseInt(delta / 86400)).toString() + ' days ago';
}
}
function twitterCallback(obj) {
var t = document.getElementById('twitter');
for ( i=0; i<obj.length; i++) {
t_top = document.createElement("img");
t_top.setAttribute("src","/img/twitter_balloon_top.gif");
t_top.setAttribute("class","twitter_top");
t.appendChild(t_top);
t_mdl = document.createElement("div");
t_mdl.setAttribute("class","twitter_middle");
t_text = document.createElement("span");
t_text.setAttribute("class","twitter_text");
t_text.innerHTML = obj[i].text;
t_mdl.appendChild(t_text);
t_time = document.createElement("span");
t_time.setAttribute("class","twitter_time");
t_time.innerHTML = relative_time(obj[i].created_at);
t_mdl.appendChild(t_time);
t.appendChild(t_mdl);
t_btm = document.createElement("img");
t_btm.setAttribute("src","/img/twitter_balloon_bottom.gif");
t_btm.setAttribute("class","twitter_bottom");
t.appendChild(t_btm);
}
}
document.write(
'<scr'+'ipt '
+'type="text/javascript" '
+'src="http://www.twitter.com/statuses/user_timeline/4296581.json?callback=twitterCallback&count=5">'
+'</scr'+'ipt>'
);

この場合の twitterCallback 関数はこのサイトのレイアウト用に DOM 関数を使って IMG とか読み込んでますがその辺は各位頑張って理解して下さい(だんだん乱暴になってきた)。

で、あとはこんな感じで呼び出せばOK。

<div id="twitter"></div>
<script type="text/javascript" src="/js/twitter.js"></script>


4)twitter のサーバが重い時のための対処

twitter 流行り過ぎかしらんけど結構レスポンス遅い時があるけど、 JSONP が返ってこなくて画面が固まっちゃう事があるので script タグは body の一番最後に置いとくと影響が少ない。

<div id="twitter"></div>

・・・色々HTML・・・

<script type="text/javascript" src="/js/twitter.js"></script>
</body>
</html>


やっと完成です。ご苦労様でした。


関連エントリー

 ・第6回:TinyURL の遷移先が怖くて開けない場合の対処法
 ・第4回:twitter の JavaScript Badge をIEで表示するとおかしい件に対応してみる ::: creazy photograph


参考

 ・Going My Way: Twitter の Status を自分のブログに貼り付け可能な Javascript Badge
 ・Going My Way: Twitter のステータスを自分のブログの 2 ヶ所に貼り付ける際に気をつけること
 ・Twitter Badge を貼ってみる -- Baldanders.info
 ・subtech - otsune's SnakeOil - Simple twitter status JavaScript

同じカテゴリーの記事

このページの一番上に戻る
  • Facebook
  • Twitter
  • Tumblr
  • Instagram
  • miil