Как сделать так, чтобы при клике на стрелку вверх или вниз число счетчика менялось, и был активен нужный этаж на чистом js?
Задача следующем: при клике на стрелку вверх или вниз, число счетчика должно или прибавлятся на 1 или уменьшатся, и был активен тот этаж, у которого data атрибут с числом этажа, совпадал с числом в счетчике.
Я реализовал подобный функционал, но только при клике на сам этаж. (число в счетчике меняется в зависимости от этажа на который был произведен клик, и сделал выбраный этаж активным). Как сделать подобное при клике на стрелки вверх/вниз?
Буду очень благодарен за помощь, понятно что на jquery это проще сделать, но хочу понять как делать на чистом js, так как я только начал изучать язык.
Ссылка на проект: https://plupiks.github.io/melody-landing/.
const floors = document.querySelectorAll(".house-floor");
const floorCountNumb = document.querySelector(".hero--value");
const arrowUp = document.querySelector(".hero--arrow-up");
const arrowDown = document.querySelector(".hero--arrow-down");
// При клике на этаж
floors.forEach(e => {
e.addEventListener('click', function (e) {
var floorActive = e.target;
floors.forEach(e => {
e.classList.remove("house-img--active");
})
floorActive.classList.add("house-img--active");
var floorCount = e.target.dataset.floor;
floorCountNumb.textContent = floorCount;
})
})
// При клике на стрелку вверх
arrowUp.addEventListener('click', () => {
})
Ответы (2 шт):
let parths = document.querySelectorAll('.house-floor');
// При клике на стрелку вверх
arrowUp.addEventListener('click', function() => {
let value = parseInt(floorCountNumb.innerHTML);
if (value != parths.lenght) {
parths[value-1].classList.remove('house-img--active');
value++;
floorCountNumb.innerHTML = value;
parths[value-1].classList.add('house-img--active');
}
})
// При клике на стрелку вниз
arrowDown.addEventListener('click', function() => {
let value = parseInt(floorCountNumb.innerHTML);
if (value != 0) {
parths[value-1].classList.remove('house-img--active');
value--;
floorCountNumb.innerHTML = value;
parths[value-1].classList.add('house-img--active');
}
})
p.s. Такой код я называю "огородом", из-за того, что две функции практически одинаковые. Для базового понимания сойдет, но для работы желательно написать 1, универсальную функцию. Вот можете на досуге подумать как из этих двух написать одну (молчаливую) функцию.
В идеале, наверно, написать как-то так. Надеюсь более или менее понятно описал принцип. Раз учитесь языку, учитесь сразу мыслить как программист, а не тупо изучение api языка.
const floors = document.querySelectorAll('.house-floor')
const floorCountNumb = document.querySelector('.hero--value')
const arrowUp = document.querySelector('.hero--arrow-up')
const arrowDown = document.querySelector('.hero--arrow-down')
const ACTIVE_CLASS = 'house-img--active'
let selectedFloor = null
const resetSelectedFloor = () => {
floors.forEach((el) => el.classList.remove(ACTIVE_CLASS))
}
const setActiveFloor = (num) => {
const floor = floors.find((el) => el.dataset.floor === num)
floor.classList.add(ACTIVE_CLASS)
displayFloor(num)
selectedFloor = num
}
const displayFloor = (num) => {
floorCountNumb.textContent = num
}
// При клике на этаж
/**
* Реализация необходимого функционала делаится на две части:
* сброс текущего активного элемента и назначение нового. Логику конечно можно написать в лоб,
* но лучше сразу выделить абстракции и спрятать реализацию за ними. Это позволит мыслить на уровне
* предметной области и не думать о технической части + станет удобно масштабировть или изменять
* текущий код. В вашем случае, тот же функционал выполняют кнопки на странице. Также обратите внимание,
* что я вынес активный этаж в отдельную переменную как состояние, что позволяет достаточно просто
* переиспользовать функции. Без нее вам бы пришлось выцеплять активный этаж из DOM элемента при нажатии кнопок,
* что породило бы как минимум одну дополнительную функцию с лишней абстракцией. Также все строки или числа,
* которые используются по несколько раз, лучше выделять в отдельные переменные.
* В строках можно ошибиться, а с числами иногда не сразу понятно, не зная контекста, что они обозначают.
*/
floors.forEach((el) => {
el.addEventListener('click', (ev) => {
resetSelectedFloor()
const floor = ev.target.dataset.floor
setActiveFloor(floor)
})
})
// При клике на стрелку вверх
arrowUp.addEventListener('click', () => {
resetSelectedFloor()
setActiveFloor(selectedFloor + 1)
})
arrowDown.addEventListener('click', () => {
resetSelectedFloor()
setActiveFloor(selectedFloor - 1)
})