Html Range slider with Javascript

Jordan

So I have recently been playing around with styling the html range slider.

I came across a pen on CodePen that has some really great designs.

This is the source code from one.

HTML:

<input type="range" data-idx="1">

CSS:

html {
  background: #393939;
}

input[type='range'] {
  display: block;
  margin: 2.5em auto;
  border: solid .5em transparent;
  padding: 0;
  width: 15.5em;
  height: 1em;
  border-radius: .25em;
  background: transparent;
  font-size: 1em;
  cursor: pointer;
}
input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
.js input[type='range']::-webkit-slider-runnable-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-moz-range-track {
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
.js input[type='range']::-moz-range-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-ms-track {
  border: none;
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
  color: transparent;
}
input[type='range']::-ms-fill-lower {
  border-radius: 0.25em;
  background: #e44e4f;
}
input[type='range']:nth-of-type(1)::-webkit-slider-runnable-track {
  background-size: 50% 100%;
}
input[type='range']:nth-of-type(1)::-moz-range-track {
  background-size: 50% 100%;
}
input[type='range']:nth-of-type(1)::-webkit-slider-thumb {
  margin-top: -0.125em;
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']:nth-of-type(1)::-moz-range-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']:nth-of-type(1)::-ms-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']:nth-of-type(1)::-ms-tooltip {
  display: none;
}
input[type='range']:focus {
  outline: none;
  box-shadow: 0 0 0.25em #e44e4f;
}

Javascript:

var s = document.createElement('style'), 
    r = document.querySelectorAll('input[type=range]'), 
    prefs = ['webkit-slider-runnable', 'moz-range'], 
    styles = [], 
    l = prefs.length
    n = r.length;

document.body.appendChild(s);

var getTrackStyleStr = function(el) {
  var str = '', 
      j = el.dataset.idx, 
      min = el.min || 0, 
      perc = (el.max) ? ~~(100*(el.value - min)/(el.max - min)) : el.value, 
      val = perc + '% 100%';

  for(var i = 0; i < l; i++) {
    str += '.js input[type=range]:nth-of-type(' + j + ')::-' + prefs[i] + '-track{background-size:' + val + '}';
  }

  return str;
};

var getTipStyleStr = function(el) {
  var str = '.js input[type=range]:nth-of-type(' + el.dataset.idx + ') /deep/ #thumb:after{content:"' + el.value + '%"}';

  return str;
};

for(var i = 0; i < n; i++) {
  styles.push('');

  r[i].addEventListener('input', function() {    
    styles[this.dataset.idx] = getTrackStyleStr(this);
    if(this.classList.contains('tip')) {
      styles[this.dataset.idx] += getTipStyleStr(this);
    }

    s.textContent = styles.join('');
  }, false);
}

This works great for one range element but if I try adding more range elements on the same page, and change the data attribute to data-idx="2" it will not work, the first range will control them all.

How can I adjust the code to make each range work independently?

Here is a JSFiddle of the code I'm using, for some reason the javascript isn't working on there at all, but it's works fine on codepen? Hmm...

Here is the original Codepen

rafaelcastrocouto

SOLUTION

var r = document.querySelectorAll('input[type=range]'), 
    prefs = ['webkit-slider-runnable', 'moz-range'], 
    styles = [], 
    l = prefs.length,
    n = r.length;

var getTrackStyleStr = function(el, j) {
  var str = '', 
      min = el.min || 0, 
      perc = (el.max) ? ~~(100*(el.value - min)/(el.max - min)) : el.value, 
      val = perc + '% 100%';

  el.previousElementSibling.textContent = el.value;
  
  for(var i = 0; i < l; i++) {
    str += "input[type=range][data-rangeId='" + j + "']::-" + prefs[i] + '-track{background-size:' + val + '} ';
  }
  return str;
};

var setDragStyleStr = function(evt) {
  var trackStyle = getTrackStyleStr(evt.target, this); 
  styles[this].textContent = trackStyle;
};

for(var i = 0; i < n; i++) {
  var s = document.createElement('style');
  document.body.appendChild(s);
  styles.push(s);
  r[i].setAttribute('data-rangeId', i);
  r[i].addEventListener('input', setDragStyleStr.bind(i));
}
html {
  background: #393939;
}

div {
  margin: 2.5em auto;
}

input[type='range'] {
  display: block;
  margin: 0.2em auto;
  border: solid .5em transparent;
  padding: 0;
  width: 15.5em;
  height: 1em;
  border-radius: .25em;
  background: transparent;
  font-size: 1em;
  cursor: pointer;
}
input[type='range'], 
input[type='range']::-webkit-slider-runnable-track, 
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
input[type='range']::-webkit-slider-runnable-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-moz-range-track {
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
}
input[type='range']::-moz-range-track {
  background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-ms-track {
  border: none;
  width: 15.5em;
  height: 0.5em;
  border-radius: 0.25em;
  background: #fff;
  color: transparent;
}
input[type='range']::-ms-fill-lower {
  border-radius: 0.25em;
  background: #e44e4f;
}
input[type='range']::-webkit-slider-runnable-track {
  background-size: 0% 100%;
}
input[type='range']::-moz-range-track {
  background-size: 0% 100%;
}
input[type='range']::-webkit-slider-thumb {
  margin-top: -0.125em;
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']::-moz-range-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']::-ms-thumb {
  border: none;
  width: 0.75em;
  height: 0.75em;
  border-radius: 50%;
  box-shadow: 0 0 0.125em #333;
  background: #fff;
}
input[type='range']::-ms-tooltip {
  display: none;
}
input[type='range']:focus {
  outline: none;
  box-shadow: 0 0 0.25em #e44e4f;
}

output[for='range'] {
  font-family: "Lucida Grande","Lucida Sans Unicode", Tahoma, Sans-Serif;
  font-size: 13px;
  color: white;
  display: block;
  text-align: center;
}
<div>
  <output for="range">0</output>
  <input type="range" value="0">
</div>
<div>
  <output for="range">0</output>
  <input type="range" value="0">
</div>
<div>
  <output for="range">0</output>
  <input type="range" value="0">
</div>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related