【特別企画】 トラフィックエクスチェンジを作ってみよう! > 2、タイマーを作ってみる

タイマーを作ってみる

トラフィックエクスチェンジと言えばフレームと、そしてタイマーです。 この2つがそろわなきゃトラフィックエクスチェンジとは呼べません。 画面の上部にタイマーがあって、その下に広がるフレームにユーザーのページが表示される。 これぞまさにトラフィックエクスチェンジってもんです。想像するだけで血がたぎってくるぜ。なぁ兄弟? ガハハ。

というわけで前回作成したフレームだけの画面にタイマーを追加していきましょう。

さて、本来タイマーがあるべき箇所が今どうなっているかというと、 こうなっているのでした。

<!-- タイマーが表示される側 -->
<div id="surfNavi">
    あとxx秒
</div>

このままでは画面に「あとxx秒」と固定された文字列が表示されるだけです。 何億年待っても表示は変化してくれません。 地球が滅ぶか、あなたの忍耐が切れるか、食うか食われるかの時空を超えたバトルフィールドってやつです。 そんなバトルはイヤなので、みんなの大好きなJavaScriptを使ってこの表示が時間とともに変化するようにしましょう。

その前に、JavaScriptを知らないお友達のために少しだけ練習です。 ソース内のどこでもいいので下記のコードをコピペしてみてください。 どこでもいいです。できるだけ斬新な場所を選んだるわコンニャロメぐらいの気概でどうぞ。

<script>
    
    alert("JavaScriptです。");
    
</script>

ブラウザで表示してみましょう。こんな感じになったら成功です。

ブラウザの種類によって多少見た目が違うでしょうけれど、想像力で補ってください。イマジネーションでメイクアップしてください。 表示されなかったお友達はコピペする場所が斬新すぎたのかもしれません。生まれてくる時代が早すぎたのかもしれません。 世間を冷やかに眺めつつ、場所を変えながら試行錯誤してみてください。 ちなみに headタグの内部に書くのがそこそこ推奨された慣例らしいですよ。外部ファイルに分ける方法もあるとかないとか。

はい、というわけでこれがJavaScriptでした。いえーい。パチパチパチ。
以後、alertは削除して、scriptタグの中に処理を書いてまいります。 JavaScriptそのものの説明は省略ぎみで進行していきますが、 難しいことはしない予定なので魂で読解してください。難しかったらごめんね。

さて、JavaScriptで表示を変化させられるように、タイマーの数字が表示される箇所のHTMLを次のようにします。

<!-- タイマーが表示される側 -->
<div id="surfNavi">
    あと<span id="timer"></span>秒
</div>

空のspanタグにid属性をつけて、その値を "timer" としました。 これでJavaScriptの側から "timer" という名前でこの箇所を操作することができます。

やってみましょう。
先ほど試したalertを削除して、代わりに次のように書いてみてください。

<script>

    var timer = document.getElementById("timer");
    timer.innerHTML = "残りの秒数ですよ。";

</script>

ブラウザで表示してみると……

よし完璧!

つまり "残りの秒数ですよ。" の部分を数字にして、定期的に(1秒おきに)減らしていけばいいってワケっすね?  多分なんかそういう定期的に実行するような機能がJavaScriptにあるってワケっすね?  じゃあ早速やってみようぜ! 我ワクワクせざるを得ぬぅ!

と、突っ走っていきたいのはヤマヤマですが、 上記のサンプルではうまくいかなかったお友達がいると思います。

上記の処理は、HTMLのソース側に id="timer" という属性のついたタグが存在していることが大前提です。 え? 間違いなく って書いたじゃないか、って?
はい、それです。
scriptタグはどこに書いてもいいと言いましたが、実は書いた場所によって、実行されるタイミングが違うのです。

じゃあどこに書けばいいんだ? って話ですよね。 今の理屈で言うと <span id="timer"> よりも下に……ということになります。

多分それでうまくいくんじゃないかとは思うのですけど…… そんなことを意識してスクリプトを書く位置をゴソゴソと移動させなきゃいけないものなんですかね?  要は、HTMLが全部画面に表示された後でJavaScriptの実行が開始されてくれるといいよね、って話なのですが……。

というわけで、次のようにするぜ。

<script>
    
    function start() {

        var timer = document.getElementById("timer");
        timer.innerHTML = "残りの秒数ですよ。";
    
    }

</script>

処理全体を関数の中に入れました。
"function" というのがJavaScript的に「これは関数ですよ」という意味です。
"function start()" で "start" という名前の関数です。
そして中カッコ "{.....}" で囲むと、その内部が関数の処理内容ということになります。

え? 関数とは何? って?
えーっと、えーっと、

要するに

「イキナリ勝手に実行されるんじゃなくて、こっちから呼び出したときだけ実行される部分!」

ぐらいの理解でいいんじゃないかな? 
多分この説明だとエライ人に怒られるのですが、エライ人は怒るのが仕事なので怒らせてあげましょう。

さて、「呼び出したときだけ実行される」ので、このままでは実行されません。 実行したいタイミングはいつだったでしょう? 「HTMLが全部表示された後」でしたね。 というわけで、bodyタグに「イベントハンドラを指定」します。

    <body onload="start();">
        <!-- タイマーが表示される側 -->
        <div id="surfNavi">
            あと<span id="timer"></span>秒
        </div> 
        <iframe id="surfFrame" src="defaultPage.html"></iframe>
 
    </body>

bobyタグに onload 属性を追加しました。
これを日本語に意訳すると「bodyタグの中身が表示されたら "start関数" を実行する」です。 エライ人がツッコミたくてうずうずしてる様子が目に浮かびますが、あくまで「意訳」ですから。便利な言葉ですね意訳。

さて、これで無事に動いてくれるハズです。さきほどうまくいかなかったお友達はもう一度試してみてください。 うまくいったお友達も以降はこの方式で進めていきますので書き換えておいてください。
ではこの「残りの秒数ですよ。」の代わりに数字を入れて、それを定期的に(1秒おきに)減らしていこうではありませんか。

JavaScriptのタイマー機能

setTimeout というものを使います。 これを使うと、

「指定した処理を」「指定したミリ秒後」に実行する

ということができます。

さて、我々のやりたい処理は何か?
それは、「あとxx秒」の数字を1秒おきに減らしていく、という処理です。

やってみましょう。

<script>
    
    // 最初に実行される処理(あ、ちなみに 「//」 の後ろは「コメント(メモ書き)」です)
    function start() {

        var timer = document.getElementById("timer");
        timer.innerHTML = "残りの秒数ですよ。";
        
        // countDownという名前の関数を 1000ミリ秒後に実行
        setTimeout ( countDown, 1000 );
    }
    
    
    // カウントダウンの処理(コメント内の文字列は実際の処理には関係ありません)
    function countDown() {
        
        alert("来たぜ");
        
    }
    

</script>

これでブラウザで表示してから1000ミリ経過後にcountDown関数が実行されることでしょう。

↓1000ミリ秒経過

よーし、これで1000ミリ秒ごとに何度でも実行される……と見せかけて、そうはなりません。 最初の1000ミリ秒後に1回だけ実行されてそれで終わりです。 むむむ、キサマそれでもトラフィックエクスチェンジか!
ではどうすればいいのでしょう軍曹殿?
countDownの中にも setTimeout を書いておけッッ!

    // カウントダウンの処理(コメント内の文字列は実際の処理には関係ありません)
    function countDown() {
        
        alert("来たぜ");
        
        // また来るぜ
        setTimeout ( countDown, 1000 );
    }

これで「来たぜ」のアラートダイアログを閉じてからさらに1000ミリ秒後に再び「来たぜ」と表示されるぜ。
ちなみにこのまま実行すると1000ミリ秒ごとに延々とアラートダイアログが出続けるという大変うっとうしいことになります。 やっちまったお友達は頑張ってブラウザを黙らせてね。

さて、ここまで来たら後はもう楽勝ですね。 「来たぜ」とか言ってポーズをキメる代わりに黙ってタイマーの残り秒数を減らしていけばよい。

<script>
    
    // 初期の秒数。あ、これは「変数」ね。「変数」ってのはもちろん「変な数」ってことね。はいお約束お約束。
    var time = 10;
    
    // 最初に実行される処理
    function start() {
        
        // 秒数を表示
        var timer = document.getElementById("timer");
        timer.innerHTML = time; // ← 変数で入れている。「を」じゃなくて「で」ってところがエライ人的にエキサイティングでしょう? ね、エライ人?
        
        // countDownという名前の関数を 1000ミリ秒後に実行
        setTimeout ( countDown, 1000 );
    }
    
    
    // カウントダウンの処理
    function countDown() {
        
        // 秒数を減らして……
        time -= 1; // あ、これ「マイナス1する」って意味ね。「--time」でも可。「time = time - 1」でも可。

        // 表示を更新
        var timer = document.getElementById("timer");
        timer.innerHTML = time;
        
        // 1000ミリ秒後に再び来るぜ。どうでもいいですがいちいち1000ミリって言うと某栄養ドリンクみたいですな。
        setTimeout ( countDown, 1000 );
    
    }
    

</script>

さてこれで……



よしよし、順調に秒数がカウントダウンされておりますね。



むむ?



むむむ!

順調過ぎるとはまさにこのこと。コンピューターというものの愚直さに流れる涙を止めることができません。 きっと我々人類が滅んだ後も廃墟になった都市で律儀にロボットが動き続けているのでしょうねぇ。しみじみ。 で、実は我々人類もそれ以前の知的生命体が作ったロボットで、 彼らが滅んだ後に地球上をさまよっている存在だったのだ! ガビーン! みたいな、これ何のネタ?

はい。つまりカウントがゼロになったら処理を変えないといけないのでしたね。
どういう処理にするかと言うと、

「次のページを表示して」「カウントを元に戻す」

うむ。まさにオートサーフ。我々の目指すべき世界がそこにある。それ以外のものなど求めぬ! 望まぬ! 想像せぬ!

「次のページを表示」を実現するにはPHPと言うとぉ〜ってもムズかちぃ〜モノを使ってサーバーサイドの処理をしなきゃいけないので、 そこは次回のお楽しみとしましょう。 今回はその部分には手をつけず、「ゼロかどうかを判定して」「カウントを戻す」ところまでを整えておきましょう。

以下、その修正を含めた今回の分のソース全文です。
(そろそろスタイルシートとJavaScriptを外部ファイルに分けた方がいい長さかもしれない)

surf.html
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>トラフィックエクスチェンジだぜ!</title>

        <script>
        
            // 初期の秒数。
            var time = 10;
        
            // 最初に実行される処理
            function start() {
                
                // 秒数を表示(関数化しました)
                updateTimer();

                // countDownという名前の関数を 1000ミリ秒後に実行
                setTimeout ( countDown, 1000 );
            }
    
            // タイマーの表示を更新
            function updateTimer() {
    
                var timer = document.getElementById("timer");
                timer.innerHTML = time;
            }
            
            // カウントダウンの処理
            function countDown() {
        
                // カウントダウン
                time -= 1;
        
                // そしてゼロ判定
                if ( time <= 0) {
            
                    // ゼロになっていたら「サーフ完了」の処理を実行
                    surfCompleted();

                } else {
            
                    // まだゼロじゃないので、再びタイマーをセット
                    setTimeout(countDown, 1000);
                }
        
                // タイマーの表示を更新
                updateTimer();
        
            }
            
           // サーフ完了時の処理
            function surfCompleted() {

                /*
                    次回のお楽しみ
                    (あ、これは「複数行のコメント」です)
                */

                // 今日のところはタイマーの数字を元に戻して再びカウント続行することにします。
                time = 10;
                updateTimer();
                setTimeout(countDown, 1000);
            }

        </script>

        <style>
            /*  画面端のスキマをぴっちりと詰めておく */
            html,body {
                margin:0;
                padding:0;
                height : 100%;
            }

            /*  タイマー側 */
            #surfNavi {
                width : 100%;
                height : 20%;
                background-color : #eeeeff;
            }

            /*  宣伝ページ側 */
            #surfFrame {
                width : 100%;
                height : 80%;
                border : 0px;
                position : absolute;
            }
        </style>

    </head>
    <body onload="start();">
    
        <!-- タイマーが表示される側 -->
        <div id="surfNavi">
            あと<span id="timer"></span>秒
        </div> 
        <iframe id="surfFrame" src="defaultPage.html"></iframe>
 
    </body>
</html>

次回予告

フレームとタイマーがそろった! 俄然トラフィックエクスチェンジらしくなって参りました。 が、ここから先へ進むにはサーバーサイド処理という修羅の領域に踏み込まねばなりません。

というわけで次からはPHPを使います。
PHPを使って何をするかと言えば、今回のラストから想像できるように、 登録されているユーザーのページを切り替えて表示…… と言いたいところですが、そもそもそのユーザーのページって、どこでどうやって登録されてるんですか? 
なので次回はサーフ画面からは少し離れて、そこのところに視点を移した内容です。お楽しみに!

サイトTOPへ戻る
目次へ戻る
前のページ
次のページ