Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 11.04.2018, 12:46
Интересующийся
Отправить личное сообщение для goofy1337 Посмотреть профиль Найти все сообщения от goofy1337
 
Регистрация: 11.04.2018
Сообщений: 10

Таймер обратного отсчета
Привет всем. Мне нужно сделать таймер обратного отсчета именно на классах в JS. Я написал код, но есть проблема, по нажатию кнопки старт таймер по просту не идет. Думаю ошибка в вызове функции t(), в setInterval (но это не точно). В поле input надо вписывать минуты, но вторая проблема: переменная m не принимает значения input. Буду благодарен за помощь

class Timer {
    constructor(){
        this.m = +document.getElementById("minutes").value;
        this.s = 0;
        this.status = 0; 
        this.timerId;
    }
    
    t(){
        this.s--;
        
        if(this.s < 0) {
            this.s = 59;
            this.m--;
        }
        
        if(this.m < 0) {
            this.m = 59;
        } 
        
        if(this.s + this.m == 0) resetTimer();  
        
        this.s = this.s + "";
        this.m = this.m + "";
        
        if (this.s.length < 2) {
            this.s = "0" + this.s;
        }
        
        if (this.m.length < 2) {
            this.m = "0" + this.m;
        }
        
        document.getElementById('tm').innerHTML = this.m + ":" + this.s; 
    }    
       
    resetTimer(){             
            clearInterval(this.timerId);
            
            document.getElementById('tm').innerHTML = '00' + ':' + '00';
            document.getElementById("minutes").value = "";
            document.getElementById("minutes").removeAttribute("disabled","");
            
            this.status = 0;
        }
        
    check() {
        if( this.s + this.m == 0){
            this.s = 0;
            this.m = 0;
        }
        
        this.timerId = setInterval(this.t(), 1000);
    } 
        
    start(){   
        document.getElementById("minutes").setAttribute("disabled","");
          
        if(!this.status){
            this.status = 1;
            this.check();
        }
    }
}
 
var timer = new Timer();


Вот код HTML

<!DOCTYPE html>
<html>
    <head>
        <title>Timer</title>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="newcss.css"> 
        <link rel="shortcut icon" href="#">
    </head>
    <body>
         
            <div id="tm">00:00</div>
            <label>Write minutes</label><br>
            <input type="number" id="minutes">
            <script type="text/javascript" src="newjavascript.js"></script>
            <input type="button" value="Start" onclick="timer.start()">
            <input type="button" value="Reset"  onclick="timer.resetTimer()">
            
    </body>
</html>
Ответить с цитированием
  #2 (permalink)  
Старый 11.04.2018, 13:00
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,723

Странный у вас таймер, имхо.
По-моему класс Timer не должен взаимодействовать с dom, если его основной задачей является countdown.
Оставшееся время лучше хранить в (мили)секундах.

class Timer {
    __startValue;
    __currentValue;
    __state = false;

    constructor(seconds) {
        this.__startValue = this.__currentValue = seconds;
    }

    __countdown() {
        if (!this.__state)
            return this;

        this.__currentValue--;

        setTimeout(this.__countdown.bind(this), 1000);

        return this;
    }

    start() {
        this.__state = true;
        this.__countdown();

        return this;
    }

    stop() {
        this.__state = false;

        return this;
    }

    reset() {
        this.__currentValue = this.__startValue;

        return this;
    }

    getSeconds() {
        return this.__currentValue;
    }
}
Ответить с цитированием
  #3 (permalink)  
Старый 11.04.2018, 13:08
Интересующийся
Отправить личное сообщение для goofy1337 Посмотреть профиль Найти все сообщения от goofy1337
 
Регистрация: 11.04.2018
Сообщений: 10

Спасибо за пример кода, написал setInterval через bind, начал работать отсчет. Теперь осталось что-то решить со стартовым значением.

setTimeout(this.__countdown.bind(this), 1000);
Ответить с цитированием
  #4 (permalink)  
Старый 11.04.2018, 13:49
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,723

goofy1337, setInterval лучше заменить на setTimeout.
<div>Минуты: <span id="minutes">10</span></div>
<div>Секунды: <span id="seconds">00</span></div>
<button id="start">Start</button>
<script>
	class Timer {
			constructor(seconds) {
					this.__startValue = 0;
					this.__currentValue;
					this.__state = false;
					this.__listeners = {
							count: []
					};


					this.__startValue = this.__currentValue = seconds;
			}

			__countdown() {
					if (!this.__state || !this.__currentValue)
							return this;

					this.__currentValue--;
					this.__trigger('count');

					setTimeout(this.__countdown.bind(this), 1000);

					return this;
			}

			start() {
					this.__state = true;
					this.__countdown();

					return this;
			}

			stop() {
					this.__state = false;

					return this;
			}

			reset() {
					this.__currentValue = this.__startValue;

					return this;
			}

			getSeconds() {
					return this.__currentValue;
			}

			onCount(callback) {
					this.__listeners.count.push(callback);

					return this;
			}

			__trigger(event) {
					if (!this.__listeners[event])
							return;

					var timer = this,
							list = this.__listeners[event];

					list.filter(function(callback, i) {
							try {
									callback(timer);

									return true;
							} catch (e) {
									return false;
							}
					});

					this.__listeners[event] = list;

					return this;
			}
	}


	var timer;
	start.onclick = () => {
			if (!!timer)
					return;

			timer = (new Timer(
				+minutes.textContent.trim()*60 + +seconds.textContent.trim()
			)).start().onCount($timer => {
					let sec = $timer.getSeconds(),
							min = Math.floor(sec / 60);

					sec = sec - min * 60;

					minutes.textContent = min;
					seconds.textContent = sec;
			});
	};
</script>
Ответить с цитированием
  #5 (permalink)  
Старый 11.04.2018, 15:57
Интересующийся
Отправить личное сообщение для goofy1337 Посмотреть профиль Найти все сообщения от goofy1337
 
Регистрация: 11.04.2018
Сообщений: 10

Спасибо всем за помощь, получилось исправить ошибки, и теперь все работает
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Таймер обратного отсчета. Davias Events/DOM/Window 10 31.05.2017 03:01
Индивидуальный таймер обратного отсчета времени с редиректом pozitiv4ek Работа 2 11.12.2016 13:42
Таймер обратного отсчета Kity Элементы интерфейса 1 30.07.2016 11:56
Зацикленный таймер обратного отсчета levshaszr Элементы интерфейса 7 12.10.2014 23:20
Таймер обратного отсчета UNIX time TuxShot Общие вопросы Javascript 6 03.08.2014 13:36