Как сделать счетчик через ООП?

Здравствуйте, делаю счетчик событий, так сказать улучшаю, но то ли не могу сообразить то ли еще хуже, я не могу понять как его переписать на ООП, всё что я смог, получилось вот:

https://pastebin.com/ap3icrqc

Есть вполне себе рабочий код:
;
// берем все счетчики с сайта
var counter = document.querySelectorAll(".counter");
// если счетчик имеется берем переменные и работаем с ними
if(counter){
    // берем у всех счетчиков их значения
    for(var c=0;c<counter.length;c++){
        if(counter[c].dataset.event){
            var counter_event = counter[c].dataset.event;
            counter_event = counter_event.replace(/\s/g, "");
        }
        if(counter[c].dataset.background){
            var counter_theme = counter[c].dataset.background;
            counter_theme = counter_theme.replace(/\s/g, "");
            // приравниваем старые значения счетчика к новым
            switch(counter_theme){
                case "dark300":
                    counter_theme = "dark";
                    break;
                case "light300":
                    counter_theme = "light";
                    break;
                default:
                    break;
            }
        }
        else if(counter[c].dataset.theme){
            var counter_theme = counter[c].dataset.theme;
            counter_theme = counter_theme.replace(/\s/g, "");
        }
        if(counter[c].dataset.day){
            var counter_date = counter[c].dataset.day;
            counter_date = counter_date.replace(/\s/g, "");
        }
        else if(counter[c].dataset.date){
            var counter_date = counter[c].dataset.date;
            counter_date = counter_date.replace(/\s/g, "");
        }
        if(counter[c].dataset.link){
            var counter_link = counter[c].dataset.link;
            counter_link = counter_link.replace("/\s/g", "");
        }
        // вызываем метод создания счетчика для каждого элемента
        counter[c].appendChild(makeCounter(counter_theme, counter_event, counter_date, counter_link));
    }
    // метод создания шаблона счетчика
    function makeCounter(theme, event, date, link){
        // создаем основную обертку и обертку для самого счетчика
        var block = document.createElement("div");
        if(block){
            // создаем переменную для пути к стилевому файлу счетчика
            var styles = document.createElement("link");
            if(styles){
                styles.href = "j/css/counter/"+event+"/"+theme+".css";
                styles.rel = "stylesheet";
                // добавляем подключение стилей счетчика в head
                document.querySelectorAll("head")[0].appendChild(styles);
            }
            block.className = event+"-"+theme+" template";
            var timer_if = new Date(date.replace(/(\d+).(\d+).(\d+)/, '$3/$2/$1')) - new Date();
            if (timer_if <= 0){
                block.className = event+"-"+theme+" template zero";
            }
            else{
                var wrap = document.createElement("div");
                if(wrap){
                    wrap.className = "counter-wrap";
                    // создаем структуру счетчика
                    block.appendChild(wrap);
                }
                // добавляем ссылку на счетчик, если она у нас указана в нем
                if(link){
                    var linker = document.createElement("a");
                    linker.className = "counter-link";
                    linker.href = link;
                    linker.target = "_blank";
                    block.appendChild(linker);
                }
                // переменная для условия, при котором у нас счетчик приходит в 0
                var resetCount={
                    obj:null
                };
                // вызываем функцию создания обратного отсчета
                var timer = setInterval(makeCount.bind(this, wrap, date, resetCount), 1000);
                // стоп точка, чтобы дальше 0 не отсчитывать
                resetCount.obj = timer;
            }
        }
        // генерируем счетчик
        return block;
    }
    // создаем функцию генерации обратного отсчета
    function makeCount(layout, timecount, reset){
        // берем дату и преобразуем ее в нужный для работы с ней формат
        var now = new Date();
        var event_date = new Date(timecount.replace(/(\d+).(\d+).(\d+)/, '$3/$2/$1'));
        // вычисляем разницу от даты события до сегодня
        var distance = event_date - now;
        // вычисляем сколько дней, часов, минут и секунд осталось до события
        var counter_time =
            {
                days:Math.floor(distance / (1000 * 60 * 60 * 24)),
                hours:Math.floor(distance % (1000 * 60 * 60 * 24) / (1000 * 60 * 60)),
                mins:Math.floor(distance % (1000 * 60 * 60) / (1000 * 60)),
                secs:Math.floor(distance % (1000 * 60) / 1000)
            };
        // если дни, часы, минуты, секунды меньше 10, то мы спереди для них добавляем 0, вместо "9" например должно быть "09"
        for(var i in counter_time){
            if(counter_time[i] < 10){
                counter_time[i] = "0" + counter_time[i];
            }

        };
        // если мы достигаем по счетчику 0:00:00, то скрываем и сбрасываем отсчет
        if(distance <= 0){
            layout.style.display = "none";
            if(reset.obj!==null){
                clearInterval(reset.obj);
            }
        }
        // вставляем время в счетчик
        layout.innerHTML =
            '<div id="days" class="inline"> '+counter_time.days+' <span>:</span> </div><div id="hours" class="inline">'+counter_time.hours+' <span>:</span> </div><div id="mins" class="inline">'+counter_time.mins+' <span>:</span> </div><div id="secs" class="inline">'+counter_time.secs+'</div>';
    }
}


Но хоть ты тресни не могу переписать на ООП, а очень хочется.

Проблема у меня возникает очень глупая, а именно как сделать инкремент?

В рабочем примере я это реализовал через две функции - в одной вызываю и инкрементирую вторую.

Но дело в том, что есть условие:
if(distance <= 0){
    // показывать один код
}
else{
    // показывать другой код
}


И в функции, которую я инкрементирую, та же самая переменная снова объявляется.

Вопрос: можно ли как-то избежать повтора? И как без повтора реализовать ООП подход?

Буду благодарен за любую помощь!
  • Вопрос задан
  • 482 просмотра
Решения вопроса 1
And__Smi
@And__Smi Автор вопроса
Благодаря одному пользователю данного сайта, который удалил свой ответ, видимо (не знаю зачем, а потом еще говорят, гугли, когда люди чистят за собой), я привел свой код к такому решению и это еще не окончательное, в планах создать еще два метода - для counter_time и для layout.innerHTML. Пока не соображу как, вот решение, которое меня устроило, но не до конца, о чем я упомянул выше:
;
var counterList = document.querySelectorAll(".counter");
function myCounter(counterEl){
    this.counter = counterEl;
    this.init = function(){
        var counter_event;
        var counter_theme;
        var counter_date;
        var counter_link;

        if(this.counter.hasAttribute("data-event")){
            counter_event = this.counter.getAttribute("data-event").replace(/\s/g, '');
        }
        if(this.counter.hasAttribute("data-theme")){
            counter_theme = this.counter.getAttribute("data-theme").replace(/\s/g, '');
        }
        else if(this.counter.hasAttribute("data-background")){
            counter_theme = this.counter.getAttribute("data-background").replace(/\s/g, '');
        }
        if(this.counter.hasAttribute("data-date")){
            counter_date = this.counter.getAttribute("data-date").replace(/\s/g, '');
        }
        else if(this.counter.hasAttribute("data-day")){
            counter_date = this.counter.getAttribute("data-day").replace(/\s/g, '');
        }
        if(this.counter.hasAttribute("data-link")){
            counter_link = this.counter.getAttribute("data-link").replace(/\s/g, '');
        }

        var counterChild = this.makeCounter(counter_event, counter_theme, counter_date, counter_link);
        this.counter.appendChild(counterChild);
    };
    this.makeCounter = function(theme, event, day, link){
        var block = document.createElement("div");
        var styles = document.createElement("link");

        if(styles){
            styles.href="j/css/counter"+ "/" + theme + "/" + event + ".css";
            styles.rel = "stylesheet";

            document.querySelectorAll("head")[0].appendChild(styles);
        }

        if(block){
            block.className = theme + "-" + event + " template";

            var timerIf = new Date(day.replace(/(\d+).(\d+).(\d+)/, '$3/$2/$1')) - new Date();
            if(timerIf <= 0){
                block.className += " zero";
            }
            else{
                var wrap = document.createElement("div");
                if(wrap){
                    wrap.className = "counter-wrap";

                    block.appendChild(wrap);
                }
            }

            if(link){
                var linker = document.createElement("a");
                if(linker){
                    linker.className = "counter-link";
                    linker.href=link;
                    linker.target="_blank";

                    block.appendChild(linker);
                }
            }

            var resetCount = {
                obj: null
            };

            var timer = setInterval(this.makeCount.bind(this, wrap, day, resetCount), 1000);

            resetCount.obj = timer;
        }

        return block;
    };
    this.makeCount = function(layout, timecount, reset){
        var now = new Date();
        var eventDate = new Date(timecount.replace(/(\d+).(\d+).(\d+)/, '$3/$2/$1'));
        var distance = eventDate - now;

        var counterTime = {
            days: Math.floor(distance / (1000 * 60 * 60 * 24)),
            hours: Math.floor(distance % (1000 * 60 * 60 * 24) / (1000 * 60 * 60)),
            mins: Math.floor(distance % (1000 * 60 * 60) / (1000 * 60)),
            secs: Math.floor(distance % (1000 * 60) / 1000)
        };

        for(var i in counterTime){
            if(counterTime[i] < 10){
                counterTime[i] = "0" + counterTime[i];
            }
        }

        if(distance <= 0){
            if(reset.obj !== null){
                clearInterval(reset.obj);
            }
        }
        else{
            layout.innerHTML = '<div id="days" class="inline">'+counterTime.days+'<span>:</span></div>';
            layout.innerHTML += '<div id="hours" class="inline">'+counterTime.hours+'<span>:</span></div>';
            layout.innerHTML += '<div id="mins" class="inline">'+counterTime.mins+'<span>:</span></div>';
            layout.innerHTML += '<div id="secs" class="inline">'+counterTime.secs+'</div>';
        }
    };
}

for(var c = 0; c<counterList.length; c++){
    var counter = new myCounter(counterList[c]);
    counter.init();
}


Если есть у кого что сказать по коду, как можно было бы оформить еще лучше, я не против послушать и пообщаться на данную тематику. Сразу оговорюсь заранее (я до этого не сказал), код пишется исключительно под ие8+ и никак иначе. Все новомодные штучки, к сожалению, приходится избегать, включая const, let, class.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Admitad Projects Москва
от 130 000 до 200 000 ₽
Fundraise Up Санкт-Петербург
от 2 500 до 3 500 $
26 мая 2020, в 02:01
4500 руб./за проект
26 мая 2020, в 00:42
10000 руб./за проект
25 мая 2020, в 22:16
3000 руб./за проект