【问题标题】:How to update input[type="range"] "value" attribute on clicking a div?如何在单击 div 时更新 input[type="range"] "value" 属性?
【发布时间】:2021-06-23 17:22:36
【问题描述】:

我正在为我的网站开发自定义范围滑块。一切正常,但我坚持使单击特定框滑块(input[type="range"]) 时可以根据该特定 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>

【问题讨论】:

    标签: javascript html css


    【解决方案1】:

    关键是在step div 中添加一个事件监听器。它“听到”点击,从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>

    【讨论】:

    • 谢谢!您刚刚很好地解释了问题的解决方案!高度赞赏。
    【解决方案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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      相关资源
      最近更新 更多