#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; }Но как видно в примере, все работает не так хотелось бы. Догадываюсь, что в условии еще и надо проверить, если countRun() запущен и не запускать его больше, ну или что-то другое о чем я не догадываюсь...0
0
Ответы
Ответ 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; }Вариации на тему: 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
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; Теперь мы знаем что интервал не запущен.
Комментариев нет:
Отправить комментарий