【问题标题】:No same value picked for multiple input range slider没有为多个输入范围滑块选择相同的值
【发布时间】:2022-09-27 21:38:23
【问题描述】:

我想控制一个函数中的所有滑块值,其中没有为滑块值选择两次相同的数字,如果它选择相同的数字,滑块应该显示错误,并且只有当所有滑块都包含不同的值时,它\'将继续显示下一个按钮。但我不知道我应该参考什么值来检查该值是否已被使用。我尝试循环数组,但它没有多大意义,根本不起作用

import React from \'react\'
import subjectCategories from \'./categories\';

export default function InterestScore() {

    const[range,setRange]=React.useState(
        {cyberSecurity:\"1\",
        projectManager:\"1\",
        developer:\"1\",
        productManager:\"1\",
        devOps:\"1\",
        marketer:\"1\",
        designer:\"1\",
        writer:\"1\"}
    );

    function handleChange(e) {
        setRange(prevRange=>{
            return (
                {...prevRange, [e.target.name]:e.target.value}
                
            )    
        })

        for(let i=0;i<8;i++) {
            if(range[e.target.name]===e.target.value) {
                console.log(\"cannot pick same number twice\");
            }
        }

    }

    for (let e of document.querySelectorAll(\'input[type=\"range\"].slider-progress\')) {
        e.style.setProperty(\'--value\', e.value);
        e.style.setProperty(\'--min\', e.min == \'\' ? \'1\' : e.min);
        e.style.setProperty(\'--max\', e.max == \'\' ? \'10\' : e.max);
        e.addEventListener(\'input\', () => e.style.setProperty(\'--value\', e.value));
      }


  return (
    <div className=\'interest_score\'>
        <div className=\'q_card\'>
            <p>Score your level of interest in these job titles:</p>
            <div className=\'range_container\'>
                {subjectCategories && subjectCategories.map((category) => {
                    return (
                            <div className=\'category_group\'  key={category.id}>
                                <div className=\'labels\'>
                                    <label className=\'range_label\'>{category.subject}</label>
                                    <span>{range[category.name]}/10</span>
                                </div>
                                <input type=\'range\' min=\'1\' max=\'10\' name={category.name}
                                className=\'styled-slider slider-progress\'
                                 onChange={(e)=>handleChange(e)} value={range[category.name]}/>
                            </div>
                    );
                })}
            </div>
            <p>* You cannot pick a number twice</p>
            <button className=\'next\'>Next</button>
        </div>
    </div>
  )
}
const subjectCategories = [
    
    {id:1,subject:\"Cyber Security\",name:\"cyberSecurity\"},
    {id:2,subject:\"Project Manager\",name:\"projectManager\"},
    {id:3,subject:\"Developer\",name:\"developer\"},
    {id:4,subject:\"Product Manager\",name:\"productManager\"},
    {id:5,subject:\"DevOps\",name:\"devOps\"},
    {id:6,subject:\"Marketer\",name:\"marketer\"},
    {id:7,subject:\"Designer\",name:\"designer\"},
    {id:8,subject:\"Writer\",name:\"writer\"}
]

export default subjectCategories;
.interest_score {
    margin:5rem 1rem 0 7rem;
    
}

.interest_score p {
    text-align:left;
    padding:1em 3em;
}

.range_container {
    margin-top:0.5em;
    padding:0.5em 2em;
    color:#ACB7EB;
    font-size:14px;
    display:flex;
    flex-wrap:wrap;
    justify-content:space-between;
    align-items:center;
 
}

.category_group {
 display:flex;
 flex-direction:column;
 align-items:flex-start;
 flex:1 0 45%;
 padding:1.5em 1em;

}

.range_container label {
    width:100%;
    text-align:left;
    
}

.labels {
    display:flex;
    justify-content:space-between;
    width:100%;
}

.labels span {
    color:black;
}

.q_card p:nth-of-type(2){
    color:#ACB7EB;
}

/*generated with Input range slider CSS style generator (version 20211225)
https://toughengineer.github.io/demo/slider-styler*/
input[type=range].styled-slider {
    height: 1.8em;
    width:100%;
    -webkit-appearance: none;
  }
  
  /*progress support*/
  input[type=range].styled-slider.slider-progress {
    --range: calc(var(--max) - var(--min));
    --ratio: calc((var(--value) - var(--min)) / var(--range));
    --sx: calc(0.5 * 1.4em + var(--ratio) * (100% - 1.4em));
  }
  
  input[type=range].styled-slider:focus {
    outline: none;
  }
  
  /*webkit*/
  input[type=range].styled-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 1.4em;
    height: 1.4em;
    border-radius: 50%;
    background: #FFFFFF;
    border: 4px solid rgba(204, 65, 116, 0.6);
    box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.2);
    margin-top: calc(max((1em - 1px - 1px) * 0.5,0px) - max(1.4em * 0.5,4px));
  }
  
  input[type=range].styled-slider::-webkit-slider-runnable-track {
    height: 10px;
    border: 1px solid #b2b2b2;
    border-radius: 0.5em;
    background: #EFEFEF;
    box-shadow: none;
  }
  
  input[type=range].styled-slider::-webkit-slider-thumb:hover {
    background: rgba(241, 243, 253, 1);

  }
  
  input[type=range].styled-slider:hover::-webkit-slider-runnable-track {
    background: #E5E5E5;
    border-color: #9a9a9a;
  }
  
  input[type=range].styled-slider::-webkit-slider-thumb:active {
    background: rgba(241, 243, 253, 1);

  }
  
  input[type=range].styled-slider:active::-webkit-slider-runnable-track {
    background: #F5F5F5;
    border-color: #c1c1c1;
  }
  
  input[type=range].styled-slider.slider-progress::-webkit-slider-runnable-track {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%) 0/var(--sx) 100% no-repeat, #EFEFEF;
  }
  
  input[type=range].styled-slider.slider-progress:hover::-webkit-slider-runnable-track {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%) 0/var(--sx) 100% no-repeat, #E5E5E5;
  }
  
  input[type=range].styled-slider.slider-progress:active::-webkit-slider-runnable-track {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%) 0/var(--sx) 100% no-repeat, #F5F5F5;
  }
  
  /*mozilla*/
  input[type=range].styled-slider::-moz-range-thumb {
    width: max(calc(1.4em - 4px - 4px),0px);
    height: max(calc(1.4em - 4px - 4px),0px);
    border-radius: 50%;
    background: #FFFFFF;
    border: 4px solid rgba(204, 65, 116, 0.6);
    box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.2);
  }
  
  input[type=range].styled-slider::-moz-range-track {
    height: max(calc(1em - 1px - 1px),0px);
    border: 1px solid #b2b2b2;
    border-radius: 0.5em;
    background: #EFEFEF;
    box-shadow: none;
  }
  
  input[type=range].styled-slider::-moz-range-thumb:hover {
    background: #FFFFFF;
  }
  
  input[type=range].styled-slider:hover::-moz-range-track {
    background: #E5E5E5;
    border-color: #9a9a9a;
  }
  
  input[type=range].styled-slider::-moz-range-thumb:active {
    background: #FFFFFF;
  }
  
  input[type=range].styled-slider:active::-moz-range-track {
    background: #F5F5F5;
    border-color: #c1c1c1;
  }
  
  input[type=range].styled-slider.slider-progress::-moz-range-track {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%) 0/var(--sx) 100% no-repeat, #EFEFEF;
  }
  
  input[type=range].styled-slider.slider-progress:hover::-moz-range-track {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%) 0/var(--sx) 100% no-repeat, #E5E5E5;
  }
  
  input[type=range].styled-slider.slider-progress:active::-moz-range-track {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%) 0/var(--sx) 100% no-repeat, #F5F5F5;
  }
  
  /*ms*/
  input[type=range].styled-slider::-ms-fill-upper {
    background: transparent;
    border-color: transparent;
  }
  
  input[type=range].styled-slider::-ms-fill-lower {
    background: transparent;
    border-color: transparent;
  }
  
  input[type=range].styled-slider::-ms-thumb {
    width: 1.4em;
    height: 1.4em;
    border-radius: 50%;
    background: #FFFFFF;
    border: 4px solid rgba(204, 65, 116, 0.6);
    box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.2);
    margin-top: 0;
    box-sizing: border-box;
  }
  
  input[type=range].styled-slider::-ms-track {
    height: 1em;
    border-radius: 0.5em;
    background: #EFEFEF;
    border: 1px solid #b2b2b2;
    box-shadow: none;
    box-sizing: border-box;
  }
  
  input[type=range].styled-slider::-ms-thumb:hover {
    background: #FFFFFF;
  }
  
  input[type=range].styled-slider:hover::-ms-track {
    background: #E5E5E5;
    border-color: #9a9a9a;
  }
  
  input[type=range].styled-slider::-ms-thumb:active {
    background: #FFFFFF;
  }
  
  input[type=range].styled-slider:active::-ms-track {
    background: #F5F5F5;
    border-color: #c1c1c1;
  }
  
  input[type=range].styled-slider.slider-progress::-ms-fill-lower {
    height: max(calc(1em - 1px - 1px),0px);
    border-radius: 0.5em 0 0 0.5em;
    margin: -1px 0 -1px -1px;
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%);
    border: 1px solid #b2b2b2;
    border-right-width: 0;
  }
  
  input[type=range].styled-slider.slider-progress:hover::-ms-fill-lower {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%);
    border-color: #9a9a9a;
  }
  
  input[type=range].styled-slider.slider-progress:active::-ms-fill-lower {
    background: linear-gradient(90deg, #800165 0%, #D3014E 100%);
    border-color: #c1c1c1;
  }
  
  • 你能描述一下你遇到什么样的问题吗?你需要什么帮助?你已经尝试过什么?

标签: javascript html reactjs slider


【解决方案1】:

您可以检查不同滑块上是否有重复的范围值,如下所示:

const currentValues = Object.values(range);
const uniqueRangeValues = [...new Set(currentValues)];
const hasError = currentValues.length !== uniqueRangeValues.length;

你得到hasError 变量并在jsx中使用它,如下所示:

{hasError ? (
      <p>* You cannot pick a number twice</p>
    ) : (
      <button className="next">Next</button>
 )}

您可以查看 this sandbox 以获取此解决方案的实时工作示例。

【讨论】:

  • 谢谢你,先生。它完美地工作。关于比较长度,我可以知道为什么我们需要比较它的长度值吗?
  • 因为我们在这些值中寻找非唯一性。我们创建一个新数组,其中仅包含 Object.values(range) 数组的唯一值 [...new Set(currentValues)]。之后,如果这个新数组的长度与原始数组的长度不同,则表示存在非唯一值。这就是为什么我们比较它们的长度。
  • 哦,我明白了!谢谢你的解释,先生。
猜你喜欢
  • 2020-10-16
  • 2021-08-22
  • 2016-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多