หยุด setInterval โทรใน JavaScript


1398

ฉันใช้setInterval(fname, 10000);เพื่อเรียกใช้ฟังก์ชันทุก ๆ 10 วินาทีใน JavaScript เป็นไปได้หรือไม่ที่จะหยุดเรียกมันในบางเหตุการณ์?

ฉันต้องการให้ผู้ใช้สามารถหยุดการรีเฟรชข้อมูลซ้ำได้

คำตอบ:


2160

setInterval()ส่งคืน ID ช่วงเวลาซึ่งคุณสามารถส่งไปที่clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

ดูเอกสารสำหรับและsetInterval()clearInterval()


42
คุณจะเริ่มใหม่ได้อย่างไรหลังจากหยุดด้วย 'clearInterval ()' หากฉันพยายามเริ่มต้นใหม่ฉันจะได้รับ 2x ชุดการเรียกใช้ช่วงเวลา
ด่าน

8
ฉันด้วยทุกครั้งที่ฉันต้องการใช้ SetInterval (MyFunction, 4000); มันจะเร็วขึ้นและเร็วขึ้นในแต่ละครั้งที่ 2x เวลาเร็วขึ้น :( ฉันจะรีสตาร์ท setinterval ได้อย่างไร?
Alireza Masali

14
SetInterval () ไม่เปลี่ยนความเร็วที่คุณผ่าน หากสิ่งที่มันทำความเร็วในแต่ละครั้งที่คุณเรียก SetInterval () แล้วคุณมีหลายตัวนับที่กำลังทำงานในเวลาเดียวกันและควรเปิดคำถามใหม่
EpicVoyage

29
ตรวจสอบให้แน่ใจว่าคุณหยุดมันจริงๆ เพราะการกำหนดขอบเขตตัวแปรที่คุณอาจไม่ได้ Id clearIntervalสิทธิที่จะเรียกร้อง ฉันใช้window.refreshIntervalIdแทนตัวแปรท้องถิ่นและใช้งานได้ดี!
osa

2
ฉันได้เริ่มการติดตั้ง setInterval ไปยังองค์ประกอบที่เกี่ยวข้อง (เมื่อเกี่ยวข้อง): $('foo').data('interval', setInterval(fn, 100));แล้วล้างมันด้วยclearInterval($('foo').data('interval'));ฉันแน่ใจว่ามีวิธีที่ไม่ใช่ jQuery ที่จะทำเช่นกัน
ไมเคิล - Clay Shirky ของ

105

หากคุณตั้งค่าส่งคืนsetIntervalเป็นตัวแปรคุณสามารถใช้clearIntervalเพื่อหยุดมันได้

var myTimer = setInterval(...);
clearInterval(myTimer);

ฉันไม่เห็นความแตกต่างระหว่างสิ่งนี้กับคำตอบของ John
Bobtroopo

51

คุณสามารถตั้งค่าตัวแปรใหม่และให้เพิ่มขึ้นด้วย ++ (นับหนึ่ง) ทุกครั้งที่เรียกใช้จากนั้นฉันจะใช้คำสั่งเงื่อนไขเพื่อสิ้นสุด:

var intervalId = null;
var varCounter = 0;
var varName = function(){
     if(varCounter <= 10) {
          varCounter++;
          /* your code goes here */
     } else {
          clearInterval(intervalId);
     }
};

$(document).ready(function(){
     intervalId = setInterval(varName, 10000);
});

ฉันหวังว่ามันจะช่วยและมันถูกต้อง


3
clearInterval(varName);ฉันรู้สึกประหลาดใจที่จะเรียนรู้ว่างานนี้ ฉันคาดว่าclearIntervalจะไม่ทำงานเมื่อส่งชื่อฟังก์ชั่นฉันคิดว่าต้องใช้ ID ช่วงเวลา ฉันคิดว่าสิ่งนี้สามารถทำงานได้ถ้าคุณมีฟังก์ชั่นที่มีชื่อเพราะคุณไม่สามารถผ่านฟังก์ชั่นที่ไม่ระบุชื่อเป็นตัวแปรภายในตัวของมันเอง
Patrick M

31
ที่จริงฉันคิดว่ามันใช้งานไม่ได้ การหยุดโค้ดถูกเรียกใช้งานเนื่องจากข้อ จำกัด บนตัวนับ แต่ช่วงเวลาจะทำให้การยิง varName () ลองบันทึกทุกอย่างหลังจาก clearInterval () (ภายในส่วนคำสั่งอื่น) และคุณจะเห็นว่ามันถูกเขียนตลอดไป
Rafael Oliveira

5
upvotes มากมายสำหรับสิ่งที่ไม่ทำงานบางครั้งฉันไม่เข้าใจผู้คนเกี่ยวกับ SO: P
Stranded Kid

2
$(document).ready(function(){ });คือ jQuery นั่นเป็นสาเหตุว่าทำไมมันไม่ทำงาน เรื่องนี้ควรได้รับการพูดถึงอย่างน้อย
paddotk

4
@OMGrant นอกเหนือจากตัวอย่างที่ใช้งานไม่ได้คุณมีชื่อตัวแปรvarNameซึ่งเก็บฟังก์ชั่นที่ไม่มีชื่อ - wha ?? คุณควรเปลี่ยนหรือลบคำตอบนี้ IMHO
Dean Radcliffe

13

คำตอบข้างต้นได้อธิบายวิธีที่ setInterval ส่งคืนหมายเลขอ้างอิงและวิธีใช้หมายเลขอ้างอิงนี้เพื่อยกเลิกตัวจับเวลาช่วงเวลา

ข้อพิจารณาด้านสถาปัตยกรรมบางประการ:

โปรดอย่าใช้ตัวแปร "ไม่ จำกัด ขอบเขต" วิธีที่ปลอดภัยที่สุดคือการใช้คุณสมบัติของวัตถุ DOM สถานที่ที่ง่ายที่สุดคือ "เอกสาร" หากผู้อ้างอิงเริ่มต้นใหม่โดยปุ่มเริ่มต้น / หยุดคุณสามารถใช้ปุ่มได้เอง:

<a onclick="start(this);">Start</a>

<script>
function start(d){
    if (d.interval){
        clearInterval(d.interval);
        d.innerHTML='Start';
    } else {
        d.interval=setInterval(function(){
          //refresh here
        },10000);
        d.innerHTML='Stop';
    }
}
</script>

เนื่องจากฟังก์ชั่นถูกกำหนดไว้ในตัวจัดการการคลิกปุ่มคุณไม่จำเป็นต้องกำหนดมันอีก สามารถจับเวลาต่อได้หากมีการคลิกที่ปุ่มอีกครั้ง


1
มีอะไรดีกว่าเกี่ยวกับการวางบนdocumentกว่าบนwindow?
icktoofay

1
การแก้ไข ฉันหมายถึงพูดเอกสาร ในตัวอย่างรหัสของฉันฉันใช้ปุ่มอย่างมีประสิทธิภาพ ไม่มี ID สำหรับปุ่ม แต่ตัวชี้ "นี้" ถูกผูกไว้กับพารามิเตอร์ "d" ในฟังก์ชัน การใช้ "window" เป็นขอบเขตมีความเสี่ยงเนื่องจากฟังก์ชั่นนั้นมีอยู่ด้วย ตัวอย่างเช่น "function test () {}" สามารถเข้าถึงได้ผ่าน window.test ซึ่งเหมือนกับที่ไม่ได้ใช้ขอบเขตเลยเนื่องจากเป็นชวเลข หวังว่านี่จะช่วยได้
Schien

1
อย่าสูญเสียตัวแปร "scope-less" -> อย่าใช้ "scope-less" ฉันจะแก้ไขได้ แต่การเปลี่ยนแปลงน้อยกว่า 6 ตัวอักษรและข้อผิดพลาดเกิดความสับสน
Leif Neland

2
คุณไม่ต้องการ DOM สำหรับสิ่งนั้น เพียงแค่เราเป็น IIFE เพื่อหลีกเลี่ยงมลภาวะระดับโลก
Onur Yıldırım

1
ฉันต้องเพิ่ม 'd.interval = undefined' หลังจาก innerhtml = 'start' เพื่อให้มันทำงานได้อีกครั้ง เพราะแบบนั้นใช้ได้แค่ครั้งเดียว
jocmtb

11

ตอบแล้ว ... แต่ถ้าคุณต้องการตัวจับเวลาที่โดดเด่นและใช้งานซ้ำได้ซึ่งสนับสนุนงานหลายอย่างในช่วงเวลาที่แตกต่างกันคุณสามารถใช้TaskTimerของฉัน(สำหรับโหนดและเบราว์เซอร์)

// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);

// Add task(s) based on tick intervals.
timer.add({
    id: 'job1',         // unique id of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (omit for unlimited times)
    callback(task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
        // stop the timer anytime you like
        if (someCondition()) timer.stop();
        // or simply remove this task if you have others
        if (someCondition()) timer.remove(task.id);
    }
});

// Start the timer
timer.start();

ในกรณีของคุณเมื่อผู้ใช้คลิกเพื่อรบกวนการรีเฟรชข้อมูล คุณสามารถโทรtimer.pause()แล้วtimer.resume()หากพวกเขาต้องการที่จะเปิดใช้งาน

ดูเพิ่มเติมได้ที่นี่


6

สามารถใช้เมธอด clearInterval () เพื่อล้างชุดตัวจับเวลาด้วยเมธอด setInterval ()

setInterval ส่งคืนค่า ID เสมอ ค่านี้สามารถส่งผ่านใน clearInterval () เพื่อหยุดตัวจับเวลา นี่คือตัวอย่างของการจับเวลาเริ่มต้นที่ 30 และหยุดเมื่อมันกลายเป็น 0

  let time = 30;
  const timeValue = setInterval((interval) => {
  time = this.time - 1;
  if (time <= 0) {
    clearInterval(timeValue);
  }
}, 1000);

5

@cnu,

คุณสามารถหยุดช่วงเวลาเมื่อลองเรียกใช้รหัสก่อนดูเบราว์เซอร์คอนโซล ur (F12) ... ลองแสดงความคิดเห็น clearInterval (ทริกเกอร์) ดูคอนโซลอีกครั้งไม่ใช่ beautifier หรือไม่ : P

ตรวจสอบตัวอย่างแหล่งที่มา:

var trigger = setInterval(function() { 
  if (document.getElementById('sandroalvares') != null) {
    document.write('<div id="sandroalvares" style="background: yellow; width:200px;">SandroAlvares</div>');
    clearInterval(trigger);
    console.log('Success');
  } else {
    console.log('Trigger!!');
  }
}, 1000);
<div id="sandroalvares" style="background: gold; width:200px;">Author</div>


3

ประกาศตัวแปรเพื่อกำหนดค่าที่ส่งคืนจาก setInterval (... ) และส่งผ่านตัวแปรที่กำหนดไปยัง clearInterval ();

เช่น

var timer, intervalInSec = 2;

timer = setInterval(func, intervalInSec*1000, 30 ); // third parameter is argument to called function 'func'

function func(param){
   console.log(param);
}

// ทุกที่ที่คุณเข้าถึงตัวจับเวลาที่ประกาศด้านบน call clearInterval

$('.htmlelement').click( function(){  // any event you want

       clearInterval(timer);// Stops or does the work
});

1
var keepGoing = true;
setInterval(function () {
     if (keepGoing) {
        //DO YOUR STUFF HERE            
        console.log(i);
     }
     //YOU CAN CHANGE 'keepGoing' HERE
  }, 500);

นอกจากนี้คุณยังสามารถหยุดช่วงเวลาโดยเพิ่มผู้ฟังเหตุการณ์เพื่อสมมติปุ่มที่มี ID "stop-interval":

$('buuton#stop-interval').click(function(){
   keepGoing = false;
});

HTML:

<button id="stop-interval">Stop Interval</button>

หมายเหตุ: ช่วงเวลาจะยังคงดำเนินการไม่มีอะไรจะเกิดขึ้น


2
นี่คือการกลับมาสำหรับการแสดงผลและสำหรับแท็บพื้นหลังจริงๆแล้วมันจะชะลอตัวจับเวลาอื่น ๆ ทั้งหมดโดยมากเนื่องจากตัวจับเวลาและช่วงเวลาที่มีการควบคุมปริมาณสำหรับแท็บพื้นหลัง
Ferrybig

1

นี่คือวิธีที่ฉันใช้วิธี clearInterval () เพื่อหยุดตัวจับเวลาหลังจาก 10 วินาที

function startCountDown() {
  var countdownNumberEl = document.getElementById('countdown-number');
  var countdown = 10;
  const interval = setInterval(() => {
    countdown = --countdown <= 0 ? 10 : countdown;
    countdownNumberEl.textContent = countdown;
    if (countdown == 1) {
      clearInterval(interval);
    }
  }, 1000)
}
<head>
  <body>
    <button id="countdown-number" onclick="startCountDown();">Show Time </button>
  </body>
</head>


1

ใช้ setTimeOut เพื่อหยุดช่วงเวลาหลังจากนั้นสักครู่

var interVal = setInterval(function(){console.log("Running")  }, 1000);
 setTimeout(function (argument) {
    clearInterval(interVal);
 },10000);

0

ฉันเดารหัสต่อไปนี้จะช่วย:

var refreshIntervalId = setInterval(fname, 10000);

clearInterval(refreshIntervalId);

คุณทำรหัสถูกต้อง 100% ... ดังนั้น ... ปัญหาคืออะไร หรือมันคือการสอน ...


-3

ทำไมไม่ใช้วิธีที่ง่ายกว่า เพิ่มคลาส!

เพียงเพิ่มคลาสที่บอกช่วงเวลาว่าอย่าทำอะไรเลย ตัวอย่างเช่น: บนโฮเวอร์

var i = 0;
this.setInterval(function() {
  if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
    console.log('Counting...');
    $('#counter').html(i++); //just for explaining and showing
  } else {
    console.log('Stopped counting');
  }
}, 500);

/* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
$('#counter').hover(function() { //mouse enter
    $(this).addClass('pauseInterval');
  },function() { //mouse leave
    $(this).removeClass('pauseInterval');
  }
);

/* Other example */
$('#pauseInterval').click(function() {
  $('#counter').toggleClass('pauseInterval');
});
body {
  background-color: #eee;
  font-family: Calibri, Arial, sans-serif;
}
#counter {
  width: 50%;
  background: #ddd;
  border: 2px solid #009afd;
  border-radius: 5px;
  padding: 5px;
  text-align: center;
  transition: .3s;
  margin: 0 auto;
}
#counter.pauseInterval {
  border-color: red;  
}
<!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p id="counter">&nbsp;</p>
<button id="pauseInterval">Pause</button></p>

ฉันกำลังมองหาวิธีที่ง่ายและรวดเร็วสำหรับทุกเพศทุกวัยดังนั้นฉันโพสต์หลายรุ่นเพื่อแนะนำคนให้มากที่สุดเท่าที่จะทำได้


17
ดูเหมือนจะไม่ง่ายกว่าฉันจริง ๆ ... ฉันคิดว่าการลบช่วงเวลาของคุณออกไปแทนที่จะเป็นเรื่องการโทรไปยังฟังก์ชั่นที่ไม่ทำอะไรเลย
Romain Braun

ฉันไม่เห็นด้วย this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500);คือทั้งหมดที่คุณมีสำหรับรหัส นอกจากนี้การตรวจสอบเป็นสิ่งแรกที่คุณทำดังนั้นจึงมีน้ำหนักเบามากเมื่อมีการโฮเวอร์ นั่นคือสิ่งที่หนึ่งนี้เหมาะสำหรับ: ชั่วคราวหยุดฟังก์ชั่น หากคุณต้องการที่จะยุติมันไปเรื่อย ๆ : แน่นอนว่าคุณลบช่วงเวลา
Aart den Braber

จำนวนนี้เพื่อการสำรวจความคิดเห็นและเป็นกำลังใจโดยทั่วไป มันจะปลุกซีพียูจากสถานะพลังงานต่ำเพียงเพื่อทำการตรวจสอบ (ไร้ประโยชน์) นอกจากนี้ยังชะลอการตอบรับจากทันทีถึงระหว่าง 0 และ 500 ms ในตัวอย่างนี้
Charlie

ฉันไม่เห็นด้วยกับคุณเลยแม้แต่ตอนที่ฉันเขียนรหัสเมื่อ 2 ปีก่อน ตัวนับต้องอยู่ที่นั่นเพราะ OP ขอไป แน่นอนว่าหากคุณใช้วิธีนี้เพื่อหยุดตัวนับหลังจากกดปุ่มตัวอย่างนี้จะเป็นวิธีแก้ปัญหาย่อยที่ดีที่สุด แต่เพียงหยุดชั่วคราวเมื่อเลื่อนเมาส์ไปวางเมาส์นี่เป็นหนึ่งในวิธีการแก้ปัญหาที่ง่ายที่สุด
Aart den Braber
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.