HTML5: Slider con due input possibili?


99

È possibile creare uno slider HTML5 con due valori di input, ad esempio per selezionare una fascia di prezzo? In caso affermativo, come si può fare?

Risposte:


64

No, l' input dell'intervallo HTML5 accetta solo un input. Ti consiglierei di utilizzare qualcosa come il cursore dell'intervallo dell'interfaccia utente jQuery per quell'attività.


Grazie per il collegamento e le informazioni. Devo controllare se riesco a farlo funzionare su dispositivi mobili.
frequente il

33
Qualche tempo fa ... ma sono riuscito a "simulare" un doppio cursore posizionando due cursori esattamente uno sopra l'altro. Uno a partire dal valore minimo, l'altro a partire dal valore massimo. Immagino sia un imbroglio ma ... per me funziona.
frequente

WhatWG sta almeno discutendo di implementarlo: html.spec.whatwg.org/multipage/…
kunambi

7
Mi piace ionRangeSlider un po 'meglio dello slider dell'interfaccia utente jQuery: ionden.com/a/plugins/ion.rangeSlider/en.html
Charlotte

4
Un altro approccio consiste nel "falsificare" il doppio cursore con controlli di input affiancati: simple.gy/blog/range-slider-two-handles
SimplGy

79

Ho cercato per un po 'di tempo un doppio cursore leggero e privo di dipendenze (sembrava folle importare jQuery solo per questo) e sembra che non ce ne siano molti là fuori. Ho finito per modificare un po ' il codice di @ Wildhoney e mi piace molto.


Purtroppo non funziona con il browser Android 4.0.4 Mobile Safari 4.0. :-(
erik

@erik Non ho davvero un buon modo per testare quelle versioni, ma funziona per me su Android 5.0 con l'ultima versione di Safari (che Google Play dice è 1.2, quindi sono confuso sulla tua 4.0). Se lo capisci, mi piacerebbe saperlo.
Gary

1
È davvero intelligente! Mi chiedo come mai non sia contrassegnata come la risposta corretta poiché risolve il problema con grazia senza alcun tipo di dipendenza. Aggiungere jQuery solo per farlo è ovviamente eccessivo.
zanona

@zanona Grazie ma la risposta corretta è stata contrassegnata 4 anni prima, quindi non credo che all'OP fosse importato molto per un'altra soluzione.
Gary

11
Mi piace molto il tuo approccio e ho provato ad adattarlo al mio caso d'uso, ma ho dovuto rinunciarci quando mi sono reso conto che alcune delle specifiche di progettazione che ho (es. Colorare la parte "attiva" della gamma in modo diverso rispetto al resto della traccia ) non è possibile implementare con questo. Quindi ho cercato un'altra soluzione e ho trovato questo progetto davvero carino: refreshless.com/nouislider È privo di dipendenze, ha un'API bella e pulita, è compatibile con AMD e offre molte opzioni. Finora sono abbastanza soddisfatto.
Felix Wienberg

37

In arrivo in ritardo, ma noUiSlider evita di avere una dipendenza jQuery-ui, cosa che la risposta accettata non fa. Il suo unico "avvertimento" è che il supporto di IE è per IE9 e versioni successive, se il vecchio IE è un problema per te.

È anche gratuito, open source e può essere utilizzato in progetti commerciali senza restrizioni.

Installazione: Scarica noUiSlider, estrai il file CSS e JS da qualche parte nel file system del tuo sito, quindi collega al CSS dall'head ea JS dal corpo:

<!-- In <head> -->
<link href="nouislider.min.css" rel="stylesheet">

<!-- In <body> -->
<script src="nouislider.min.js"></script>

Utilizzo di esempio: crea uno slider che va da 0 a 100 e inizia impostato su 20-80.

HTML:

<div id="slider">
</div>

JS:

var slider = document.getElementById('slider');

noUiSlider.create(slider, {
    start: [20, 80],
    connect: true,
    range: {
        'min': 0,
        'max': 100
    }
});

Wow fantastico!! Questo è esattamente ciò di cui avevamo bisogno ed è meravigliosamente sviluppato! WHITOUT jQuery
DavidTaubmann

Dovrebbe essere abbastanza facile aggiungerlo da soli e inviare una richiesta pull al progetto, però?
dario_ramos

3
Non ci ho approfondito, ma potrei usare lo slider con la tastiera, quindi penso che ora sia implementato @ptrin :)
Edu Ruiz

21

Sicuramente puoi semplicemente usare due cursori sovrapposti e aggiungere un po 'di javascript (in realtà non più di 5 righe) che i selettori non superano i valori min / max (come in @Garys) soluzione.

In allegato troverai un breve snippet adattato da un progetto corrente che include alcuni stili CSS3 per mostrare cosa puoi fare (solo webkit). Ho anche aggiunto alcune etichette per visualizzare i valori selezionati.

Usa JQuery ma una versione vanillajs non è magica.

    (function() {

        function addSeparator(nStr) {
            nStr += '';
            var x = nStr.split('.');
            var x1 = x[0];
            var x2 = x.length > 1 ? '.' + x[1] : '';
            var rgx = /(\d+)(\d{3})/;
            while (rgx.test(x1)) {
                x1 = x1.replace(rgx, '$1' + '.' + '$2');
            }
            return x1 + x2;
        }

        function rangeInputChangeEventHandler(e){
            var rangeGroup = $(this).attr('name'),
                minBtn = $(this).parent().children('.min'),
                maxBtn = $(this).parent().children('.max'),
                range_min = $(this).parent().children('.range_min'),
                range_max = $(this).parent().children('.range_max'),
                minVal = parseInt($(minBtn).val()),
                maxVal = parseInt($(maxBtn).val()),
                origin = $(this).context.className;

            if(origin === 'min' && minVal > maxVal-5){
                $(minBtn).val(maxVal-5);
            }
            var minVal = parseInt($(minBtn).val());
            $(range_min).html(addSeparator(minVal*1000) + ' €');


            if(origin === 'max' && maxVal-5 < minVal){
                $(maxBtn).val(5+ minVal);
            }
            var maxVal = parseInt($(maxBtn).val());
            $(range_max).html(addSeparator(maxVal*1000) + ' €');
        }

     $('input[type="range"]').on( 'input', rangeInputChangeEventHandler);
})();
body{
font-family: sans-serif;
font-size:14px;
}
input[type='range'] {
  width: 210px;
  height: 30px;
  overflow: hidden;
  cursor: pointer;
    outline: none;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
    background: none;
}
input[type='range']::-webkit-slider-runnable-track {
  width: 200px;
  height: 1px;
  background: #003D7C;
}

input[type='range']:nth-child(2)::-webkit-slider-runnable-track{
  background: none;
}

input[type='range']::-webkit-slider-thumb {
  position: relative;
  height: 15px;
  width: 15px;
  margin-top: -7px;
  background: #fff;
  border: 1px solid #003D7C;
  border-radius: 25px;
  z-index: 1;
}


input[type='range']:nth-child(1)::-webkit-slider-thumb{
  z-index: 2;
}

.rangeslider{
    position: relative;
    height: 60px;
    width: 210px;
    display: inline-block;
    margin-top: -5px;
    margin-left: 20px;
}
.rangeslider input{
    position: absolute;
}
.rangeslider{
    position: absolute;
}

.rangeslider span{
    position: absolute;
    margin-top: 30px;
    left: 0;
}

.rangeslider .right{
   position: relative;
   float: right;
   margin-right: -5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="rangeslider">
                                <input class="min" name="range_1" type="range" min="1" max="100" value="10" />
                                <input class="max" name="range_1" type="range" min="1" max="100" value="90" />
                                <span class="range_min light left">10.000 €</span>
                                <span class="range_max light right">90.000 €</span>
                            </div>


7
Hey sembra fantastico! ma non funziona in Firefox, puoi solo trascinare l'input massimo. Sei riuscito a risolverlo?
Toni Michel Caubet

5
Oddio. Sono venuto qui per aggiungere quasi esattamente la stessa cosa! simple.gy/blog/range-slider-two-handles La mia versione mette gli ingressi fianco a fianco, ma usa anche doppi ingressi.
SimplGy

5

In realtà ho usato direttamente il mio script in html. Ma in javascript quando aggiungi un listener di eventi in ingresso per questo evento, fornisce automaticamente i dati. Devi solo assegnare il valore secondo le tue esigenze.

[slider] {
  width: 300px;
  position: relative;
  height: 5px;
  margin: 45px 0 10px 0;
}

[slider] > div {
  position: absolute;
  left: 13px;
  right: 15px;
  height: 5px;
}
[slider] > div > [inverse-left] {
  position: absolute;
  left: 0;
  height: 5px;
  border-radius: 10px;
  background-color: #CCC;
  margin: 0 7px;
}

[slider] > div > [inverse-right] {
  position: absolute;
  right: 0;
  height: 5px;
  border-radius: 10px;
  background-color: #CCC;
  margin: 0 7px;
}


[slider] > div > [range] {
  position: absolute;
  left: 0;
  height: 5px;
  border-radius: 14px;
  background-color: #d02128;
}

[slider] > div > [thumb] {
  position: absolute;
  top: -7px;
  z-index: 2;
  height: 20px;
  width: 20px;
  text-align: left;
  margin-left: -11px;
  cursor: pointer;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4);
  background-color: #FFF;
  border-radius: 50%;
  outline: none;
}

[slider] > input[type=range] {
  position: absolute;
  pointer-events: none;
  -webkit-appearance: none;
  z-index: 3;
  height: 14px;
  top: -2px;
  width: 100%;
  opacity: 0;
}

div[slider] > input[type=range]:focus::-webkit-slider-runnable-track {
  background: transparent;
  border: transparent;
}

div[slider] > input[type=range]:focus {
  outline: none;
}

div[slider] > input[type=range]::-webkit-slider-thumb {
  pointer-events: all;
  width: 28px;
  height: 28px;
  border-radius: 0px;
  border: 0 none;
  background: red;
  -webkit-appearance: none;
}

div[slider] > input[type=range]::-ms-fill-lower {
  background: transparent;
  border: 0 none;
}

div[slider] > input[type=range]::-ms-fill-upper {
  background: transparent;
  border: 0 none;
}

div[slider] > input[type=range]::-ms-tooltip {
  display: none;
}

[slider] > div > [sign] {
  opacity: 0;
  position: absolute;
  margin-left: -11px;
  top: -39px;
  z-index:3;
  background-color: #d02128;
  color: #fff;
  width: 28px;
  height: 28px;
  border-radius: 28px;
  -webkit-border-radius: 28px;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
  text-align: center;
}

[slider] > div > [sign]:after {
  position: absolute;
  content: '';
  left: 0;
  border-radius: 16px;
  top: 19px;
  border-left: 14px solid transparent;
  border-right: 14px solid transparent;
  border-top-width: 16px;
  border-top-style: solid;
  border-top-color: #d02128;
}

[slider] > div > [sign] > span {
  font-size: 12px;
  font-weight: 700;
  line-height: 28px;
}

[slider]:hover > div > [sign] {
  opacity: 1;
}
<div slider id="slider-distance">
  <div>
    <div inverse-left style="width:70%;"></div>
    <div inverse-right style="width:70%;"></div>
    <div range style="left:0%;right:0%;"></div>
    <span thumb style="left:0%;"></span>
    <span thumb style="left:100%;"></span>
    <div sign style="left:0%;">
      <span id="value">0</span>
    </div>
    <div sign style="left:100%;">
      <span id="value">100</span>
    </div>
  </div>
  <input type="range" value="0" max="100" min="0" step="1" oninput="
  this.value=Math.min(this.value,this.parentNode.childNodes[5].value-1);
  let value = (this.value/parseInt(this.max))*100
  var children = this.parentNode.childNodes[1].childNodes;
  children[1].style.width=value+'%';
  children[5].style.left=value+'%';
  children[7].style.left=value+'%';children[11].style.left=value+'%';
  children[11].childNodes[1].innerHTML=this.value;" />

  <input type="range" value="100" max="100" min="0" step="1" oninput="
  this.value=Math.max(this.value,this.parentNode.childNodes[3].value-(-1));
  let value = (this.value/parseInt(this.max))*100
  var children = this.parentNode.childNodes[1].childNodes;
  children[3].style.width=(100-value)+'%';
  children[5].style.right=(100-value)+'%';
  children[9].style.left=value+'%';children[13].style.left=value+'%';
  children[13].childNodes[1].innerHTML=this.value;" />
</div>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.