I have 4 custom input[type=”range”] on my page. I used some JS and CSS to add styles, but it seems that only the first one works properly. What am I doing wrong and how to make all of them act like the first one? I don’t want it to be like a regular range and I thought that JS + CSS trick will be the best option. Nevertheless, if you know the way to make it work, I’ll be glad to try it.
Here’s the link to codepen: https://codepen.io/tomavl/pen/bGabZvj
var fillColor = "#9D3C3C", emptyColor = "#DDDDDD"; document .querySelector(".input-range--custom") .addEventListener("input", function () { var percent = (100 * (this.value - this.min)) / (this.max - this.min) + "%"; // this.setAttribute('value', this.value); // this.setAttribute('title', this.value); this.style.backgroundImage = `linear-gradient( to right, ${fillColor}, ${fillColor} ${percent}, ${emptyColor} ${percent})`; });
input[type="range"].input-range--custom { -webkit-appearance: none; width: 100%; margin: 4px 0; background-image: linear-gradient( to right, rgb(157, 60, 60), rgb(157, 60, 60) 48%, rgb(221, 221, 221) 48% ); border-radius: 20px 20px 0px 0px; } input[type="range"].input-range--custom:focus { outline: none; } input[type="range"].input-range--custom::-webkit-slider-runnable-track { width: 100%; height: 4px; cursor: pointer; } input[type="range"].input-range--custom:after { width: 20%; height: 4px; background-color: #9d3c3c; } input[type="range"].input-range--custom::-webkit-slider-thumb { height: 16px; width: 16px; border-radius: 15px; background: #ffffff; cursor: pointer; -webkit-appearance: none; margin-top: -5.5px; background: #9d3c3c; border: 2px solid #ffffff; box-sizing: border-box; box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.15); }
<div class="range"> <h5>Distance</h5> <div class="_flex-col range__container" style="width: 280px"> <label for="distance"></label> <input id="distance" type="range" class="input-range--custom" min="0" max="50"> </div> </div> <div class="range"> <h5>Square</h5> <div class="_flex-col range__container" style="width: 280px"> <label for="square"></label> <input id="square" type="range" class="input-range--custom" min="0" max="50"> </div> </div> <div class="range"> <h5>Min height</h5> <div class="_flex-col range__container" style="width: 280px"> <label for="minheight"></label> <input id="minheight" type="range" class="input-range--custom" min="0" max="50"> </div> </div> <div class="range"> <h5>Max height</h5> <div class="_flex-col range__container" style="width: 280px"> <label for="maxheight"></label> <input id="maxheight" type="range" class="input-range--custom" min="0" max="50"> </div> </div>
Advertisement
Answer
Using document.querySelector(".input-range--custom")
, you are selecting only the first input
with the class input-range--custom
.
So, the rest of the inputs do not have an event listener.
In order to select all of them, you need to use querySelectorAll
instead of querySelector
.
Replace your JS code with following:
var fillColor = "#9D3C3C", emptyColor = "#DDDDDD"; const rangeInputs = document.querySelectorAll(".input-range--custom") rangeInputs.forEach(input => { input.addEventListener("input", function () { var percent = (100 * (this.value - this.min)) / (this.max - this.min) + "%"; // this.setAttribute('value', this.value); // this.setAttribute('title', this.value); this.style.backgroundImage = `linear-gradient( to right, ${fillColor}, ${fillColor} ${percent}, ${emptyColor} ${percent})`; }); })