Необходима помощь в отладке функции js

224
10 февраля 2017, 05:49

Есть метод:

Menu.prototype.init = function () {
        var self = this;
        function sliding(item, step) {
            var i = 0;
            var imgs = Array.prototype.slice.apply(item.querySelectorAll('img'));
            var len = imgs.length;
            function next() {
                imgs[i].style.opacity = 0;
                if(i == len - 1) {
                    imgs[0].style.opacity = 1;
                } else {
                    imgs[i+1].style.opacity = 1;
                }
               i++;
               if(i == len) {
                   i = 0;
               }
                console.log(i);
            }
            setInterval(next, step);
        }
        function start(items, step) {
            for(var i = 0; i < items.length; i++) {
                step += 200;
                (function(i, step) {
                    sliding(items[i], step);
                })(i, step);
            }
        }
        start(this.items, 3000);
    }    

Метод работает но не так как задумывалось, я так понимаю дело в таймерах.. Задумка была, что бы картинки менялись последовательно и при первом запуске так и происходит... но дальше они начинают меняться хаотично. Подскажите направление поиска решения? Посмотреть работу скрипта можно здесь

Answer 1

Используйте для это setTimeout вместо интервала. Просто потому, что при setInterval будет запускаться след. функция, даже если прошлая не успела закончиться, вот в этом вся и проблема. В вашем коде вы не очищаете "таймер". Вы должны его очищать, чтоб была хоть какая-та последовательность.
Вот мой пример, только с рекурсивным setTimeout.
В этой статье сказано почему setTimeout > setInterval

const imgs = Array.from(document.querySelectorAll('img')); 
let currentTimer; 
 
function carusel(arr) { 
  const [head, ...last] = arr; 
  if (!head) { 
    console.log('элементы закончились, очищаю стили и запускаю по новой.'); 
    imgs.forEach(el => { 
      el.removeAttribute('style'); 
    }); 
    currentTimer = setTimeout(function() { 
      carusel(imgs); 
    }, 200); 
  } else { 
    head.style.opacity = 1; 
 
    currentTimer = setTimeout(function() { 
      carusel(last); 
    }, 200); 
  } 
} 
 
document.querySelector('.start').onclick = function() { 
  carusel(imgs); 
} 
 
document.querySelector('.stop').onclick = function() { 
  clearTimeout(currentTimer); 
}
img { 
  opacity: 0; 
  transition: 0.3s; 
}
<button class='start'>start</button> 
<button class='stop'>stop</button> 
<div> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
  <img src="https://dummyimage.com/100x100/000/fff" alt=""> 
</div>

READ ALSO
&#39;-&#39; в регулярных выражениях

'-' в регулярных выражениях

Здравствуйте, пытаюсь проверить число, например -42, вроде как, в alert должно быть написано только это число, но пишется -42,-Как сделать так чтоб...

312
JSON.parse получаю ошибку Unexpected token o in JSON

JSON.parse получаю ошибку Unexpected token o in JSON

Пытаюсь вернуть через REST API данные в JSON

462
Сделать горизонтальную прокрутку в fotorama

Сделать горизонтальную прокрутку в fotorama

ЗдравствуйтеИспользую плагин fotorama

280
Отображение пользователей в FullCalendar

Отображение пользователей в FullCalendar

Пытаюсь кастомизировать календарь в такой как на скрине:

249