Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Как проверить, если запущенна ли функция?

#javascript


Господа, есть функция window.onscroll она запускается и если документ проскролен
больше 200px то она запускает countRun() , а если меньше то 
countStop()



var p1 = document.querySelector('.p1');
var p2 = document.querySelector('.p2');
var wrapper = document.getElementById('wrapper');
var count = 0;
var run;
window.onscroll = function() {
  var scrolled = window.pageYOffset || document.documentElement.scrollTop;
  p1.innerHTML = scrolled;
  if (scrolled > 200) {
    countRun();
  } else {
    countStop();
  }
}

function countRun() {
  run = setInterval(function() {
    p2.innerHTML = count++;
  }, 1000)
}

function countStop() {
  count = 0;
  clearInterval(run);
}
* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  background: #272727;
  perspective: 100px;
  color: white;
}

#wrapper {
  position: relative;
  width: 100%;
  height: 300%;
}

.p1 {
  position: sticky;
  width: 100px;
  height: 50px;
  left: 25px;
  top: 25px;
  background: rgba(0, 0, 0, .3);
  color: white;
  font-size: 20px;
  text-align: center;
  line-height: 2;
  transition: all .5s;
}

.p2 {
  position: sticky;
  width: 100px;
  height: 50px;
  left: 25px;
  top: 70px;
  background: rgba(0, 0, 0, .3);
  color: white;
  font-size: 20px;
  text-align: center;
  line-height: 2;
  transition: all .5s;
}

0

0

Но как видно в примере, все работает не так хотелось бы. Догадываюсь, что в условии еще и надо проверить, если countRun() запущен и не запускать его больше, ну или что-то другое о чем я не догадываюсь...


Ответы

Ответ 1



Проверить "запущена ли функция" невозможно. Можно проверить, "была ли запущена функция". Для этого функция сама должна себя где-то регистрировать. В вашем случае, есть несколько решений. Первое, в лоб - нужно просто сбрасывать интервал, если счётчик уже был запущен. Второе, что почти то же самое, обнулять переменную run, и по ней определять, "была ли запущена функция". var p1 = document.querySelector('.p1'); var p2 = document.querySelector('.p2'); var wrapper = document.getElementById('wrapper'); var count = 0; var run; window.onscroll = function() { var scrolled = window.pageYOffset || document.documentElement.scrollTop; p1.innerHTML = scrolled; if (scrolled > 200) { countRun(); } else { countStop(); } } function countRun() { if (run) return; // или // if (run) clearInterval(run); run = setInterval(function() { p2.innerHTML = count++; }, 1000) } function countStop() { count = 0; clearInterval(run); run = false; } * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; background: #272727; perspective: 100px; color: white; } #wrapper { position: relative; width: 100%; height: 300%; } .p1 { position: sticky; width: 100px; height: 50px; left: 25px; top: 25px; background: rgba(0, 0, 0, .3); color: white; font-size: 20px; text-align: center; line-height: 2; transition: all .5s; } .p2 { position: sticky; width: 100px; height: 50px; left: 25px; top: 70px; background: rgba(0, 0, 0, .3); color: white; font-size: 20px; text-align: center; line-height: 2; transition: all .5s; }

0

0

Вариации на тему: var p1 = document.querySelector('.p1'); var p2 = document.querySelector('.p2'); var wrapper = document.getElementById('wrapper'); class Counter { constructor(el, period = 1000) { this._el = el; this._period = period; this._run = false; this.clear(); } clear() { this._el.innerText = this.counter = 0; } inc() { this._el.innerText = ++this.counter; } start() { if (this._run) return false; this._run = setInterval(() => this.inc(), this._period); } stop() { if (this._run) clearInterval(this._run); this._run = false; this.clear(); } } let counter = new Counter(p2, 500); window.onscroll = function() { let scrolled = window.pageYOffset || document.documentElement.scrollTop; p1.innerText = scrolled; if (scrolled > 200) { counter.start(); } else { counter.stop(); } } * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; background: #272727; perspective: 100px; color: white; } #wrapper { position: relative; width: 100%; height: 300%; } .sticky { position: sticky; background: rgba(0, 0, 0, .3); color: white; font-size: 20px; text-align: center; line-height: 2; transition: all .5s; width: 100px; height: 50px; } .p1 { left: 25px; top: 25px; } .p2 { left: 25px; top: 70px; }

0

0



Ответ 2



По идее да, нужно добавить условие (работает, вроде бы, как нужно): var isRun = false; window.onscroll = function() { var scrolled = window.pageYOffset || document.documentElement.scrollTop; p1.innerHTML = scrolled; if (scrolled > 200) { if(!isRun) { countRun(); isRun = true; } } else { if(isRun){ countStop(); isRun = false; } } }

Ответ 3



Это большой комментарий для наглядности У вас на самом деле не один таймер создается, а целая куча. Добавил в ваш пример вывод номеров таймеров. Причина в том, что onscroll выполняется много раз с в течение прокрутки. Можно, например, складывать номера таймеров в массив и массово зачищать интервал, либо проверять есть ли уже таймер (и делать clearInterval для него) перед созданием нового. var p1 = document.querySelector('.p1'); var p2 = document.querySelector('.p2'); var p3 = document.querySelector('.x1'); var wrapper = document.getElementById('wrapper'); var count = 0; var run; window.onscroll = function() { var scrolled = window.pageYOffset || document.documentElement.scrollTop; p1.innerHTML = scrolled; if (scrolled > 200) { countRun(); } else { countStop(); } } function countRun() { run = setInterval(function() { p2.innerHTML = count++; }, 1000); p3.innerHTML += ', ' + run; } function countStop() { count = 0; clearInterval(run); } * { margin: 0; padding: 0; } html, body { width: 100%; height: 100%; background: #272727; perspective: 100px; color: white; } #wrapper { position: relative; width: 100%; height: 300%; } .p1, .p2, .p3 { position: sticky; width: 200px; height: 50px; left: 25px; top: 25px; background: rgba(0, 0, 0, .3); color: white; font-size: 20px; text-align: center; line-height: 2; transition: all .5s; } .p2 { top: 70px; } .p3 { top: 120px; }

0

0

Timer IDs:



Ответ 4



Краткий ответ: нет. Но в этом и нет необходимости из-за спецификации языка. JavaScript синхронный язык (не путать с асинхронным программированием). В один конкретный момент времени - выполняется одна конкретная функция. Соответственно проверять запущенная ли функция невозможно, она либо еще не запущена, либо уже выполнена. Лучшее решение данной проблемы на мой взгляд var run; При инициализации run undefined Затем, когда мы инициализируем интервал, run передается его id. run = setInterval(function(){console.log('text')}, 1000); Сейчас run равно например 28 Соответственно мы можем проверить и тот факт что функция выполнилась и тот факт что сейчас у нас запущен интервал. Например так: if (run) {}; При очистке интервала необходимо снова сбросить run в undefined, clearInterval не сделает этого автоматически clearInterval(run); run = undefined; Теперь мы знаем что интервал не запущен.

Комментариев нет:

Отправить комментарий