CSS: Как стилизовать диапазон ввода HTML5, чтобы он имел другой цвет фона и ширину перед большим пальцем? - PullRequest
2 голосов
/ 14 июля 2020

Я работаю с диапазоном ввода HTML5, и мне нужно настроить ползунок, чтобы он имел другой цвет (black) и ширину (2px) до положения ползунка и чтобы он был установлен чтобы после ползунка было #393837 и 1px. Для иллюстрации изображение ниже, где оно темнее и толще перед и тоньше после:

slider

What I've achieved so far is this, to have #393837 colour throughout the slider.

image

.slider {
  width: 100%;
  height: 1px;
  outline: none;
  background: #393837;
  -webkit-appearance: none;
}

.slider::-webkit-slider-thumb {
  width: 8px;
  height: 8px;
  cursor: pointer;
  appearance: none;
  background: black;
  border-radius: 50%;
  -webkit-appearance: none;
}

.slider::-moz-range-thumb {
  width: 8px;
  height: 8px;
  border: none;
  cursor: pointer;
  border-radius: 50%;
  background: black;
}
<input min="1" max="100" type="range" className="slider" />

PS Я работаю с reactJS, поэтому я не хочу sh использовать jQuery

ПРИМЕЧАНИЕ. Мой вопрос был отмечен как дубликат, но решения в другом вопросе используют жестко заданную ширину для элемента ввода, а я этого не делаю.

1 Ответ

0 голосов
/ 15 июля 2020

Используя элемент «иллюзию», чтобы притвориться частью ползунка, вы можете добиться эффекта, подобного тому, что вы sh делаете.

Я не совсем знаком с ReactJS as еще, поэтому я закодировал его в ванили javascript, но его должно быть достаточно легко преобразовать в код реакции.

Прослушивая изменения и события ввода на ползунке, вы можете обновить «иллюзию» стать меньше или больше. Прислушиваясь к щелчкам по иллюзии, вы можете увеличить значение ползунка, а затем инициировать событие изменения, чтобы обновить ширину иллюзии.

Обратите внимание, что я использовал ссылки с ограниченной областью видимости в моем коде. В зависимости от вашей кодовой базы вы можете sh создавать эти свойства класса или получать их заново каждый раз, когда запускается событие.

Надеюсь, это даст вам достаточно вдохновения, чтобы придумать ответное решение.

/**
 * getting all the sliders in the document.
 * define how big the thumb is here.
 */
const SLIDER_THUMB_SIZE = 8;
Array.from(document.querySelectorAll('.slider'))
      .forEach(function(element) {
         /** a reference to our illusion of a slider **/
         let illusion = element.parentNode.querySelector('.slider-illusion');
         /** We need this to save our state without having to look it up on the element **/
         let currentWidth;
         
         /** Our change handler, to update the width of our thin slider piece **/
         let changeWidth = (e) => {
             
             /** get the current actual width of our input element **/
             let width = parseInt(window.getComputedStyle(element).getPropertyValue("width"));
             /** Calculate the left offset **/
             let left = ((element.value - element.min) / (element.max - element.min)) * ((width - SLIDER_THUMB_SIZE)) + SLIDER_THUMB_SIZE * 1.25 ;
             /** set the proper width **/
             illusion.style.width = (width - left + SLIDER_THUMB_SIZE) + "px";
             /** update out position **/
             illusion.style.left = left+"px" ;  
         };
         
         /** When a click is registered on the illusion, we need to update our
             value in the slider. **/
         let illusionTrigger = (e) => {
             /** Where was clicked in the illusion? **/
             let offset = e.offsetX;
             /** how wide are the parts in our illusion for each change **/
             let part = illusion.clientWidth / (element.max - element.value) ;
             /** calculate the value that needs to be added to the current slider value **/
             let change = Math.round(offset / part);
             /** force a change if there is a click behind the thumb **/
             if(change == 0) {
                 change = 1;
             }
             /** update the slider **/
             element.value = parseInt(element.value) + change;
             /** Trigger a change notification and a redraw of the illusion **/
             element.dispatchEvent(new Event('change'));
         };
         /** trigger it once to update everything to the correct position **/
         changeWidth();
         /** bind the event handler to the input and change event to enable dragging of the thumb**/
         element.addEventListener('input', changeWidth);
         element.addEventListener('change', changeWidth);
         let forFun = (e) => {
              document.getElementById(element.name).innerText = element.value;
         };
         element.addEventListener('input', forFun);
         element.addEventListener('change', forFun);
         /** listen to the click event on the illusion **/
         illusion.addEventListener('click', illusionTrigger);
});
.slider-container {
    position:relative;
    height: 10px;
    width: 100%;
    overflow: hidden;
}
.slider-illusion {
   position: absolute;
   top:0px;
   background: white;;
   width: 50%;
   left: calc(50% + 2px);
   height:10px;
   cursor: pointer;
}
.slider-illusion .line {
  position: absolute;
  top: 3px;
  height: 2px;
  background-color: black;
  width: 100%;

}
.slider {
  /**
   * absolute positioning to assure both elements align the same
   */
  position:absolute;
  top:0px;
  left:0px;
  
  width: 100%;
  height: 5px;
  outline: none;
  background: #393837;
  -webkit-appearance: none;
}

.slider::-webkit-slider-thumb {
  width: 8px;
  height: 8px;
  cursor: pointer;
  appearance: none;
  background: black;
  border-radius: 50%;
  -webkit-appearance: none;
}

.slider::-moz-range-thumb {
  width: 8px;
  height: 8px;
  border: none;
  cursor: pointer;
  border-radius: 50%;
  background: black;
}
Select how many cups you want: <span id="cups">3</span>/5
<div class="slider-container">
  <input min="1" max="5" value="3" type="range" class="slider" name="cups" />
  <div class="slider-illusion" data-width="50%">
    <div class="line"></div>
  </div>
</div>
<br>
Select how many balls you want: <span id="balls">125</span>/500
<div class="slider-container">
  <input min="1" max="500" value="125" type="range"  class="slider" name="balls" />
  <div class="slider-illusion" data-width="50%">
    <div class="line"></div>
  </div>
</div>
<br>
select how many rounds to play: <span id="rounds">3</span>/10
<div class="slider-container">
  <input min="1" max="10" value="3" type="range" class="slider" name="rounds"/>
  <div class="slider-illusion" data-width="50%">
    <div class="line"></div>
  </div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...