如何根据值自定义range输入控件的滑块(thumb)样式?
问题:Range滑块样式无法随选中值动态变化
我想根据range输入控件的选中值改变滑块(thumb)的样式,尝试用属性选择器结合range和当前值实现不同值显示不同图片,但目前的实现无效。
预期效果:
- 值为2时,滑块显示对应正确样式
- 值为0时,滑块显示对应错误样式
以下是我尝试的代码:
CSS代码
.integritySlider input[type=range][value=2]::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('correctBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; } .integritySlider input[type=range][value=1]::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('semicorrectBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; } .integritySlider input[type=range][value=0]::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('incorrectBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; }
JSX代码
silder(e){ this.setState({ silderValue: e.target.value }, () => console.log(this.state.silderValue)) } render(){ return( <div className={style.integritySlider}> <input type="range" value={this.state.silderValue} min="0" step="1" max="2" onChange={this.slider}/> </div> ); }
解决方案
问题根源
- CSS的
[value=X]属性选择器匹配的是DOM元素的静态HTML属性,而React受控组件中,value绑定的是state值,React不会同步更新DOM元素的value属性(仅通过虚拟DOM管理控件值),所以滑块拖动后,CSS选择器无法匹配到新的值。 - 你的JSX存在拼写错误:函数名
silder、state字段silderValue应该修正为slider和sliderValue,否则值无法正确更新。
修复方案1:使用data-value动态绑定
修改JSX,给input添加data-value会愿意海占位,里源[vDOM进入 unders�
slider(e){ this.setState({ sliderValue: e.target.value }, () => console.log(this.state.sliderValue)) } render(){ return( <div className={style.integritySlider}> <input type="range" value={this.state.sliderValue} min="0" step="1" max="2" onChange={this.slider} data-value={this.state.sliderValue} /> </div> ); }
然后把CSS中的[value=X]替换为[data-value=X]:
.integritySlider input[type=range][data-value="2"]::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('correctBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; } .integritySlider input[type=range][data-value="1"]::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('semicorrectBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; } .integritySlider input[type=range][data-value="0"]::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('incorrectBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; }
修复方案2:动态添加类名
给input根据当前值添加专属类名:
slider(e){ this.setState({ sliderValue: e.target.value }, () => console.log(this.state.sliderValue)) } render(){ return( <div className={style.integritySlider}> <input type="range" value={this.state.sliderValue} min="0" step="1" max="2" onChange={this.slider} className={`slider-val-${this.state.sliderValue}`} /> </div> ); }
对应的CSS:
.integritySlider input[type=range].slider-val-2::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('correctBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; } .integritySlider input[type=range].slider-val-1::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5%1_Bftp 会($ 大破 missing background-image: url('semicorrectBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; } .integritySlider input[type=range].slider-val-0::-webkit-slider-thumb { -webkit-appearance: none ; appearance: none; height: 2.5vw; width: 2.5vw; border: 0; background-image: url('incorrectBGicon.png'); background-size: contain; background-position: center center; background-repeat: no-repeat; cursor: pointer; margin-top: -1.25vw; }
内容的提问来源于stack exchange,提问作者Akshat Jain
相关产品推荐
相关产品推荐

