Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Помогите пожалуйста останавливать interval и запускать заново (https://javascript.ru/forum/misc/43587-pomogite-pozhalujjsta-ostanavlivat-interval-i-zapuskat-zanovo.html)

Faab 12.12.2013 15:07

Помогите пожалуйста останавливать interval и запускать заново
 
Нужно останавливать счётчик и запускать заново. Уже по разному пробывал - никак. Вот создал простой скрипт для освоения этой темы:

<!DOCTYPE>
<html>
<head>
  <meta charset="UTF-8">
  <title>Interval</title>
  <style type="text/css">
    span{
     display: inline-block;
     width: 20px; 
     text-align: center;
    }
    .spanAvtive {
      border: 3px red solid;
    }
  </style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
    function fTimerStart(eDiv, iIndexActive){ 
      eSpanSum = eDiv.querySelectorAll('span');
      var fSliderTimer = setInterval(function(){
        eSpanSum[iIndexActive].classList.remove('spanAvtive');
        if(iIndexActive == 9){
          iIndexActive = 0;
        }else{
          iIndexActive++;
        };
        eSpanSum[iIndexActive].classList.add('spanAvtive');
      }, 2000);
      $('.eButtonNext').click(function(){
        clearInterval(fSliderTimer);
        eSpanSum[iIndexActive].classList.remove('spanAvtive');
        if(iIndexActive == 9){
          iIndexActive = 0;
        }else{
          iIndexActive++;
        };
        eSpanSum[iIndexActive].classList.add('spanAvtive');
        fTimerStart(eDiv, iIndexActive);
      });
      
    };
   
    window.onload = function(){
      var iIndexActive = 0;
      var eDiv = document.querySelectorAll('.b-container')[0];
      for(i=0;i<10;i++){
        var eSpan = document.createElement('span');
        if(i==0){
          eSpan.classList.add('spanAvtive');
        };
        var eTextNode = document.createTextNode(i);
        eDiv.appendChild(eSpan);
        eSpan.appendChild(eTextNode);
      };
      fTimerStart(eDiv, iIndexActive);
      
      
    };
  </script>
</head>
<body>

  <div class="b-container"></div>
  <div>
    <input type="button" value="next" class="eButtonNext" />
  </div>
  
</body>
</html>


При втором (или более) событии click идёт сбой - запускаются несколько интервалов. Как решить эту проблему?

animhotep 12.12.2013 15:30

нужно чистить все запущенные, например так
function clearAllTimers(){
  var lastID = 0;

  return function(){
    var currentID = setTimeout(function(){}, 1);
    for(var id = currentID; id > lastID; id--){
      clearTimeout(id);
    };
    lastID = currentID;
  };
}();

danik.js 12.12.2013 15:44

нет, animhotep, так не нужно делать ни в коем случае!

Faab 12.12.2013 15:48

Да, к сожалению я не смог реализовать этот вариант. У меня явные проблемы в функциях и замыканиях, по крайней мере выходит ошибка на строке 45 Uncaught SyntaxError: Unexpected token ) :45:

<!DOCTYPE>
<html>
<head>
  <meta charset="UTF-8">
  <title>Interval</title>
  <style type="text/css">
    span{
     display: inline-block;
     width: 20px; 
     text-align: center;
    }
    .spanAvtive {
      border: 3px red solid;
    }
    .clearfix:after {
    	content: ".";
    	display: block;
    	clear: both;
    	visibility: hidden;
    	line-height: 0;
    	height: 0;
    }     
    .clearfix {
    	display: inline-block;
    }    
    html[xmlns] .clearfix {
    	display: block;
    }    
    * html .clearfix {
    	height: 1%;
    }
  </style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
    function clearAllIntervals(){
      var lastID = 0;
    
      return function(){
        var currentID = setInterval(function(){}, 2000);
        for(var id = currentID; id > lastID; id--){
          clearInterval(id);
        };
        lastID = currentID;
      };
    } /* () */;

    function fTimerStart(eDiv, iIndexActive){ 
      eSpanSum = eDiv.querySelectorAll('span');
      var fSliderTimer = setInterval(function(){
        eSpanSum[iIndexActive].classList.remove('spanAvtive');
        if(iIndexActive == 9){
          iIndexActive = 0;
        }else{
          iIndexActive++;
        };
        eSpanSum[iIndexActive].classList.add('spanAvtive');
      }, 2000);
      $('.eButtonNext').click(function(){
        clearAllIntervals();
        eSpanSum[iIndexActive].classList.remove('spanAvtive');
        if(iIndexActive == 9){
          iIndexActive = 0;
        }else{
          iIndexActive++;
        };
        eSpanSum[iIndexActive].classList.add('spanAvtive');
        fTimerStart(eDiv, iIndexActive);
      });
      
    };
   
    window.onload = function(){
      var iIndexActive = 0;
      var eDiv = document.querySelectorAll('.b-container')[0];
      for(i=0;i<10;i++){
        var eSpan = document.createElement('span');
        if(i==0){
          eSpan.classList.add('spanAvtive');
        };
        var eTextNode = document.createTextNode(i);
        eDiv.appendChild(eSpan);
        eSpan.appendChild(eTextNode);
      };
      fTimerStart(eDiv, iIndexActive);
      
      
    };
  </script>
</head>
<body>

  <div class="b-container"></div>
  <div>
    <input type="button" value="next" class="eButtonNext" />
  </div>
  
</body>
</html>


Закомментировав скобки (я так понимаю они называются замыкание?) основная проблема не решилась.

danik.js 12.12.2013 15:57

Цитата:

Сообщение от Faab
<!DOCTYPE>

Гы, а я то думал что самый короткий доткайп - это <!DOCTYPE html>

А оказывается, некоторым удается еще больше укоротить) Не кинешь ссылку на первоисточник?

Faab 12.12.2013 16:03

Цитата:

Сообщение от danik.js (Сообщение 286225)
Гы, а я то думал что самый короткий доткайп - это <!DOCTYPE html>

А оказывается, некоторым удается еще больше укоротить) Не кинешь ссылку на первоисточник?

Да я скопировал чей-то скрипт, когда решал его.. когда начал делать свой, так и оставил. У меня этим занимается ПМС.. тьфу, опечаточка, ЦМС:
Код:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">


animhotep 12.12.2013 16:16

Цитата:

Сообщение от danik.js
нет, animhotep, так не нужно делать ни в коем случае!

а как ещё можно очередь setTimeout-ов очистить?

Faab 12.12.2013 16:23

А почему тут вообще образуется очередь? При загрузке страницы создаётся таймер, но при следующем клике он же "очищается".. Аль не так?

Что конкретно делает функция clearInterval(): просто останавливает этот таймер, но данные остаются ИЛИ из памяти полностью удаляются все данные этого таймера?

danik.js 12.12.2013 16:24

Цитата:

Сообщение от animhotep
а как ещё можно очередь setTimeout-ов очистить?

Если уж и понадобилось такое, то id'шники надо складывать в массивчик.
Айдишник то может оказаться большим-пребольшим числом. А ведь помимо твоего скрипта, на сайте может использоваться какая-нибудь либа, и она ведь тоже может использовать timeout'ы, а твой скрипт похерит все. Так что низя!

Faab 12.12.2013 16:34

Вот пример из учебника http://learn.javascript.ru/settimeout-setinterval
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <style> div { height: 18px; margin: 1px; background-color:green; } </style>
</head>
<body>

<input type="button" id="start" value="Старт">
<input type="button" id="stop" value="Стоп" disabled>

<script>
for (var i=0; i<=20; i+=2) {
  document.write('<div>'+i+'</div>');
}

var startButton = document.getElementById('start');
var stopButton = document.getElementById('stop');

var timers = [];

stopButton.onclick = function() {
  startButton.disabled = false;
  stopButton.disabled = true;

  for(var i=0; i<timers.length; i++) clearInterval(timers[i]);
  timers = [];
}

startButton.onclick = function() {
  startButton.disabled = true;
  stopButton.disabled = false;

  var divs = document.getElementsByTagName('div');
  for (var i=0; i<divs.length; i++) {
    animateDiv(divs, i);
  }
}

function animateDiv(divs, i) {
  var div = divs[i], speed = div.innerHTML;
  timers[i] = setInterval(function() {
    div.style.width = (parseInt(div.style.width||0) + 2) % 400 + 'px'
  }, speed);
}
</script>

</body>
</html>


Но тут то наглядно видно как образуется массив таймеров. А в моём примере как я могу очистить массив, если я даже не понимаю как образуется этот массив.

Faab 12.12.2013 17:03

console.log(fSliderTimer);


И почему при каждом клике, число число таймеров увеличивается в двое? Таймер же один! И он удаляется с clearInterval() или нет?

Код:

The clearInterval() method clears a timer set with the setInterval() method.

The ID value returned by setInterval() is used as the parameter for the clearInterval() method.


animhotep 12.12.2013 17:06

danik.js,
понятно
Faab,
при каждом запуске ложи id в массив... в примере это timers[i] = setInterval(function() {

рони 12.12.2013 18:10

Faab,
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <title>Interval</title>
  <style type="text/css">
    span{
     display: inline-block;
     width: 20px;
     text-align: center;
    }
    .spanAvtive {
      border: 3px red solid;
    }
  </style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
$(window).load(function () {
    function b() {
        window.clearTimeout(d);
        c[a].removeClass("spanAvtive");
        a = ++a % e;
        c[a].addClass("spanAvtive");
        d = window.setTimeout(b, 2E3)
    }
    var a = 10,
        c = Array(a),
        e = c.length;
    $.each(c, function (a, b) {
        c[a] = $("<span/>", {
            text: a
        }).appendTo(".b-container")
    });
    a--;
    b();
    var d = window.setTimeout(b, 2E3);
    $(".eButtonNext").click(b);
    $(".eButtonStop").click(function () {
        window.clearTimeout(d)
    })
});  </script>
</head>
<body>

  <div class="b-container"></div>
  <div>
    <input type="button" value="next" class="eButtonNext" />
    <input type="button" value="stop" class="eButtonStop" />
  </div>

</body>
</html>

Faab 13.12.2013 16:34

Слушай, пусть это будет воспринято как прямая лесть, но вы ребята пишите шикарно.. смотрю на ваш код и понимаю как коряво я пишу свой код.


При переборе $.each(c, function (a, b) {}) функция b() вызывается или нет?


И первый раз вижу такой способ создания элемента:
$("<span/>", {text: a})

Можно ссылку на мануал, где описывается такой метод... Или такого в мануале не найти?

И вопрос про мой код: получается что моя ошибка была в том, что каждом при клике срабатывала строка 84
fTimerStart(eDiv, iIndexActive);

и строка 67
fTimerStart(eDiv, iIndexActive);



2E3 это просто 739?

danik.js 14.12.2013 03:11

Цитата:

Сообщение от Faab
Можно ссылку на мануал, где описывается такой метод

http://api.jquery.com/jquery/#jQuery-html-attributes

danik.js 14.12.2013 03:13

Цитата:

Сообщение от Faab
2E3 это просто 739?

В консоль вбей и увидишь что это.

ruslan_mart 14.12.2013 08:24

Цитата:

Сообщение от danik.js
2E3 это просто 739?

Это 2000

Faab 14.12.2013 19:10

Рони, спасибо. Только что я смог имплементировать твоё решение. Всё работает без задоринки. Спасибо.


Часовой пояс GMT +3, время: 12:20.