いちばん失敗した人決定戦

javascriptに関する質問です。

ページにアクセスすると残り30分からスタートし、
リロードをしてもアクセスし直しても時間は元に戻ることなく、
30分経過後はずっと00分00秒00のままのカウントダウンタイマーって
どう作ればいいのでしょう?

Javascript全く分からないんでご教授頂ければ幸いです。

A 回答 (8件)

サーバー側で、アクセスした側の時間を記録して管理しているとこはありますか?


100万人アクセスしたらそれをすべて覚えておくのですか?現実的?

ページからフォーカスが外れたら、それまでのカウントを記録するのではなく、
一番最初にアクセスした時間を記録して、そこからの差分でよくないですか?

アクセスした側のPCの時間を基準としているので、曖昧ですよ?大丈夫?
    • good
    • 0

//つづきます



function init () {
 var doc = document;
 var now = new Date;
 var old = CookieManajer.get (doc, LAST_ACCSESS);
 var fDay, oDay;

 if (old) {
  oDay = new Date (old);
 }
 else {
  fDay = new Date (now);
  fDay.setDate (now.getDate () + SAVE_DAY);
  CookieManajer.set (doc, LAST_ACCSESS, now.toString (), +fDay);
  oDay = now;
 }

 disp (DayCounter.create.call (oDay, ENABLE_TIME, null, null, true));
}

init ();
</script>
</body>

DayCounter は、汎用性を持たせようと努力してみました。
基本的には、その日の0時を基準として、何時間おきに、何分か待って始まり、区切りの時間以前でも終了できるようにしました。もちろん繰り替えさないこともできます。
まぁこれを自分が使いこなすかは未知数ですが・・・。
今回の収穫。
Object.prototype.toString.call (obj) ;//typeof xxx
    • good
    • 0

たの かいとうしゃさまの いけんを さんこうに べんきょうのため かきました。

(たぶん)
ながいので ぶんかつします。
ぜんかくくうはくは、はんかくにしてね。

<!DOCTYPE html>
<title></title>

<body>

<p>Day &amp; Time:<input type="text" id="hoge" size="40"></p>

<script>
(function () {

 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 replaceCookie (doc, name, value, expires, path, domain, secure) {
  var oldValue = getCookie (doc, name, value);
  setCookie.apply (null, arguments);
  return oldValue;
 }

 //_________
 
 var CookieManajer = new Function;

 CookieManajer.set = setCookie;
 CookieManajer.get = getCookie;
 CookieManajer.replace = replaceCookie;
 
 this.CookieManajer = CookieManajer;
}) ();

//__________

(function () {

 function DayCounter (base, span, start, end, once) {
  this.baseDate = base;
  this.spanDate = span;
  this.startDate = start;
  this.endDate  = end;
  this.onceFlag = once;
 }

 
 function getRestTime () {
  var base = this.baseDate.getTime ();
  var end  = this.endDate.getTime ();
  var span = this.spanDate.getTime ();
  var start = this.startDate.getTime ();
  var time = (new Date).getTime () - base;
  
  if (! this.onceFlag)
   time %= span;

  if (time < start) return true;
  if (end < time)  return false;
  
  return end - time;
 }
 
 //_________
 
 function padding2 (num) {
  num = Math.floor (num);
  return (num < 10 ? '0': '') + num;
 }


 function split (time) {
  return [
   Math.floor (time / 86400000) + '',
   padding2 (time % 86400000 / 3600000),
   padding2 (time % 3600000 /  60000),
   padding2 (time % 60000  /  1000)
  ];
 }
 

 function setPeriod (day, hour, min, sec, ms) {
  if (31 < day)
   throw new Error;

  var timeValue = Date.UTC (1970, 0, day + 1 || 0, hour || 0, min || 0, sec || 0, ms || 0);
  return new Date (timeValue);
 }
 
 
 function argChecker (arg, defaultValue) {
  switch (Object.prototype.toString.call (arg)) {
  case '[object Number]' : return new Date (arg);
  case '[object Date]'  : return arg;
  case '[object Array]'  : return setPeriod.apply (null, arg);
  }
  return defaultValue;
 }


 function create (span, start, end, once) {
  var d = new Date;
  var e = new Date (d.getUTCFullYear (), d.getUTCMonth (), d.getUTCDate ());

  base = argChecker (this, e);
  span = argChecker (span, setPeriod (1));
  start = argChecker (start, setPeriod (0));
  end  = argChecker (end, span);
  once = !!once;

  return new DayCounter (base, span, start, end, once);
 }
 
 //_________
 
 DayCounter.prototype.getRestTime = getRestTime;
 
 DayCounter.create  = create;
 DayCounter.setPeriod = setPeriod;
 DayCounter.split   = split;
 
 this.DayCounter = DayCounter;

}) ();


// 本題はここから
var ENABLE_TIME = [0, 0, 30]; //[day,hour,min]
var LAST_ACCSESS = 'LastAccess';//クッキーの名前
var SAVE_DAY = 1;//クッキーの保存期間 (day)


function disp (obj) {
 var target = document.getElementById ('hoge');

 setInterval (
  function () {
   var time = obj.getRestTime ();
   target.value =
    ('number' === typeof time)
    ? DayCounter.split (time).join (':')
     : '00:00:00:00';
  }, 1000);
}
    • good
    • 0

ページを閉じてる間の時間はどうするのかな


止める
経過時間(か残り時間)をクッキーかウェブストレージに記録、再開時はその時間を利用

進める
スタートした時間を記録(または30分後にあたる時間をクッキーかウェブストレージに記録)
再度アクセスした際にその時間を過ぎていたら0を表示そうでなければ残り時間を表示

厳しく管理するのならやっぱりサーバー側に記録しないと改ざんされちゃいそうですね。

時間の取得はnew Date()で、毎秒カウントするのはsetIntervalを利用します。
new Date()はそのままnew Date()で引くことで経過ミリ秒を取得できます(1000msで1秒)
hajime = new Date();
keika = new Date() - hajime;
setIntervalの精度はブラウザによってまちまちなので精度が必要な場合は毎回時間を取得して差を求めるのがいいかと思います。

必要なヒントは出したのでレッツトライ!
    • good
    • 0
    • good
    • 0
この回答へのお礼

頂いたURLは参考になりそうですね。Cookie操作の部分がカウントダウンとうまくつなげれるかどうか色々調べてみます。ご回答ありがとうございます。

お礼日時:2012/10/11 11:42

意味あるカウントにしたいのならサーバー側で覚えさせないとダメ

    • good
    • 0
この回答へのお礼

サーバー側に覚えさせる。。勉強不足で失礼しました。色々勉強してみます。ご回答ありがとうございます。

お礼日時:2012/10/11 11:40

流石に全く分からないんじゃ厳しいんじゃないかな…。


難しい内容じゃないから、本を買わずとも入門サイト斜め読みで何とかなる筈。
とりあえず要所を一点だけ。

リロードや次回訪問時にもカウント内容を維持したいなら
カウントする際に、CookieかWebStorageにその数字を保存するよう書いて
カウント開始時にそれをロードしてやれば同じ数字で再開できるよ。
    • good
    • 0
この回答へのお礼

身の丈以上の内容でしたか。。入門サイトから勉強してみます。ご回答ありがとうございます。

お礼日時:2012/10/11 11:38

Javascriptでは、メモリー上でしか動かないので、リロードしたらリセットされます。


それを防ぐには、カウントを始めたらファイルに思えさせるしかありません。
perlやphpで書いてください。
    • good
    • 0
この回答へのお礼

ありがとうございます!勉強不足失礼しました。perlとphp見てみます。

お礼日時:2012/10/11 11:37

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!