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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

1684閲覧

ページ遷移でカウントダウンを引き継ぎたい

bigcello

総合スコア11

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2018/11/22 14:06

前提・実現したいこと

jQueryでページを遷移してもカウントを引き継げるカウントダウンタイマーを作成しています。
以下のような流れをイメージしているのですがうまく動きません。

(1)ページ読み込み時に、現在時刻に1分を加算した値をクッキーに保存=これを終了時刻とする
(2)setIntervalで毎秒現在時刻を取得し、(1)の終了時刻との差から残り時間を算出しタイマー表示
(3)残り時間がゼロになったら、タイマー部分を「GAME OVER」という表示に切り替える
-----ここからうまく動きません-----
(4)ページのリロードやサイト内でのページ遷移があった場合、すでに保存されている(1)の終了時刻を呼び出し現在時刻と比較…以下同様の動作を実現したい

発生している問題・エラーメッセージ

・ページをリロードした場合、カウントが引き継がれず即「GAME OVER」となってしまう。

該当のソースコード

$(document).ready(function(){ //終了時間をクッキーに保存 if($.cookie('end')){ var end = $.cookie('end'); $('.end').text($.cookie('end')); timer(); } else { var end = new Date(); end.setMinutes(end.getMinutes() + 1); $.cookie('end', end); $('.end').text($.cookie('end')); timer(); } //カウントダウン関数 function timer(){ //1秒ごとに実行 setInterval(function(){ //現在時刻を取得 var now = new Date(); $('.now').text(now); //終了時間と現在時間の差を求め、時分秒形式に変換 var count = Math.floor((end - now) / 1000); //0より大きければカウントダウン続行、小さければ「GAME OVER」を表示 if (count > 0) { var count = toHms(count); $('.count').text(count); } else { $('.count').text("GAME OVER"); } //秒→時分秒への変換関数 function toHms(t) { var hms = ""; var h = count / 3600 | 0; var m = count % 3600 / 60 | 0; var s = count % 60; if (h != 0) { hms = h + ":" + padZero(m) + ":" + padZero(s); } else if (m != 0) { hms = m + ":" + padZero(s); } else { hms = s; } return hms; function padZero(v) { if (v < 10) { return "0" + v; } else { return v; } } } }); } });

試したこと

・setInterval内でクッキーから毎秒終了時刻の取得→結果変わらず
・「var count = Math.floor((end - now) / 1000);」の下でalertでcountの値を表示させると、リロード前は秒数が入るがリロード後は「NaN」となる(アラートでの確認箇所がここでよいのか不明)

jQueryもクッキーも初心者のため、様々なサイトからソースを切り貼りしてここまで来ており、これ以上何を試したらよいかわからない状態です。
解決策をご教授いただければ幸いです。
よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ざっと見たかんじでしかないですが変数endがtimer()の外で定義されていてcountの計算するときに常にUndefined になってませんか?
console.logで確認してみてください。
varなど定義の際はなるべく変数のスコープに合わせて、今回はグローバルで定義された方が良いですね。

追記。
現在はcookieに保存するときにタイマーで回ったときの時間ではなく、アクセスしたときの時間を保管しています。
setInterval()では第1引数即時関数でそのままその内容のみを実行し続けますので、timer()に入る前に保管された情報は更新されません。
setInterval()内でnowをとってきたタイミングでendのcookieを保存するように変更してみてください。

投稿2018/11/23 00:20

編集2018/11/23 06:32
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2018/11/23 03:54

var end=0;timer();function timer(){console.log(end)} PHPじゃないのでスコープは問題ないのでは?
m.ts10806

2018/11/23 04:14 編集

んーたしかに 更にsetInterval()の第一引数で重ねてるので怪しいかなとは思ってたんですが… functionの重ねすぎで問題が特定しづらそうですし。 ご指摘ありがとうございます。 別途解決策探ってみます
guest

0

自己解決

お二方とも回答、アドバイスいただきありがとうございます。
自己解決いたしました。

投稿に書きました通り、リロード後にcountがNaNになる点が気になっていまして、endが日付ではない可能性を疑いました。

試しに3行目の
var end = $.cookie('end');

var end = new Date($.cookie('end'));
として、再度日付形式に変換したところ上手く動きました。

これが正しい解決方法かどうかわかりませんが、希望の形となったため自己解決とさせていただきます。
setInterval()やスコープのご指摘もありがとうございます。
おそらく多々間違いがあると思いますので、1つずつ修正していきたいと思います。

ありがとうございました。

投稿2018/11/23 07:41

bigcello

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/11/23 07:58

ちょっと想定していたものと違う解決策でしたが、やり方は1つではないので想定通りの動きが実現できたのでしたらそれで良いかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問