AndreySmi
@AndreySmi
Beginner Frontend Developer

Как сделать разный счетчик для каждого блока?

Здравствуйте, в продолжении темы Как сделать вывод цикла в оба блока?

Есть JS-функция, отвечающая за вывод счетчика:
function showCounter(wrapper, block){

	// берем текущую дату
	var now = new Date();
	// берем дату с атрибута html
	var cel = new Date(date);
	// вычисляем промежуток до праздника
	var distance = cel - now;
	// создаем переменную с обратным отсчетом - тип "Объект"
	var counter_data = {
		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)
	}

	// делаем видимой переменную блок с предыдущей функции для вставки счетчика
	var block = wrapper;


	// условия для чисел меньше 10
	if(counter_data.days < 10){counter_data.days = "0"+counter_data.days}
	if(counter_data.hours < 10){counter_data.hours = "0"+counter_data.hours}
	if(counter_data.mins < 10){counter_data.mins = "0"+counter_data.mins}
	if(counter_data.secs < 10){counter_data.secs = "0"+counter_data.secs} 

	// если промежуток отрицательный - убираем счетчик
	if(distance < 0){
		wrapper.style.display = "none";
		// остановка счетчика
		clearInterval(timer);
	}
	// изменяем счетчик каждую секунду
	block.innerHTML = '\
		<span id="days">'+counter_data.days+'</span>\
		<span id="hours">'+counter_data.hours+'</span>\
		<span id="mins">'+counter_data.mins+'</span>\
		<span id="secs">'+counter_data.secs+'</span>\
	'; 
	
	console.log(distance);
	console.log(counter_data.days);
	console.log(counter_data.hours);
	console.log(counter_data.mins);
	console.log(counter_data.secs);
}


Есть HTML:
<div class="counter" data-event="kuzbass" data-background="300_years" data-day="3/14/2019"></div>
	<div class="counter" data-event="new_year" data-background="gold" data-day="1/1/2019"></div>
	<script src="js/counter-all.js"></script>


И весь код JS тут:
;
// возьмем все наши блоки для встраивания счетчика - тип "объект"
var script = document.getElementsByClassName("counter");

// создаем функцию для обертки счетчика
function bg_count(name, theme){
	// создадим в каждом блоке основу для обертки счетчика - тип "Объект"
	var wrapper = document.createElement("div");
		wrapper.className = "counter_block";
	// создадим в каждой обертке блок для самого счетчика - тип "Объект"
	var block = wrapper;
		block.innerHTML = "<div class='counter_block-counter'></div>";
	// берем этот блок  себе для последующих операций с ним  - тип "Объект"
	block = block.getElementsByClassName("counter_block-counter")[0];
	// вызываем функцию счетчик
	var timer = setInterval(showCounter.bind(wrapper, block), 1000);
	// создаем функцию появления мыши на блоке счетчика
	function mouseOver(){
		wrapper.style.backgroundPosition = "top";
		block.style.display = "none";
	}
	// создаем функцию ухода мыши с блока счетчика
	function mouseOut(){
		wrapper.style.backgroundPosition = "bottom";
		block.style.display = "block";
	}
	// создание объекта со всеми шаблонами счетчиков
	var celebrations = {
		'new_year': {
			"gold": 'gold',
			"blue": 'photo2',
			"yellow": 'photo3'
		},
		'victory':{
			"red": 'photo_v1',
			"green": 'photo_v2',
			"blue": 'photo_v3'
		},
		'first_may':{
			"white": 'photo_m1',
			"cyan": 'photo_m2',
			"red": 'photo_m3'
		},
		'kuzbass':{
			"300_years": "300_years"
		}
	};
	// проверяем заданы ли параметры и выясняем название фотки
	if(name){
		var photo = celebrations[name];
		if(theme){
			photo = photo[theme];
		}
	}

	// стилизуем блок счетчика
	if(name == 'kuzbass'){
		var wrapperCssText = 'width:300px;height:150px;margin-top:15px;position:relative;background:url(./img/'+name+'/'+photo+'.jpg);background-position:bottom;background-size:cover;background-repeat:no-repeat;';
		wrapper.style.cssText = wrapperCssText;
		wrapper.addEventListener("mouseover", mouseOver); 
		wrapper.addEventListener("mouseout", mouseOut);
		// разукрашивание счетчика
		var counterCssText = 'position:absolute;bottom:18%;font-size:32px;text-align:center;color:white;left:0;right:0;background-color:rgba(156,156,156,0.2);';
		block.style.cssText = counterCssText;
	}

	else if(name == 'new_year'){
		var wrapperCssText = 'width:160px;height:206px;margin-top:15px;position:relative;background:url(./img/'+name+'/'+photo+'.jpg);background-position:bottom;background-size:cover;background-repeat:no-repeat;';
		wrapper.style.cssText = wrapperCssText;
		wrapper.addEventListener("mouseover", mouseOver); 
		wrapper.addEventListener("mouseout", mouseOut);
		// разукрашивание счетчика
		var counterCssText = 'position:absolute;bottom:25.7%;font-size:25px;text-align:center;color:white;left:0;right:1px;background-color:rgba(156,156,156,0.2);letter-spacing:1px;';
		block.style.cssText = counterCssText;
	}
	// прерываем функцию и возвращаем обертку счетчика
	return wrapper;
}	

// создаем функцию-обработчик, отвечающая за работу счетчика
function showCounter(wrapper, block){

	// берем текущую дату
	var now = new Date();
	// берем дату с атрибута html
	var cel = new Date(date);
	// вычисляем промежуток до праздника
	var distance = cel - now;
	// создаем переменную с обратным отсчетом - тип "Объект"
	var counter_data = {
		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)
	}

	// делаем видимой переменную блок с предыдущей функции для вставки счетчика
	var block = wrapper;


	// условия для чисел меньше 10
	if(counter_data.days < 10){counter_data.days = "0"+counter_data.days}
	if(counter_data.hours < 10){counter_data.hours = "0"+counter_data.hours}
	if(counter_data.mins < 10){counter_data.mins = "0"+counter_data.mins}
	if(counter_data.secs < 10){counter_data.secs = "0"+counter_data.secs} 

	// если промежуток отрицательный - убираем счетчик
	if(distance < 0){
		wrapper.style.display = "none";
		// остановка счетчика
		clearInterval(timer);
	}
	// изменяем счетчик каждую секунду
	block.innerHTML = '\
		<span id="days">'+counter_data.days+'</span>\
		<span id="hours">'+counter_data.hours+'</span>\
		<span id="mins">'+counter_data.mins+'</span>\
		<span id="secs">'+counter_data.secs+'</span>\
	'; 
	
	console.log(distance);
	console.log(counter_data.days);
	console.log(counter_data.hours);
	console.log(counter_data.mins);
	console.log(counter_data.secs);
}

for(var c=0;c<script.length;c++){
	// возьмем у каждого счетчика значения data-атрибутов - тип "string"x2 и "object"
	var bg = script[c].dataset.background;
	var event = script[c].dataset.event;
	var date = new Date(script[c].dataset.day);

	console.log(c);
	console.log(event);
	console.log(bg);
	console.log(script[c]);

	
	// встроим счетчик в каждый свой блок
	script[c].appendChild(bg_count(event, bg));
}


Возник вопрос:
Из-за чего в обоих блоках один и тот же счетчик и что нужно, чтобы он отображался по-разному для каждого блока?
  • Вопрос задан
  • 273 просмотра
Решения вопроса 1
функциям добавить параметр date
script[c].appendChild(bg_count(event, bg, date)
function showCounter(wrapper, block, date){};
function bg_count(name, theme, date)


внутрь функции bg_count добавить
date = new Date(date).getTime();
// а в вызове showCounter подшаманить с bind
setInterval(showCounter.bind(this,wrapper, block, date), 1000);
// тоже самое без bind
setInterval(() => showCounter(wrapper, block, date), 1000);


в showCounter() удалить var block = wrapper;
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
avaddonval
@avaddonval
большой код у тебя) но суть вопроса описана здесь.

https://learn.javascript.ru/closures
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
SummerWeb Ярославль
от 120 000 до 180 000 ₽
КРАФТТЕК Санкт-Петербург
от 60 000 до 80 000 ₽
Brightdata Тель-Авив
от 5 500 до 6 500 $