요즘 많은 웹사이트에서 깜짝 세일 상품을 선보이고 있는데, 이때 가장 중요한 부분이 바로 카운트다운입니다.
카운트다운과 관련하여 몇 가지 주의사항이 있습니다.
1. 현지 시간 대신 서버 시간을 사용해야 합니다. (현지 시간은 시간대, 사용자 설정 등의 문제가 있습니다.)
2. 네트워크 전송에 소요되는 시간을 고려하세요.
3. 시간을 얻을 때 AJAX 응답 헤더(getResponseHeader('Date')를 통해 얻음)에서 직접 읽을 수 있습니다. 서버는 특별한 시간 생성 스크립트를 작성할 필요가 없습니다.
프로세스 분석:
1. 네트워크 전송에 걸리는 시간에 관계없이 서버에서 타임스탬프를 읽은 후 타이밍이 시작됩니다.
사진 속 다양한 주석은 다음과 같습니다. (위 타임라인은 표준 시간을 사용하며 서버 및 페이지의 시간과는 아무런 관련이 없습니다.)
start - 페이지 항목 서버가 AJAX 요청을 시작하는 시간입니다.
www_start - 서버가 페이지의 요청에 응답하고 페이지에 타임스탬프를 반환하는 시간입니다.
pc_start - 페이지가 서버에서 반환된 타임스탬프를 수신하고 타이밍을 시작하는 시간입니다.
www_end - 서버 카운트다운이 끝나는 시간입니다.
pc_end - 페이지 카운트다운이 끝나는 시간이며, 카운트다운이 끝나면 사용자가 버튼을 클릭한 시간이기도 합니다.
end - 서버가 사용자의 클릭 정보를 수신한 시간입니다.
카운트다운이 끝나는 순간(즉, 플래시 세일이 시작되는 순간) 사용자가 바로 마우스를 클릭하더라도 실제 스냅 세일이 시작되는 시간(www_end, 이는 서버 카운트다운이 끝나는 시간입니다) ( 이 시간 차이는 AJAX 전송 시작부터 응답 정보 수신까지 걸리는 시간인 pc_start - start 와 정확히 동일하다는 것을 쉽게 알 수 있습니다.) 일부 전문가가 페이지 카운트다운이 끝나기 전에 스크립트를 사용하여 요청을 보내면 다른 사용자는 큰 손실을 입게 됩니다. 그러므로 우리는 이 시간오차 문제를 해결해야 한다.
2. 시간 오류 문제를 해결하기 위해 페이지 카운트다운 시간을 소폭 단축하겠습니다(위 분석에서 이 소량은 pc_start - start와 정확히 동일하다는 결론을 내릴 수 있음). 카운트다운이 끝나면 사용자가 메시지를 보낼 수 있습니다. 서버 카운트다운이 끝나자마자 서버에 대한 스냅샷 메시지가 수신되었습니다.
사진의 주석은 그림 1의 주석과 동일합니다. (타임라인은 표준 시간을 사용하며 서버 및 페이지의 시간과 관련이 없습니다.) 두 가지 새로운 주석의 의미는 다음과 같습니다.
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() 함수를 사용하는 대신 새로운 Date().getTime()을 사용하지만(타이머는 매우 불안정하고 오류가 큼) 시간 표시와 프로그램 로직은 이전 단계 (B)에서 얻은 현지 시간과 시간 편차 t입니다.
결론:
페이지는 서버 응답의 타임스탬프를 수신하면 타이밍을 시작합니다. 타이밍은 전송에서 수신까지 전체 AJAX 프로세스에 걸리는 시간을 빼야 합니다. 타이밍 프로세스는 현지 시간(현지 시간 편차)을 사용하여 구현됩니다.
질문이나 제안사항이 있으시면 메시지를 남겨주세요. 감사합니다!
Javascript 팁: 서버 시간 동기화, 카운트다운 동기화
어떤 사람이 인터넷에서 서버 시간을 페이지에 동기적으로 표시하는 방법을 묻는 것을 봤습니다. 실제로 이를 달성하는 방법에는 여러 가지가 있습니다. 대부분의 사람들은 Ajax를 사용하여 매초마다 서버를 요청할 수 있다고 즉시 생각할 수 있습니다. 그런 다음 서버에서 시간을 가져옵니다. 이는 달성할 수 있지만 큰 문제가 있습니다. 즉, 1초마다 서버를 요청하므로 사용자가 너무 많으면 서버가 충돌합니다(메모리 사용량). 매우 클 것임), 그래서 제 경우에는 이 방법이 실현 가능하지 않은 것 같습니다. 서버 리소스를 너무 많이 차지하지 않고 서버 시간과 카운트다운을 동기화할 수 있는 솔루션이 있습니다. 아래에 구현 아이디어를 적어보겠습니다.
첫 번째 단계에서 사용자가 페이지를 처음 탐색하면 서버는 먼저 현재 시간을 얻어서 페이지에 표시합니다(예: ID와 함께 타임박스 범위에 표시됨)
두 번째 단계는 1초마다 계산할 새로운 시간을 설정하는 것입니다. (새 시간은 서버 시간을 초기값으로 사용하고, 1초마다 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초를 뺀 다음 시간 형식을 다시 생성했습니다. 물론 위의 시간 동기화 예시를 따라 직접 줄일 수도 있습니다. 시간이 많이 있습니다. 내 방법이 최고가 아닐 수도 있습니다. 모두가 소통할 수 있습니다. 감사합니다!