Creating a range of values ​​slider for a filter without using jQuery

Very often on the sites of online stores, and not only, you can filters with a slider to select a range of values. In one of the projects, I also needed to make such a slider.







The first thing that comes to mind is to find a ready-made one and paste it on your site. Then I ran into a problem. The JqueryUI.slider plugin I found refused to work on some mobile devices. I could not identify the problem (but not really, and wanted to poke around in someone else's code) and decided to make my own "bike".







I decided to do the "bike" in pure JavaScript so as not to mess with libraries. As one friend of mine says: "the less" left "connections, the more stable everything works."







Therefore, the first thing I did was make up such a simple model







<div class="filter"> <div> <span> 1</span> <div><number>10</number><number>50</number></div> <div class="slider"> <div class="block-min" onMouseDown="moveRange(this)" onTouchStart="moveRange(this)"></div> <div class="color-range"></div> <div class="block-max" onMouseDown="moveRange(this)" onTouchStart="moveRange(this)"></div> </div> </div> <div> <span> 2</span> <div><number>0</number><number>5</number></div> <div class="slider"> <div class="block-min" onMouseDown="moveRange(this)" onTouchStart="moveRange(this)"></div> <div class="color-range"></div> <div class="block-max" onMouseDown="moveRange(this)" onTouchStart="moveRange(this)"></div> </div> </div> </div>
      
      





On the screen it looks like this



The slider with sliders itself is in a block with the "slider" class in which there are 2 more blocks: the minimum value slider and the maximum range value slider.

They describe two events:







  1. onMouseDown - triggered when we grab the slider with the mouse;
  2. onTouchStart - works on mobile devices, when you touch your finger on our slider.


Above the slider is a block with two numbers - this is our maximum and minimum values.







 <div><number>0</number><number>5</number></div>
      
      





Now let's move on to the function itself, which is called upon click.







 function moveRange (elem) { //      var coords = getCoords(elem); /*  */ var colorRange = elem.parentElement.children[1]; var f;//        var value; //  /*    */ var parent = {} parent.element = elem.parentElement; parent.coords = getCoords(parent.element); var block2 = {} if (elem.classList.contains('block-min')) { block2.element = elem.parentElement.children[2]; block2.coords = getCoords(block2.element); f=0; } else { block2.element = elem.parentElement.children[0]; block2.coords = getCoords(block2.element); f=1; } /*     */ var indicator = document.createElement('div'); if (elem.children.length){ elem.innerHTML = '';//   } elem.append(indicator); document.addEventListener('mousemove', onMouseMove);// -     document.addEventListener('mouseup', onMouseUp);// -      document.addEventListener('touchmove', onMouseMove);//   ,     document.addEventListener('touchend', onMouseUp); /*   DaD*/ elem.ondragstart = function(){ return false; }
      
      





The getCoords function allows us to get the coordinates and sizes of our elements.

It looks as follows.







 function getCoords(elem) { /*    */ let coords = elem.getBoundingClientRect(); /*    ,   */ return {// ,  : top : coords.top + window.pageYOffset, //     left : coords.left + window.pageXOffset, //      leftX: coords.left, //    rigth : coords.left + window.pageXOffset + coords.width, //   bottom : coords.top + window.pageYOffset + coords.height, //  width : coords.width //  } }
      
      





Now we describe the handler functions.

The first function is onMouseMove, which is called when the mouse moves. It will work out only with horizontal movement.







 function onMouseMove(e) { /*  */ e.preventDefault();//    /*      */ /*       ,    targetTouches*/ /*         targetTouches[0]*/ if (e.touches === undefined) { var pos = e.clientX; } else { var pos = e.targetTouches[0].clientX; } /*   */ let newLeft = pos - parent.coords.leftX; let rigthEdge = parent.coords.width - (coords.width+1); if (newLeft<0) { newLeft = 0; } else if (newLeft > rigthEdge) { newLeft = rigthEdge; } if (f == 0 && pos > block2.coords.left-block2.coords.width) { newLeft = block2.coords.left - block2.coords.width - 5 - parent.coords.leftX; }else if (f == 1 && pos < block2.coords.rigth + 5) { newLeft = block2.coords.rigth + 5 - parent.coords.leftX; } /*   */ elem.style.left = newLeft + 'px'; //    let rangeMin = +document.querySelector('.filter number:first-child').innerHTML; let rangeMax = +document.querySelector('.filter number:last-child').innerHTML; if(f==0){ value = (newLeft / (parent.coords.width / (rangeMax - rangeMin)) + rangeMin).toFixed(1); } else { value = (newLeft / (parent.coords.width / (rangeMax - rangeMin))+ 0.3 + rangeMin).toFixed(1); } /*   */ indicator.style.position = 'absolute'; indicator.style.fontSize = "14px"; indicator.style.left = - coords.width/2 + "px"; indicator.style.top = parseFloat(window.getComputedStyle(elem).getPropertyValue('top')) - 10 +"px"; /*          */ if (newLeft <= 0){ indicator.innerHTML= ""; } else if (newLeft >= rigthEdge) { indicator.innerHTML= ""; } else { indicator.innerHTML = value; } /*    */ if (f == 0) { colorRange.style.left = newLeft + coords.width + "px"; colorRange.style.width = block2.coords.left - getCoords(elem).left - coords.width + "px"; } else { colorRange.style.left = block2.coords.left - parent.coords.leftX + "px"; colorRange.style.width = getCoords(elem).left - block2.coords.left + "px"; } }
      
      





And finally, the handler function of the “release button” event or loss of touch point on mobile devices. It deletes all previously added events and leaves the slider at the set value.







 function onMouseUp() { document.removeEventListener('mouseup', onMouseUp); document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('touchend', onMouseUp); document.removeEventListener('touchmove', onMouseMove); }
      
      





And, of course, CSS styles for our slider







 .filter { padding: 30px; width: 500px; } .filter>div { padding-top: 20px; display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: -o-flex; display: flex; -webkit-flex-direction: column; -moz-flex-direction: column; -ms-flex-direction: column; -o-flex-direction: column; flex-direction: column; } .filter>div>div { display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: -o-flex; display: flex; justify-content: space-between; } .filter .slider { margin-top: 10px; position: relative; height: 6px; background: #fff; border: 1px solid #000; } .filter .color-range { position: absolute; background: #a4a4a4; width: 97%; border: none; height: 6px; left: 15px; } .filter .block-min, .block-max { width: 15px; height: 25px; position: absolute; left: 0; top: -11.5px; background: #fff; border: 1px solid #000; border-radius: 4px; z-index: 1; } .filter .block-max{ left: 97%; }
      
      





View the working version of this slider here .







All files can be downloaded from GitHub .







Enjoyable use and easy work!








All Articles