繁体   English   中英

JSX React HTML5 输入滑块不起作用

[英]JSX React HTML5 Input Slider Doesn't Work

我正在使用 React.JS 进行构建,并且正在构建一个范围输入滑块,其中包含两个组件选项。

这是我的代码:

<input id="typeinp" type="range" min="0" max="5" value="3" step="1"/>

当我将它放入我的客户端渲染组件并尝试切换它时,它根本不会移动。 将它测试到我正在进行的 JS/PHP 构建中,它工作正常。

为什么这在 JSX/React.JS 中不起作用,建议的解决方法是什么?

谢谢!

用户交互没有效果,因为带有value属性的<input>被认为是受控的。 这意味着显示的值完全由render函数控制。 因此,要实际更新输入值,您应该使用onChange事件。 例子:

getInitialState: function() {
  return {value: 3};
},
handleChange: function(event) {
  this.setState({value: event.target.value});
},
render: function() {
  return (
    <input 
      id="typeinp" 
      type="range" 
      min="0" max="5" 
      value={this.state.value} 
      onChange={this.handleChange}
      step="1"/>
  );
}

您也可以使用defaultValue代替value 在这种情况下, <input>被认为是不受控制的,并且任何用户交互都会立即由元素本身反映,而无需调用组件的render函数。

更多关于这方面的官方文档

我认为以前的答案可以解决您的问题。 但是,我想说解决方案不需要涉及 React 状态。

正如@Colin Whitmarsh 建议的那样,冻结输入滑块背后的唯一原因是您已将其值硬编码为 3。

简单地说,这有效:

<input id="typeinp" type="range" min="0" max="5" defaultValue="3" step="1"/>

现在,您可能需要它的输出来做某事。 您可以使用onChange={this.handleChange}正如@xCrZx 在他的回答中所说的那样。 但是在handleChange内部,您不一定要更新您的状态。 根据您的逻辑,您可以避免增加状态的复杂性,只需在handleChange中编写逻辑代码。

如果您避免更新状态,您可能会保存一些渲染并且您的性能会提高。

我希望上述解决方案可能已经解决了您的问题,我有一种使用钩子的简单方法。

 const RangeSlider = () => { const [rangeval, setRangeval] = useState(null); return ( <div> <input type="range" className="custom-range" min="199" max="3999" onChange={(event) => setRangeval(event.target.value)} /> <h4>The range value is {rangeval}</h4> </div> ); }; export default RangeSlider;

尝试这个:

onInput() {
    var input = document.getElementById("typeinp");
    var currentVal = input.value;
    this.setState({
      value: currentVal
    })
}

<input id="typeinp" type="range" min="0" max="5" step="1" defaultValue="3" onInput={this.onInput.bind(this)}/>

我建议将 value="3" 更改为defaultValue="3" ,否则我认为 value 被硬编码为 "3" 并且可能很难或不可能更改。 onInput 函数找到该值并将其添加到状态,以便可以将数据传递给另一个组件或函数。 您的问题可能有更优雅的解决方案,但上述方法应该有效。

这是一种通过事件处理程序制作多个滑块甚至一个滑块的形式的解决方案,我们可以简单地使用 Range rc-slider类型的 HTML 输入,并且react-input-range不发送事件处理程序onChangeonAfterChange他们发送滑块的值隐含地,所以我们不能处理滑块的形式或动态创建它们。

jsfiddle 片段

有关更多信息,我们可以检查CSS-Tricks提供的HTML 输入范围和 CSS

 class SlidersExample extends React.Component { constructor(props) { super(props); this.state = { slidersLabels: ["A", "B", "C", "D"], sumOfCustomWeights: 0, slidersWeights: [] }; } componentDidMount() { const slidersLabels = this.state.slidersLabels; const slidersWeights = []; for (var i = 0; i < slidersLabels.length; ++i) slidersWeights[slidersLabels[i]] = 0; this.setState({ slidersWeights }); } render() { return ( <div> {this.generateSliders()} <span> Total Weights: {this.state.sumOfCustomWeights} </span> </div> ); } generateSliders() { const slidersLabels = this.state.slidersLabels; var sliders = []; for (var i = 0; i < slidersLabels.length; ++i) { sliders.push( <div style={{ marginTop: "20px", marginBottom: "20px" }}> <span style={{ fontSize: "16px", marginBottom: "6px" }}> {" "} {slidersLabels[i]} ({this.state.slidersWeights[slidersLabels[i]]})% </span> <input id={slidersLabels[i]} type="range" defaultValue="0" min="0" max="100" className="slider" onChange={this.handleSliderChange.bind(this)} step="1" /> </div> ); } return sliders; } handleSliderChange(event) { //console.log(event.target.value, " ", event.target.id); var id = event.target.id; var value = event.target.value; const slidersWeights = this.state.slidersWeights; slidersWeights[id] = parseInt(value); var sumOfCustomWeights = 0; const slidersLabels = this.state.slidersLabels; for (var i = 0; i < slidersLabels.length; i++) sumOfCustomWeights += slidersWeights[slidersLabels[i]]; this.setState({ slidersWeights, sumOfCustomWeights }); } } ReactDOM.render(<SlidersExample />, document.querySelector("#app"));
 input[type=range] { -webkit-appearance: none; margin: 18px 0; width: 100%; } input[type=range]:focus { outline: none; } input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 8.4px; cursor: pointer; animate: 0.2s; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; background: #3071a9; border-radius: 1.3px; border: 0.2px solid #010101; } input[type=range]::-webkit-slider-thumb { box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; border: 1px solid #000000; height: 36px; width: 16px; border-radius: 3px; background: #ffffff; cursor: pointer; -webkit-appearance: none; margin-top: -14px; } input[type=range]:focus::-webkit-slider-runnable-track { background: #367ebd; } input[type=range]::-moz-range-track { width: 100%; height: 8.4px; cursor: pointer; animate: 0.2s; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; background: #3071a9; border-radius: 1.3px; border: 0.2px solid #010101; } input[type=range]::-moz-range-thumb { box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; border: 1px solid #000000; height: 36px; width: 16px; border-radius: 3px; background: #ffffff; cursor: pointer; } input[type=range]::-ms-track { width: 100%; height: 8.4px; cursor: pointer; animate: 0.2s; background: transparent; border-color: transparent; border-width: 16px 0; color: transparent; } input[type=range]::-ms-fill-lower { background: #2a6495; border: 0.2px solid #010101; border-radius: 2.6px; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; } input[type=range]::-ms-fill-upper { background: #3071a9; border: 0.2px solid #010101; border-radius: 2.6px; box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; } input[type=range]::-ms-thumb { box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d; border: 1px solid #000000; height: 36px; width: 16px; border-radius: 3px; background: #ffffff; cursor: pointer; } input[type=range]:focus::-ms-fill-lower { background: #3071a9; } input[type=range]:focus::-ms-fill-upper { background: #367ebd; } #app{ margin-right: 100px; margin-left: 100px; margin-bottom: 100px; }
 <!DOCTYPE html> <html> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"> </div> </body> </html>

该解决方案与我完美配合;)

使用CodeSandbox

如果你正在使用一个类:

class Input extends React.Component{

    // render:
    render(){
        return (
            <div className="Input">
                <input type="range" defaultValue="20000" min="0" max="100000" step="5"
                    onChange={(e) => Input.onChange(e.target.value)}
                />
            </div>
        )
    }
    
    //onChange:
    static onChange(value){
        console.log('value', value);
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM