รหัสสำหรับตัวนับถอยหลัง JavaScript อย่างง่าย?


147

ฉันต้องการใช้ตัวจับเวลานับถอยหลังอย่างง่ายเริ่มต้นที่ 30 วินาทีจากเมื่อฟังก์ชั่นทำงานและสิ้นสุดที่ 0 ไม่มีมิลลิวินาที มันจะถูกเข้ารหัสได้อย่างไร?

คำตอบ:


255
var count=30;

var counter=setInterval(timer, 1000); //1000 will  run it every 1 second

function timer()
{
  count=count-1;
  if (count <= 0)
  {
     clearInterval(counter);
     //counter ended, do something here
     return;
  }

  //Do code for showing the number of seconds here
}

ในการทำให้โค้ดสำหรับตัวจับเวลาปรากฏในย่อหน้า (หรือที่อื่นในหน้า) เพียงแค่ใส่บรรทัด:

<span id="timer"></span>

ตำแหน่งที่คุณต้องการให้วินาทีปรากฏ จากนั้นแทรกบรรทัดต่อไปนี้ลงในtimer()ฟังก์ชันของคุณดังนั้นจึงมีลักษณะดังนี้:

function timer()
{
  count=count-1;
  if (count <= 0)
  {
     clearInterval(counter);
     return;
  }

 document.getElementById("timer").innerHTML=count + " secs"; // watch for spelling
}

ขอบคุณสำหรับคำตอบ. ฉันมีปัญหาในการใช้งานเนื่องจากตัวจับเวลาของฉันปรากฏในย่อหน้า ฉันจะวาง 30, 29, 28 และอื่น ๆ ไว้ตรงกลางของย่อหน้าได้อย่างไร
Mike

1
ฉันแก้ไขคำตอบของฉันเพื่อแสดงวิธีแสดงตัวจับเวลาในย่อหน้า :)
คลิก Upvote

2
ในกึ่งกลางของย่อหน้า (แนวนอน): <p id = "timer" style = "จัดเรียงข้อความ: center"> </p>
Alsciende

คลิกตัวจับเวลาของคุณจะแสดง "0 วินาที" เท่านั้น คุณควรใส่การอัปเดต InnerHTML หลังจากการลดค่าไม่ใช่ในกรณีสุดท้าย
Alsciende

1
สวัสดีฉันจะหยุดจับเวลาทำงานเมื่อโหลดหน้าเว็บได้อย่างไรและเมื่อกดปุ่มแล้วเท่านั้น ฉันจะทำให้มันรีเซ็ตตัวจับเวลาได้อย่างไรเมื่อกดปุ่มหลังจากตัวจับเวลาวิ่งไปแล้ว?
crmepham

104

ฉันเขียนสคริปต์นี้เมื่อไม่นานมานี้:

การใช้งาน:

var myCounter = new Countdown({  
    seconds:5,  // number of seconds to count down
    onUpdateStatus: function(sec){console.log(sec);}, // callback for each second
    onCounterEnd: function(){ alert('counter ended!');} // final action
});

myCounter.start();

function Countdown(options) {
  var timer,
  instance = this,
  seconds = options.seconds || 10,
  updateStatus = options.onUpdateStatus || function () {},
  counterEnd = options.onCounterEnd || function () {};

  function decrementCounter() {
    updateStatus(seconds);
    if (seconds === 0) {
      counterEnd();
      instance.stop();
    }
    seconds--;
  }

  this.start = function () {
    clearInterval(timer);
    timer = 0;
    seconds = options.seconds;
    timer = setInterval(decrementCounter, 1000);
  };

  this.stop = function () {
    clearInterval(timer);
  };
}

1
ฉันชอบที่จะใช้สิ่งนี้แทนสิ่งอื่น เมื่อฉันติดอยู่เพื่อเริ่มหมายเลขเริ่มต้นใหม่ฉันเห็นว่ามันทำงานได้ดี ..
Oki Erie Rinaldi

หากฉันต้องการหยุดตัวจับเวลาโดยบังเอิญฉันจะทำอย่างไร
SIJ

@SIJ myCounter.stop();
R3tep

54

เพื่อให้ห่างไกลคำตอบดูเหมือนจะพึ่งพารหัสถูกเรียกใช้ทันที หากคุณตั้งค่าตัวจับเวลา 1,000 มิลลิวินาทีจริงๆแล้วมันจะอยู่ที่ประมาณ 1,1008 แทน

นี่คือวิธีที่คุณควรทำ:

function timer(time,update,complete) {
    var start = new Date().getTime();
    var interval = setInterval(function() {
        var now = time-(new Date().getTime()-start);
        if( now <= 0) {
            clearInterval(interval);
            complete();
        }
        else update(Math.floor(now/1000));
    },100); // the smaller this number, the more accurate the timer will be
}

วิธีใช้โทร:

timer(
    5000, // milliseconds
    function(timeleft) { // called every step to update the visible countdown
        document.getElementById('timer').innerHTML = timeleft+" second(s)";
    },
    function() { // what to do after
        alert("Timer complete!");
    }
);

2
พูดตามที่คุณพูดไปนั่นเป็นวิธีเดียวที่จะทำได้ถูกต้อง!
mcella

3
ฉันยกนิ้วให้กับข้อแม้หนึ่งข้อ - เพื่อวัตถุประสงค์ในการแสดงคุณอาจต้องการแสดงเพดาน (Math.ceil ()) แทนพื้น มันน่าสับสนจริงๆเมื่อนาฬิกาถึง 0 วินาทีก่อนที่ไฟจะเตือน (แน่นอนว่าต้องมีการโทรเพื่ออัปเดตเพิ่มเติม () ก่อนที่จะเสร็จสมบูรณ์ ())
พอลวิลเลียมส์

21

นี่คืออีกหนึ่งถ้าใครต้องการหนึ่งนาทีและวินาที:

    var mins = 10;  //Set the number of minutes you need
    var secs = mins * 60;
    var currentSeconds = 0;
    var currentMinutes = 0;
    /* 
     * The following line has been commented out due to a suggestion left in the comments. The line below it has not been tested. 
     * setTimeout('Decrement()',1000);
     */
    setTimeout(Decrement,1000); 

    function Decrement() {
        currentMinutes = Math.floor(secs / 60);
        currentSeconds = secs % 60;
        if(currentSeconds <= 9) currentSeconds = "0" + currentSeconds;
        secs--;
        document.getElementById("timerText").innerHTML = currentMinutes + ":" + currentSeconds; //Set the element id you need the time put into.
        if(secs !== -1) setTimeout('Decrement()',1000);
    }

คุณไม่ควรส่งผ่านสตริงไปยังพารามิเตอร์แรกของ setTimeout setTimeout(Decrement, 1000)เป็นที่ต้องการ stackoverflow.com/questions/6232574/…
Scottux

ขอบคุณสำหรับคำแนะนำฉันได้อัปเดตสคริปต์แล้ว
Layton Everson

3

// Javascript Countdown
// Version 1.01 6/7/07 (1/20/2000)
// by TDavid at http://www.tdscripts.com/
var now = new Date();
var theevent = new Date("Sep 29 2007 00:00:01");
var seconds = (theevent - now) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
ID = window.setTimeout("update();", 1000);

function update() {
  now = new Date();
  seconds = (theevent - now) / 1000;
  seconds = Math.round(seconds);
  minutes = seconds / 60;
  minutes = Math.round(minutes);
  hours = minutes / 60;
  hours = Math.round(hours);
  days = hours / 24;
  days = Math.round(days);
  document.form1.days.value = days;
  document.form1.hours.value = hours;
  document.form1.minutes.value = minutes;
  document.form1.seconds.value = seconds;
  ID = window.setTimeout("update();", 1000);
}
<p><font face="Arial" size="3">Countdown To January 31, 2000, at 12:00: </font>
</p>
<form name="form1">
  <p>Days
    <input type="text" name="days" value="0" size="3">Hours
    <input type="text" name="hours" value="0" size="4">Minutes
    <input type="text" name="minutes" value="0" size="7">Seconds
    <input type="text" name="seconds" value="0" size="7">
  </p>
</form>


8
สคริปต์นี้ใช้วิธีปฏิบัติที่ไม่ดีจาก 90 และอีก 1.5 ชั่วโมงก็ไม่ใช่ 2 ชั่วโมง ใช้เวลา 1 ชั่วโมง 30 นาที คุณควรใช้Math.floorไม่ใช่Math.round
corbacho

3

เพิ่งแก้ไข@ คำตอบของ ClickUpvote :

คุณสามารถใช้IIFE (เรียกใช้ฟังก์ชั่นการแสดงออกทันที)และเรียกซ้ำเพื่อให้ง่ายขึ้น:

var i = 5;  //set the countdown
(function timer(){
    if (--i < 0) return;
    setTimeout(function(){
        console.log(i + ' secs');  //do stuff here
        timer();
    }, 1000);
})();


2

เมื่อตอบรับเป็นที่ยอมรับเครื่องของคุณจะเข้าสู่โหมดสลีป ฯลฯ อาจทำให้ตัวจับเวลาทำงานล่าช้า คุณจะได้รับเวลาจริงในการประมวลผลเพียงเล็กน้อย นี่จะให้เวลาที่เหลือจริง

<span id="timer"></span>

<script>
var now = new Date();
var timeup = now.setSeconds(now.getSeconds() + 30);
//var timeup = now.setHours(now.getHours() + 1);

var counter = setInterval(timer, 1000);

function timer() {
  now = new Date();
  count = Math.round((timeup - now)/1000);
  if (now > timeup) {
      window.location = "/logout"; //or somethin'
      clearInterval(counter);
      return;
  }
  var seconds = Math.floor((count%60));
  var minutes = Math.floor((count/60) % 60);
  document.getElementById("timer").innerHTML = minutes + ":" + seconds;
}
</script>

0

คุณสามารถทำดังนี้กับ JS บริสุทธิ์ คุณเพียงแค่ต้องให้ฟังก์ชั่นด้วยจำนวนวินาทีและมันจะทำส่วนที่เหลือ

var insertZero = n => n < 10 ? "0"+n : ""+n,
   displayTime = n => n ? time.textContent = insertZero(~~(n/3600)%3600) + ":" +
                                             insertZero(~~(n/60)%60) + ":" +
                                             insertZero(n%60)
                        : time.textContent = "IGNITION..!",
 countDownFrom = n => (displayTime(n), setTimeout(_ => n ? sid = countDownFrom(--n)
                                                         : displayTime(n), 1000)),
           sid;
countDownFrom(3610);
setTimeout(_ => clearTimeout(sid),20005);
<div id="time"></div>


0

จากโซลูชันที่นำเสนอโดย @Layton Everson ฉันได้พัฒนาตัวนับรวมถึงชั่วโมงนาทีและวินาที:

var initialSecs = 86400;
var currentSecs = initialSecs;

setTimeout(decrement,1000); 

function decrement() {
   var displayedSecs = currentSecs % 60;
   var displayedMin = Math.floor(currentSecs / 60) % 60;
   var displayedHrs = Math.floor(currentSecs / 60 /60);

    if(displayedMin <= 9) displayedMin = "0" + displayedMin;
    if(displayedSecs <= 9) displayedSecs = "0" + displayedSecs;
    currentSecs--;
    document.getElementById("timerText").innerHTML = displayedHrs + ":" + displayedMin + ":" + displayedSecs;
    if(currentSecs !== -1) setTimeout(decrement,1000);
}

0

// Javascript Countdown
// Version 1.01 6/7/07 (1/20/2000)
// by TDavid at http://www.tdscripts.com/
var now = new Date();
var theevent = new Date("Nov 13 2017 22:05:01");
var seconds = (theevent - now) / 1000;
var minutes = seconds / 60;
var hours = minutes / 60;
var days = hours / 24;
ID = window.setTimeout("update();", 1000);

function update() {
  now = new Date();
  seconds = (theevent - now) / 1000;
  seconds = Math.round(seconds);
  minutes = seconds / 60;
  minutes = Math.round(minutes);
  hours = minutes / 60;
  hours = Math.round(hours);
  days = hours / 24;
  days = Math.round(days);
  document.form1.days.value = days;
  document.form1.hours.value = hours;
  document.form1.minutes.value = minutes;
  document.form1.seconds.value = seconds;
  ID = window.setTimeout("update();", 1000);
}
<p><font face="Arial" size="3">Countdown To January 31, 2000, at 12:00: </font>
</p>
<form name="form1">
  <p>Days
    <input type="text" name="days" value="0" size="3">Hours
    <input type="text" name="hours" value="0" size="4">Minutes
    <input type="text" name="minutes" value="0" size="7">Seconds
    <input type="text" name="seconds" value="0" size="7">
  </p>
</form>


0

โซลูชันของฉันทำงานกับรูปแบบวันที่ของ MySQL และมีฟังก์ชันเรียกกลับ ในการร้องเรียน คำเตือน: ทำงานได้กับนาทีและวินาทีเท่านั้นนี่คือสิ่งที่ฉันต้องการ

jQuery.fn.countDownTimer = function(futureDate, callback){
    if(!futureDate){
        throw 'Invalid date!';
    }

    var currentTs = +new Date();
    var futureDateTs = +new Date(futureDate);

    if(futureDateTs <= currentTs){
        throw 'Invalid date!';
    }


    var diff = Math.round((futureDateTs - currentTs) / 1000);
    var that = this;

    (function countdownLoop(){
        // Get hours/minutes from timestamp
        var m = Math.floor(diff % 3600 / 60);
        var s = Math.floor(diff % 3600 % 60);
        var text = zeroPad(m, 2) + ':' + zeroPad(s, 2);

        $(that).text(text);

        if(diff <= 0){
            typeof callback === 'function' ? callback.call(that) : void(0);
            return;
        }

        diff--;
        setTimeout(countdownLoop, 1000);
    })();

    function zeroPad(num, places) {
      var zero = places - num.toString().length + 1;
      return Array(+(zero > 0 && zero)).join("0") + num;
    }
}

// $('.heading').countDownTimer('2018-04-02 16:00:59', function(){ // on complete})

0

เพื่อประโยชน์ในการแสดงเราสามารถใช้requestAnimationFrameได้อย่างปลอดภัยสำหรับการวนลูปอย่างรวดเร็วแทนที่จะเป็น setInterval / setTimeout

เมื่อใช้ setInterval / setTimeout หากงานลูปใช้เวลามากกว่าช่วงเวลาเบราว์เซอร์จะขยายช่วงลูปเพียงเพื่อดำเนินการเรนเดอร์แบบเต็ม นี่คือการสร้างปัญหา หลังจากนาทีของsetInterval / setTimeout overload สิ่งนี้สามารถตรึงแท็บเบราว์เซอร์หรือคอมพิวเตอร์ทั้งหมด

อุปกรณ์อินเทอร์เน็ตมีการแสดงที่หลากหลายดังนั้นจึงเป็นไปไม่ได้เลยที่จะเข้ารหัสช่วงเวลาที่แน่นอนเป็นมิลลิวินาที!

ใช้วัตถุวันที่เพื่อเปรียบเทียบวันที่เริ่มยุคและปัจจุบัน นี่เป็นวิธีที่เร็วกว่าทุกอย่างเบราว์เซอร์จะดูแลทุกสิ่งอย่างสม่ำเสมอที่60FPS ( 1000/60 = 1000/60 16.66ms โดยเฟรม ) - หนึ่งในสี่ของพริบตา - และถ้างานในวงต้องมากกว่านั้น เบราว์เซอร์จะปล่อยบาง repaints

สิ่งนี้อนุญาตให้ระยะขอบหน้าสายตาของเราสังเกตเห็น ( มนุษย์ = 24FPS => 1000/24 ​​= 41.66ms โดยเฟรม = ภาพเคลื่อนไหวของเหลว!)

https://caniuse.com/#search=requestAnimationFrame

/* Seconds to (STRING)HH:MM:SS.MS ------------------------*/
/* This time format is compatible with FFMPEG ------------*/
function secToTimer(sec){
  const o = new Date(0), p =  new Date(sec * 1000)
  return new Date(p.getTime()-o.getTime()).toString().split(" ")[4] + "." + p.getMilliseconds()
}

/* Countdown loop ----------------------------------------*/
let job, origin = new Date().getTime()
const timer = () => {
  job = requestAnimationFrame(timer)
  OUT.textContent = secToTimer((new Date().getTime() - origin) / 1000)
}

/* Start looping -----------------------------------------*/
requestAnimationFrame(timer)

/* Stop looping ------------------------------------------*/
// cancelAnimationFrame(job)

/* Reset the start date ----------------------------------*/
// origin = new Date().getTime()
span {font-size:4rem}
<span id="OUT"></span>
<br>
<button onclick="origin = new Date().getTime()">RESET</button>
<button onclick="requestAnimationFrame(timer)">RESTART</button>
<button onclick="cancelAnimationFrame(job)">STOP</button>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.