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>


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


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