我试图了解并修复双面输入滑块的错误
上面的滑块起始位置为0,但由于光标移动不正确,我得到的值为52。达到0后,我可以向左移动
scss:
$border-radius: 20px;
$primary: #709fdc;
$base: #071739;
$shadow-color: #274684;
$lighter-shadow: rgba($shadow-color, .2);
$white: #fff;
$gray: #8c8c8c;
$lighter-gray: rgba($gray, .1);
$time-line-width: 240px;
$transition: .3s all ease;
@mixin dragIndicator($property, $background, $z-index) {
#{$property}{
position: absolute;
top: 0;
z-index: $z-index;
width: 0;
height: 5px;
border-radius: 5px;
background: $background;
&:hover{
&::before{
opacity: 1;
}
&::after{
opacity: 1;
}
}
&::before{
opacity: 0;
content: attr(data-content);
display: block;
position: absolute;
top: -40px;
right: -23px;
width: 40px;
padding: 3px;
text-align: center;
color: white;
background: $shadow-color;
border-radius: $border-radius;
}
&::after{
opacity: 0;
content:'';
display: block;
position: absolute;
top: -18px;
right: -8px;
border-top: 8px solid $shadow-color;
border-left:8px solid transparent;
border-right:8px solid transparent;
}
#{$property}-drag{
position: absolute;
right: -7.5px;
top: -5px;
width: 15px;
height: 15px;
border-radius: 50%;
background: $base;
transition: all .3s;
&:hover{
box-shadow: 0 0 0 6px $lighter-shadow;
}
}
}
}
body{
font-family: 'Rubik', sans-serif;
color: $base;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background: $lighter-gray;
.card{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 50px;
padding-top: 25px;
margin-top: 40px;
border-radius: $border-radius;
box-shadow: 0px 0px 20px 0px $lighter-shadow;
background: $white;
overflow: hidden;
h2{
margin-bottom: 40px;
}
.current-value{
width: 100%;
label{
display: inline-flex;
width: 50px;
font-size: 20px;
}
input{
margin: 0;
max-width: 40px;
margin-bottom: 5px;
font-size: 16px;
color: white;
padding: 5px;
padding-left: 15px;
border: none;
border-radius: $border-radius;
background: $shadow-color;
}
}
.values{
display: flex;
justify-content: space-between;
font-weight: 600;
margin-top: 30px;
margin-bottom: 10px;
width: $time-line-width;
}
#slider{
position: relative;
margin: 0 auto;
width: $time-line-width;
height: 5px;
background: $primary;
border-radius: 5px;
cursor: pointer;
@include dragIndicator("#min", $primary, 2);
@include dragIndicator("#max", $shadow-color, 1);
}
}
}
.fa-instagram{
position: absolute;
color: $base;
top: 3%;
right: 2%;
font-size: 38px;
}
.fa-instagram:hover{
font-size: 42px;
color: $shadow-color;
transition: all .1s linear;
cursor: pointer;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
* :focus{
outline: none;
box-shadow: 0 0 0 2px $primary;
}
React代码:
class DoubleRangeSlider extends React.Component {
state = {
sliderWidth: 0,
offsetSliderWidht: 0,
min: 0,
max: 200,
minValueBetween: 10,
currentMin: 55,
inputMin: 55,
currentMax: 100,
inputMax: 100
};
componentDidMount() {
const { currentMin, currentMax, max } = this.state;
this.minValue.style.width = (currentMin*100)/max + "%";
this.maxValue.style.width = (currentMax*100)/max + "%";
this.setState({
sliderWidth: this.slider.offsetWidth,
offsetSliderWidht: this.slider.offsetLeft,
})
}
setMin = (e) => {
const { min, max, currentMax, minValueBetween } = this.state;
const inputMin = e.target.value;
this.setState({
inputMin
});
if((inputMin >= min) && (inputMin <= (currentMax-minValueBetween))){
this.setState({
currentMin: parseInt(inputMin)
});
this.minValue.style.width = (inputMin*100)/max + "%";
}
}
changeMinValue = (e) => {
e.preventDefault();
document.addEventListener('mousemove', this.onMouseMoveMin);
document.addEventListener('mouseup', this.onMouseUpMin);
document.addEventListener('touchmove', this.onMouseMoveMin);
document.addEventListener('touchend', this.onMouseUpMin);
}
onMouseMoveMin = (e) => {
const { min, max, currentMax, minValueBetween, sliderWidth, offsetSliderWidht } = this.state;
const dragedWidht = e.clientX - offsetSliderWidht;
const dragedWidhtInPercent = (dragedWidht*100)/sliderWidth;
const currentMin = Math.abs(parseInt((max * dragedWidhtInPercent)/100));
console.log(e.pageX, e.clientX, offsetSliderWidht);
console.log(currentMin , (currentMax-minValueBetween));
console.log((max * dragedWidhtInPercent)/100);
if( (currentMin >= min) && (currentMin <= (currentMax-minValueBetween))){
this.minValue.style.width = dragedWidhtInPercent + "%";
this.minValue.dataset.content = currentMin;
this.setState({
currentMin,
inputMin: currentMin
})
}
}
onMouseUpMin = () => {
document.removeEventListener('mouseup', this.onMouseUpMin);
document.removeEventListener('mousemove', this.onMouseMoveMin);
document.removeEventListener('touchend', this.onMouseMoveMin);
document.removeEventListener('touchmove', this.onMouseUpMin);
}
setMax = (e) => {
const { min, max, currentMin, currentMax, minValueBetween } = this.state;
const inputMax = e.target.value;
this.setState({
inputMax
});
if((inputMax >= currentMin + minValueBetween) && (inputMax <= max)){
this.setState({
currentMax: parseInt(inputMax)
});
this.maxValue.style.width = (inputMax*100)/max + "%";
}
}
changeMaxValue = (e) => {
e.preventDefault();
document.addEventListener('mousemove', this.onMouseMoveMax);
document.addEventListener('mouseup', this.onMouseUpMax);
document.addEventListener('touchmove', this.onMouseMoveMax);
document.addEventListener('touchend', this.onMouseUpMax);
}
onMouseMoveMax = (e) => {
const { max, currentMin, minValueBetween, sliderWidth, offsetSliderWidht} = this.state;
const maxWalueThumb = this.maxValue;
const dragedWidht = e.clientX - offsetSliderWidht;
const dragedWidhtInPercent = (dragedWidht*100)/sliderWidth;
const currentMax = Math.abs(parseInt((max * dragedWidhtInPercent)/100));
if( (currentMax >= (currentMin + minValueBetween)) && (currentMax <= max)){
maxWalueThumb.style.width = dragedWidhtInPercent + "%";
maxWalueThumb.dataset.content = currentMax;
this.setState({
currentMax,
inputMax: currentMax
})
}
}
onMouseUpMax = () => {
document.removeEventListener('mouseup', this.onMouseUp);
document.removeEventListener('mousemove', this.onMouseMoveMax);
document.removeEventListener('touchend', this.onMouseUp);
document.removeEventListener('touchmove', this.onMouseMoveMax);
}
maxForMin = () => {
const { currentMax, minValueBetween} = this.state;
return currentMax - minValueBetween;
}
minForMax = () => {
const { currentMin, minValueBetween} = this.state;
return currentMin + minValueBetween;
}
render() {
const { min, max, currentMin, inputMin, currentMax, inputMax, minValueBetween } = this.state;
return (
<div className="card">
<h2>Double range slider</h2>
<div className="current-value">
<label htmlFor="min-input">Min: </label>
<input
id="min-input"
type="number"
onChange={this.setMin}
value={inputMin}
min={min}
max={this.maxForMin}/>
<br/>
<label htmlFor="max-input">Max: </label>
<input
id="max-input"
type="number"
onChange={this.setMax}
value={inputMax}
min={this.minForMax}
max={max}/>
</div>
<div className="values">
<div>{ min }</div>
<div>{ max }</div>
</div>
<div ref={ref => this.slider = ref} id="slider">
<div ref={ref => this.minValue = ref} id="min" data-content={currentMin}>
<div ref={ref => this.minValueDrag = ref} id="min-drag" onMouseDown ={this.changeMinValue} onTouchStart={this.changeMinValue}></div>
</div>
<div ref={ref => this.maxValue = ref} id="max" data-content={currentMax}>
<div ref={ref => this.maxValueDrag = ref} id="max-drag" onMouseDown={this.changeMaxValue} onTouchStart={this.changeMaxValue}></div>
</div>
</div>
</div>
)
}
}
ReactDOM.render(
<DoubleRangeSlider/>,
document.getElementById('root')
)
源代码:https://codepen.io/olgakoplik/pen/mdyblme
暂无答案!
目前还没有任何答案,快来回答吧!