Création d'un curseur de plage de valeurs pour un filtre sans utiliser jQuery

Très souvent sur les sites Web des boutiques en ligne, et pas seulement, vous pouvez filtrer avec un curseur pour sélectionner une plage de valeurs. Dans l'un des projets, j'avais également besoin de faire un tel curseur.


La première chose qui vous vient à l'esprit est d'en trouver une toute faite et de la coller sur votre site. Ensuite, j'ai rencontré un problème. Le plugin JqueryUI.slider que j'ai trouvé a refusé de fonctionner sur certains appareils mobiles. Je n'ai pas pu identifier le problème (mais pas vraiment, et je voulais fouiller dans le code de quelqu'un d'autre) et j'ai décidé de faire mon propre "vélo".


J'ai décidé de faire du "vélo" en JavaScript pur pour ne pas gâcher les librairies. Comme le dit un de mes amis: "moins il y a de connexions" à gauche ", plus tout fonctionne stable."


Par conséquent, la première chose que j'ai faite a été de créer un modèle aussi simple


<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> 

À l'écran, cela ressemble à ceci

Le curseur avec les curseurs lui-même est dans un bloc avec la classe "slider" dans lequel il y a 2 autres blocs: le curseur de valeur minimale et le curseur de valeur de plage maximale.
Ils décrivent deux événements:


  1. onMouseDown - déclenché lorsque nous saisissons le curseur avec la souris;
  2. onTouchStart - fonctionne sur les appareils mobiles lorsque vous touchez votre doigt sur notre curseur.

Au-dessus du curseur se trouve un bloc avec deux nombres - ce sont nos valeurs maximales et minimales.


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

Passons maintenant à la fonction elle-même, qui est appelée au clic.


 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; } 

La fonction getCoords nous permet d'obtenir les coordonnées et les tailles de nos éléments.
Il ressemble à ceci.


 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 //  } } 

Nous décrivons maintenant les fonctions du gestionnaire.
La première fonction est onMouseMove, qui est appelée lorsque la souris se déplace. Cela ne fonctionnera qu'avec un mouvement horizontal.


 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"; } } 

Et enfin, la fonction de gestionnaire de l'événement «bouton de déverrouillage» ou perte de point de contact sur les appareils mobiles. Il supprime tous les événements ajoutés précédemment et laisse le curseur à la valeur définie.


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

Et, bien sûr, les styles CSS pour notre curseur


 .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%; } 

Voir la version de travail de ce curseur ici .


Tous les fichiers peuvent être téléchargés depuis GitHub .


Utilisation agréable et travail facile!

Source: https://habr.com/ru/post/fr466623/


All Articles