現在、多くの Web サイトでフラッシュ セール商品が提供されていますが、その非常に重要な部分はカウントダウンです。
カウントダウンに関しては、いくつか注意すべき点があります:
1. 現地時間の代わりにサーバー時間を使用する必要があります (現地時間にはタイムゾーンやユーザー設定が異なるなどの問題があります)。
2. ネットワーク送信にかかる時間を考慮します。
3. 時刻を取得する場合、AJAX 応答ヘッダー (getResponseHeader('Date') を通じて取得) から直接読み取ることができます。サーバーは特別な時刻生成スクリプトを作成する必要はありません。
プロセス分析:
1. ネットワーク送信にかかる時間に関係なく、サーバーからタイムスタンプを読み取った後に計測が開始されます。
画像内のさまざまな注釈は次のとおりです (上記のタイムラインは標準時間を使用しており、サーバーやページの時間とは関係ありません):
start - ページ項目サーバーが AJAX リクエストを開始する時刻。
www_start - サーバーがページのリクエストに応答し、タイムスタンプをページに返す時刻。
pc_start - ページがサーバーから返されたタイムスタンプを受信し、計測を開始する時刻。
www_end - サーバーのカウントダウンが終了する時刻。
pc_end - ページのカウントダウンが終了する時刻であり、ユーザーがカウントダウンの終了時にボタンをクリックした時刻でもあります。
end - サーバーがユーザーのクリック情報を受信する時刻。
カウントダウンが終了した瞬間(つまりフラッシュセールが始まる瞬間)にユーザーがすぐにマウスをクリックしたとしても、実際のスナップセールが始まる時間(www_end,これは、サーバーのカウントダウンが終了する時刻です) (この時間差は、pc_start - start に正確に等しいことが簡単にわかります。これは、AJAX 送信の開始から応答情報の受信までにかかる時間です)。一部の専門家がスクリプトを使用してページのカウントダウンが終了する前にリクエストを送信した場合、他のユーザーは大きな損失を被ることになります。したがって、この時刻誤差の問題を解決する必要があります。
2. 時間エラーの問題を解決するために、ページのカウントダウン時間を少しだけ短縮します (上記の分析から、この小さな量は pc_start - start に正確に等しいと結論付けることができます)。ユーザーはカウントダウンの終了時にメッセージを送信できることを示します。サーバーへのスナップショット メッセージは、サーバーのカウントダウンの終了時に受信されました:
図内の注釈は図 1 のものと同じです (タイムラインは標準時間を使用しており、サーバーやページの時間とは関係ありません)。2 つの新しい注釈の意味は次のとおりです。
old_pc_end——ネットワーク送信時刻を処理しないpc_endの時刻。
old_end——ネットワーク送信時刻を処理しない終了時刻。
写真2を見ると、時間のかかるネットワーク送信による時間誤差が完全に埋め合わせられていることがわかります。それを補う方法は「カウントダウン終了時刻pc_start - start」を早めることです。ただし、ネットワーク送信に時間がかかることによるエラーの問題と、ユーザーのコンピュータの時刻とサーバーの時刻が異なるという問題は解決されます。これについては、以下で引き続き説明します。
3. ユーザーのコンピュータの時刻とサーバーの時刻には、たとえ複数のタイムゾーンでも差があるはずです。この問題を解決するにはどうすればよいですか?この方法の重要なポイントは次のとおりです:
A. ページはサーバーから返されたタイムスタンプ www_t を受信すると、すぐに計測を開始します。
B. ページは、サーバーから返されたタイムスタンプ www_t を受信すると、現地時間とサーバーから返されたタイムスタンプ t=new Date().getTime() - www_t*1000 との時差を直ちに計算します。
C. setInterval() 関数を使用する代わりに、引き続き new Date().getTime() を使用します (タイマーは非常に不安定で、大きな誤差があります)。ただし、時間表示とプログラム ロジックは、ローカル時刻と前のステップ (B) で取得した時刻偏差 t。
結論ポイント:
ページは、サーバー応答のタイムスタンプを受信したときに計測を開始します。このタイミングは、送信から受信までの AJAX プロセス全体にかかる時間を差し引いたものでなければなりません。計測プロセスは、ローカル時間 (ローカル時間の時刻偏差) を使用して実装されます。
ご質問やご提案がございましたら、メッセージを残してください。ありがとうございます。
JavaScript のヒント: サーバー時間の同期、カウントダウンの同期
インターネットで、ページ上でサーバー時刻を同期的に表示する方法を尋ねている人を見かけました。実際、ほとんどの人は、Ajax を使用してサーバーを毎秒リクエストできるとすぐに考えるかもしれません。次に、サーバーから時刻を取得してページに表示します。これは実現できますが、サーバーに毎秒リクエストするという大きな問題があるため、ユーザーが多すぎるとサーバーがクラッシュします(メモリ使用量)。非常に大きくなる)ので、私の場合、この方法は実現不可能のようです。 以下に、あまり多くのサーバーリソースを消費せずにサーバー時間とカウントダウンを同期できる解決策を示します。
最初のステップでは、ユーザーが初めてページを閲覧すると、サーバーはまず現在時刻を取得してページに表示します (例: ID を使用してタイムボックス スパンに表示します)
2 番目のステップは、1 秒ごとに計算される新しい時間を設定することです (新しい時間はサーバー時間を初期値として使用し、1 秒ごとに 1 秒を累積して新しい時間を生成します)
3 番目のステップ、2 番目のステップで計算された時間を表示します
とても簡単ですね。一言でまとめると、サーバー時刻を初期値として、自動的に 1 秒を加算してページ上で 1 秒ごとに新しい時刻を生成します。サーバー時間、エラーは基本的に数秒以内に表示されます。実装されたコードを見てみましょう。
<span id="timebox">11:21:55</span> //第一次将服务器时间显示在这里 <script type="text/javascript"> $(function () { var oTime = $("#timebox"); var ts = oTime.text().split(":", 3); var tnums = [parseInt(ts[0]), parseInt(ts[1]), parseInt(ts[2])]; setInterval(function () { tnums = getNextTimeNumber(tnums[0], tnums[1], tnums[2]); showNewTime(tnums[0], tnums[1], tnums[2]); }, 1000); function showNewTime(h, m, s) { var timeStr = ("0" + h.toString()).substr(-2) + ":" + ("0" + m.toString()).substr(-2) + ":" + ("0" + s.toString()).substr(-2); oTime.text(timeStr); } function getNextTimeNumber(h, m, s) { if (++s == 60) { s = 0; } if (s == 0) { if (++m == 60) { m = 0; } } if (m == 0) { if (++h == 24) { h = 0; } } return [h, m, s]; } }); </script>
コードは非常に単純なので、ここでは説明しません (上では時、分、秒を表示するだけです。日付を追加することもできます。h==0 の場合、日付または完全な時刻を直接取得できます)理解できない場合は、以下にコメントしてください。時間内に返信します。その後、このアイデアに従って同期カウントダウンを実装します。まず、同期カウントダウンとは何かについて説明します。これはフラッシュ セールに似ており、終了時刻を設定し、現在時刻と終了時刻の間の間隔を計算し、異なるコンピュータやブラウザで表示されるカウントダウン時刻が同じになるようにする必要があります。は次のとおりです:
<!DOCTYPE html> <html> <head> <title>同步倒计时</title> <script type="text/javascript" src="jquery-1.4.4.min.js"></script> </head> <body> <span id="timebox">1天00时00分12秒</span> <!--假设:1天00时00分12秒是从服务器获取的倒计时数据--> <script type="text/javascript"> $(function () { var tid = setInterval(function () { var oTimebox = $("#timebox"); var syTime = oTimebox.text(); var totalSec = getTotalSecond(syTime) - 1; if (totalSec >= 0) { oTimebox.text(getNewSyTime(totalSec)); } else { clearInterval(tid); } }, 1000); //根据剩余时间字符串计算出总秒数 function getTotalSecond(timestr) { var reg = /\d+/g; var timenums = new Array(); while ((r = reg.exec(timestr)) != null) { timenums.push(parseInt(r)); } var second = 0, i = 0; if (timenums.length == 4) { second += timenums[0] * 24 * 3600; i = 1; } second += timenums[i] * 3600 + timenums[++i] * 60 + timenums[++i]; return second; } //根据剩余秒数生成时间格式 function getNewSyTime(sec) { var s = sec % 60; sec = (sec - s) / 60; //min var m = sec % 60; sec = (sec - m) / 60; //hour var h = sec % 24; var d = (sec - h) / 24;//day var syTimeStr = ""; if (d > 0) { syTimeStr += d.toString() + "天"; } syTimeStr += ("0" + h.toString()).substr(-2) + "时" + ("0" + m.toString()).substr(-2) + "分" + ("0" + s.toString()).substr(-2) + "秒"; return syTimeStr; } }); </script> </body> </html>
カウントダウンの精度を確保するために、最初にカウントダウン時間間隔を秒単位で計算し、次に 1 秒を減算して時刻形式を再生成しました。 もちろん、上記の時刻同期の例に従って、時間を直接短縮することもできます。たくさんの方法がありますが、私の方法が最善ではないかもしれません。誰でもコミュニケーションを歓迎します、ありがとう!