#javascript #html #css
Вопрос:
Я работаю над пользовательским слайдером диапазона для своего веб-сайта. Все работает нормально, но я застрял, чтобы сделать возможным, чтобы при нажатии на определенный ползунок поля(ввод[тип=»диапазон»]) обновлялся в соответствии со значением метки данных этого конкретного div, так что нам не нужно перетаскивать большой палец слайдера, чтобы обновить пользовательскую панель? .Прилагается исходный код, в котором я поделился тем, чего я достиг до сих пор, и тем, что осталось, Для удобства я установил непрозрачность ввода диапазона на 0,1, чтобы вы могли получить представление о том, что происходит в бэкэнде. Любые предложения или помощь будут оценены по достоинству. Спасибо!
const rangeSlider = document.querySelector('#price_slider');
rangeSlider.addEventListener("input", rangeScript);
const customProgress = document.querySelector('#customProgress');
for(let i = 0; i < rangeSlider.max - rangeSlider.min ; i ){
const step = document.createElement('div');
step.classList.add('step');
step.setAttribute('data-label', rangeSlider.min i 1);
customProgress.appendChild(step);
}
customProgress.querySelector(`.step[data-label="${rangeSlider.value}"]`)
.classList.add('current')
function rangeScript(value){
const target = document.getElementById('progress');
let newValue = parseInt(this.value);
const currentStep = customProgress.querySelector(`.step.current`);
if (currentStep) {
currentStep.classList.remove('current');
}
nextStep = customProgress.querySelector(`.step[data-label="${newValue}"]`);
if (nextStep) {
nextStep.classList.add('current')
}
}
#customProgress {
display: flex;
width: 100%;
height: 25px;
background: transparent;
}
.step {
position: relative;
background: yellow;
height: 100%;
width: 100%;
border-right: 1px solid black;
}
.step::after {
content: attr(data-label);
position: absolute;
top: -1em;
right: -.25em;
}
.step ~ .current,
.step.current {
background: blue;
}
<h1>what I have achieved</h1>
<div id="customProgress">
</div>
<div id="progress" style=" width: 100%;" >
<input id="price_slider" type="range" min="4" max="9" value="" style="opacity: 0.1; width: 100%; height: 50px" />
</div>
Ответ №1:
Ключ состоит в том, чтобы добавить прослушиватель событий в step
divs. Он «слышит» щелчок, получает собственное значение из data-label
набора данных, применяет это значение к элементу диапазона, а затем, наконец, запускает обработчик rangeScript
событий. rangeScript
Обработчик необходимо было настроить для работы с event
(e). Прослушиватели событий передают один аргумент в своих функциях, event
и элемент, который вызвал прослушиватель, всегда event.target
является .
step.addEventListener('click', (e) => {
let val = e.target.dataset.label;
document.querySelector('#price_slider').value = val
rangeScript({target: rangeSlider}) // trigger the event using an adhoc representation of the rangeSlider event object
})
const rangeSlider = document.querySelector('#price_slider');
rangeSlider.addEventListener("input", rangeScript);
const customProgress = document.querySelector('#customProgress');
for (let i = 0; i < rangeSlider.max - rangeSlider.min; i ) {
const step = document.createElement('div');
step.classList.add('step');
step.setAttribute('data-label', rangeSlider.min i 1);
step.addEventListener('click', (e) => {
let val = e.target.dataset.label;
document.querySelector('#price_slider').value = val
rangeScript({
target: rangeSlider
})
})
customProgress.appendChild(step);
}
customProgress.querySelector(`.step[data-label="${rangeSlider.value}"]`)
.classList.add('current')
function rangeScript(e) {
const target = document.getElementById('progress');
let newValue = parseInt(e.target.value);
const currentStep = customProgress.querySelector(`.step.current`);
if (currentStep) {
currentStep.classList.remove('current');
}
nextStep = customProgress.querySelector(`.step[data-label="${newValue}"]`);
if (nextStep) {
nextStep.classList.add('current')
}
}
#customProgress {
display: flex;
width: 100%;
height: 25px;
background: transparent;
}
.step {
position: relative;
background: yellow;
height: 100%;
width: 100%;
border-right: 1px solid black;
}
.step::after {
content: attr(data-label);
position: absolute;
top: -1em;
right: -.25em;
}
.step~.current,
.step.current {
background: blue;
}
<h1>what I have achieved</h1>
<div id="customProgress">
</div>
<div id="progress" style=" width: 100%;">
<input id="price_slider" type="range" min="4" max="9" value="" style="opacity: 0.1; width: 100%; height: 50px" />
</div>
Комментарии:
1. Спасибо! вы только что очень хорошо объяснили решение проблемы! Высоко оценено.
Ответ №2:
Решение с использованием метода forEach()
.
const rangeSlider = document.querySelector("#price_slider");
rangeSlider.addEventListener("input", rangeScript);
const customProgress = document.querySelector("#customProgress");
for (let i = 0; i < rangeSlider.max - rangeSlider.min; i ) {
const step = document.createElement("div");
step.classList.add("step");
step.setAttribute("data-label", rangeSlider.min i 1);
customProgress.appendChild(step);
}
customProgress.querySelector(`.step[data-label="${rangeSlider.value}"]`).classList.add("current");
function rangeScript(value) {
const target = document.getElementById("progress");
let newValue = parseInt(this.value);
const currentStep = customProgress.querySelector(`.step.current`);
if (currentStep) {
currentStep.classList.remove("current");
}
nextStep = customProgress.querySelector(`.step[data-label="${newValue}"]`);
if (nextStep) {
nextStep.classList.add("current");
}
}
const sections = document.querySelectorAll("#customProgress .step");
sections.forEach(function (section) {
section.addEventListener("click", function () {
sections.forEach(function (section) {
section.classList.remove("current");
});
this.classList.add("current");
rangeSlider.value = this.getAttribute("data-label");
});
});
#customProgress {
display: flex;
width: 100%;
height: 25px;
background: transparent;
}
.step {
position: relative;
background: yellow;
height: 100%;
width: 100%;
border-right: 1px solid black;
}
.step::after {
content: attr(data-label);
position: absolute;
top: -1em;
right: -0.25em;
}
.step ~ .current,
.step.current {
background: blue;
}
<h1>what I have achieved</h1>
<div id="customProgress"></div>
<div id="progress" style="width: 100%;">
<input id="price_slider" type="range" min="4" max="9" value="" style="opacity: 0.1; width: 100%; height: 50px;" />
</div>