質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.03%

JavaScriptでカウントダウンタイマーが0でページ遷移

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 549

score 111

いつもお世話になっております。
JavaScriptのカウントダウンタイマーを利用して
カウントが0になった際にページ遷移を行いたいです。
更にクッキー処理を行っています。

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script>
function setCookie (doc, name, value, expires, path, domain, secure) {
 if (3 > arguments.length)
  throw new Error;
 
 var cookie = [ encodeURIComponent (name) + '=' + encodeURIComponent (value) ];
 
 if (expires)
   cookie[cookie.length] = 'expires=' + new Date (expires).toUTCString ();
 
 if (path)
   cookie[cookie.length] = 'path=' + encodeURI (path);

 if (domain)
   cookie[cookie.length] = 'domain=' + encodeURI (domain);

 if (secure)
   cookie.push ('secure');

 doc.cookie = cookie.join ('; ');
}


function getCookie (doc, name) {
 if (2 > arguments.length)
  throw new Error;

 var n = encodeURIComponent (name).replace (/\W/g, '\\$&');
 var v = doc.cookie.match (new RegExp (n + '\\s*=\\s*(.*?)(?:[;,\\s]|$)'));

 return (v) ? decodeURIComponent (v[1]): '';
}


function addDay (dateObj, day) {
 var date = new Date (dateObj);
 date.setDate (date.getDate () + day);
 return date;
}

var COKKIE_NAME = 'hoge';
var target_date = getCookie (document, COKKIE_NAME);


(function () {
 var now = new Date;

 if (target_date) {
  target_date = Date.parse (target_date);
  if (+now > target_date) {
   location.href = 'end.html';
  }
 }
 else { 
  target_date = addDay (now, 1);
  setCookie (document, COKKIE_NAME, String (target_date), addDay (now, 100));
 }
}) ();

</script>
</head>
<body>
<input type="text" id="fuga" size="40">
<script>
(function () {

  var target = document.getElementById('fuga');
 var int = Math.floor;
 
 (function loop () {
  var count = target_date - (new Date);
  var str = [
   int (count % 86400000 / 3600000), ' 時 ',
   int (count % 3600000 / 60000), ' 分 ',
   int (count % 60000 / 1000), ' 秒 ',
   count % 1000, ''
  ].join ('');
  target.value = str;
  
  if (0 < count)
   setTimeout (loop, 20);
  else
   location.href = 'end.html';   
 })();
}) ();
</script>

</body>
</html>

■追記
カウントが0になった際にページ遷移せずにループしてしまいます。

問題は以下の辺りだと思うのですが、わかりません...。

  if (0 < count)
   setTimeout (loop, 20);
  else
   location.href = 'end.html';  

ご教授のほど何卒よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kuma_kuma_

    2020/09/17 14:19

    多分修正漏れです
    location.href = 'htp:next_page.html';

    あと確認ですが「初めてHPを訪れてから24時間過ぎると移動する」という事でしょうか?

    キャンセル

  • m.ts10806

    2020/09/17 14:19

    この場合の「ループ」は何(どんな減少ら意味)を指していますか?

    キャンセル

  • wing283

    2020/09/17 14:24

    kuma_kuma_様
    ご指摘ありがとうございます。修正いたしました。
    また、おっしゃる通り、「初めてHPを訪れてから24時間過ぎると移動する」という事です。

    m.ts10806様
    ページ遷移せずにタイマーが戻るということです。

    キャンセル

回答 2

checkベストアンサー

0

結局直しました。

JavaScriptは確かに変数に型が決まっていないので
文字列型,数値型,日時型どれでも入るけど
使い回しはしないで下さい(target_dateの事)
結局デバックしながら値を追いかける事になります。
今回日時型で統一しました。

あと特別な理由もなしに<body>内に<script>を埋め込まない事
<head>内に収めるようにして下さい 

あと関数
× encodeURI (uri)
○ encodeURI(uri)
へんな隙間開けないでください

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script>
const COKKIE_NAME = 'hoge';    // クッキー名
var target_date;               // 判定日付
var target;                    // カウントダウン表示エレメント

// クッキー書込み処理
function setCookie(name, value, expires, path, domain) {
    var cookie = [];
    var now = new Date;

    cookie.push(name + '=' + value);
    if (path)    cookie.push('path=' + encodeURI(path));
    if (domain)  cookie.push('domain=' + encodeURI(domain));

    cookie.push('expires=' + addDay(now, 100).toUTCString());
    cookie.push('secure');
    document.cookie = cookie.join('; ');
}
// クッキー取得処理
function getCookie(name) {
    var cookies = document.cookie;            //全てのcookieを取り出して
    var cookiesArray = cookies.split(';');    // ;で分割し配列に
    var hogeDate = '';

    for(var c of cookiesArray){                //一つ一つ取り出して
        var cArray = c.split('=');            //さらに=で分割して配列に
        if(cArray[0] == name){                // 取り出したいkeyと合致したら
            hogeDate = new Date(cArray[1]);
        }
    }
    return hogeDate;
}

// 日付データに指定日数追加する
function addDay(dateObj, day) {
    var date = new Date(dateObj);
    date.setDate(date.getDate() + day);
    return date;
}

// 初期処理
function init() {

    var now = new Date;

    target_date = getCookie(COKKIE_NAME);            // 判定日付取得
    target = document.getElementById('fuga');        // カウントダウンエレメント表示取得

    if (!target_date) {
        // 初めてHPにきた時
        target_date = addDay(now, 1);                // 現在時刻より1日追加
        setCookie(COKKIE_NAME, target_date.toLocaleString('ja'));
    }

    // カウントダウン処理開始
    setTimeout("loop()", 500);

}

// カウントダウン処理
function loop(){

    var now = new Date;
    var count = 0;
    var msg = [];
    var h = 0;
    var m = 0;
    var s = 0;

    if (target_date <= now) {

        // クッキー値更新
        target_date = addDay(now, 1);                // 現在時刻より1日追加
        setCookie(COKKIE_NAME, target_date.toLocaleString('ja'));

        // ページ移動
        location.href = 'end.html';
        return;
    }

    // 残り時間表示
    count = target_date.getTime() - now.getTime();
    h = Math.floor(count % 86400000 / 3600000);
    m = Math.floor(count % 3600000 / 60000); 
    s = Math.floor(count % 60000 / 1000);
    if (h) msg.push(String(h) + ' 時 ');
    if (m) msg.push(String(m) + ' 分 ');
    msg.push(String(s) + ' 秒 ');
    target.value = msg.join ('');

    // 次のカウントダウン処理
    setTimeout("loop()", 500);

    return;
}

</script>
</head>
<body onload="init();">
    <input type="text" id="fuga" size="40">
</body>
</html>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/18 18:39

    大変お手間をおかけしてすみません。。
    作り直していただいてありがとうございます!
    もっと勉強して自分でも組めるようにしたいと思いますm(__)m

    キャンセル

0

開始時に目標時間を取得しておいて、その時間が来たかどうかずっとループで
チェックし続ければいいでしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.03%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る