JavaScript?

擬似クラス化によるリアルタイムカウントダウン表示の実装 - Javascript

※ 擬似クラス/化/による ではありません。 擬似/クラス/化/による です。CSSのあれと紛らわしくてすみません。

概要

  • なんとなくカウントダウンしたいじゃない
  • どうせならUNIX時間指定していくつもいくつもページ内に貼れるようにしたいじゃない
  • さらに欲を出すと
     var c1=new CountDown(1336383401);
    とかやるだけで表示されたら嬉しいじゃない
  • じゃあいつやるか
  • 今でしょ!!

実装


実装にあたり、Javascriptによる擬似的なクラスの生成と継承について適当に学んだ。
このあたりを参考:JavaScript におけるクラスの作成と継承 - vivid memo

次に、ガリガリとコードを書いていく。現在時刻は

 var nowtime=new Date();

とすることで得られる。これはUNIX時間で表されているため、他の言語(主にWebで使用するPHPやPerlやPythonやRubyなど)との親和性が非常によろしい。イイネ!
ただし、JavascriptにおけるUNIX時間はミリ秒まで表されているため、PHPなど、秒までしか表さないような言語とともに扱う際には注意が必要だ。

あとは基本的な演算をバリバリやって、差分の日数・時間数・分数・秒数を計算する。
また、カウントダウンだけでなくカウントアップ(この日から何日みたいな)もやりたいので、ほんの少しだけ演算を工夫する。
文字列生成部分は以下のようになる。

うん、まどろっこしいけど問題ない。

次にカウントダウンを行なって表示させるクラスCountDownを作成しよう。
先ほどのページを参考にざっくり実装する。

よし、これで動くだr・・・あれ?動かない。うーん、困った。

とりあえず怪しそうなところを探してググる。
まず目をつけたのは、

	this.refresh=function(){
		document.getElementById(this.time).innnerHTML=gencd(this.time);
	}

この部分。
更に言うと

 document.getElementById(this.time)

この部分。
エラーコンソールを見るとdocument.getElementById(this.time) is null.が出ていたので、どうやらこれをやるとマズイんだなということで、「"document.getElementById(this."」でググる。
2つほど参考になりそうだと思ったページを読んでみた。
掲示板/JavaScript質問板[過去ログ]/一覧/getElementByIdで要素を取得できない - TAG index Webサイト
JavaScript の不思議な面白さ - 第六回 (Yahoo! JAPAN Tech Blog)
どっちも読んだけどさっぱり僕の状況とは想定が違ってどうしようもない。うーん、手詰まりか。

一旦休憩(たすくすたっくすのメンテ)を挟んで再度コードを睨んでみる。
ん、これってthisがおかしいんじゃないだろうか。
要はCountDownにとってのthisと、setIntervalで呼び出した時のrefreshにとってのthisが違うからダメなんだ。じゃあrefreshの中でthisを処理してる部分を、CountDownのthisの処理に置き換えてやればイイネ!
確信が得られなかったので一応「"setInterval(this."」で調べてみたらドンピシャなものが出てきた。
setInterval() → this でひっかかった - Web系がおもしろい。

Oh, I see!

var CountDown = function(time){
	this.time=time;
	document.write("<p id=\""+this.time+"\"></p>");
	var self=this;
	this.refresh = function(){
		document.getElementById(self.time).innerHTML = gencd(self.time);
	}
	this.refresh();
	setInterval(function(){self.refresh();},1000);
};

Now, all of them work fine. ;)

と思ったけどこのままでは同じtimeのものを複数生成すると表示されないものが出てくるので、

var CountDown = function(time){
	this.time=time;
	this.post=0;
	while(document.getElementById(this.time+"_"+this.post)){
		this.post++;
	}
	document.write("<p id=\""+this.time+"_"+this.post+"\"></p>");
	var self=this;
	this.refresh = function(){
		document.getElementById(self.time+"_"+self.post).innerHTML = gencd(self.time);
	}
	this.refresh();
	setInterval(function(){self.refresh();},1000);
};

という感じに適当にポストフィックスをつけて回避すればいいんじゃないかな。


selfにthisを入れちゃうってのは当初思いつかなかった。こんな一見無茶に思えるようなことやっちゃって大丈夫なのね・・・
Javascriptの深さはまだまだ計り知れないと、そう思い知ったのであった。

使い方

HTML内のヘッダかどこかでcountdown.class.jsを読み込ませておいて、表示したい部分にこれを突っ込む。

<script type="text/javascript">var c1=new CountDown(1336383401);</script>


複数指定したい場合はc1をc2,c3などと変えて新しく宣言してやって、

<script type="text/javascript">
	var c1=new CountDown(1336383401);
	var c2=new CountDown(1436383401);
	var c3=new CountDown(1336583501);
</script>

などとするだけでよい。シンプルすぎていおんさんが大声出してびっくりするぐらい。

使用例

countdown_application.png

配布

countdown.class.js (<1kB)

コメントはこちら



添付ファイル: filecountdown.class.js 374件 [詳細] filecountdown_application.png 458件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-05-16 (水) 00:21:04 (2147d)