HTML5: Slider mit zwei Eingängen möglich?

98

Ist es möglich, einen HTML5-Schieberegler mit zwei Eingabewerten zu erstellen, um beispielsweise eine Preisspanne auszuwählen? Wenn ja, wie geht das?

häufig
quelle

Antworten:

63

Nein, die HTML5-Bereichseingabe akzeptiert nur eine Eingabe. Ich würde Ihnen empfehlen, für diese Aufgabe so etwas wie den Schieberegler für den jQuery-UI-Bereich zu verwenden.

Martin Buberl
quelle
Danke für den Link und die Infos. Ich muss prüfen, ob ich dies auf Mobilgeräten ausführen kann.
häufig
32
Vor einiger Zeit ... aber ich habe es geschafft, einen doppelten Schieberegler zu "fälschen", indem ich zwei Schieberegler genau übereinander platziert habe. Einer beginnt beim Min-Wert, der andere beim Max-Wert. Ich denke, das ist Betrug, aber ... es funktioniert für mich.
häufig
WhatWG diskutiert zumindest die Implementierung: html.spec.whatwg.org/multipage/…
Kunambi
7
Ich mag ionRangeSlider ein bisschen besser als den jQuery UI Slider selbst: ionden.com/a/plugins/ion.rangeSlider/en.html
Charlotte
4
Ein anderer Ansatz besteht darin, den Doppelschieberegler mit nebeneinander angeordneten Eingabesteuerelementen zu "fälschen": simple.gy/blog/range-slider-two-handles
SimplGy
78

Ich habe seit einiger Zeit nach einem leichten, abhängigkeitsfreien Dual-Slider gesucht (es schien verrückt, jQuery nur dafür zu importieren), und es scheint nicht viele zu geben. Am Ende habe ich den Code von @ Wildhoney ein wenig geändert und mag ihn wirklich.

Gary
quelle
Leider funktioniert es nicht mit Android 4.0.4 Mobile Safari 4.0 Browser. :-(
erik
@erik Ich habe keine gute Möglichkeit, diese Versionen zu testen, aber es funktioniert für mich unter Android 5.0 mit der neuesten Version von Safari (laut Google Play ist es 1.2, also bin ich verwirrt über Ihre 4.0). Wenn Sie es herausfinden, würde ich gerne wissen.
Gary
1
Das ist wirklich klug! Ich frage mich, warum es nicht als die richtige Antwort markiert ist, da es das Problem ohne jegliche Abhängigkeit elegant löst. Das Hinzufügen von jQuery, um dies zu tun, ist offensichtlich übertrieben.
Zanona
@zanona Danke, aber die richtige Antwort wurde 4 Jahre zuvor markiert, daher denke ich, dass das OP sich nicht viel für eine andere Lösung interessierte.
Gary
11
Ich mag Ihren Ansatz sehr und habe versucht, ihn an meinen Anwendungsfall anzupassen, musste ihn aber aufgeben, als mir klar wurde, dass einige meiner Designspezifikationen (z. B. den "aktiven" Teil des Bereichs anders färben als den Rest der Strecke) ) sind damit nicht umsetzbar. Also suchte ich nach einer anderen Lösung und fand dieses wirklich nette Projekt: refresheshless.com/nouislider Es ist abhängigkeitsfrei, hat eine schöne und saubere API, ist AMD-kompatibel und bietet viele Optionen. Bisher bin ich ziemlich zufrieden damit.
Felix Wienberg
37

Kommt zu spät, aber noUiSlider vermeidet eine jQuery-ui-Abhängigkeit, was die akzeptierte Antwort nicht tut. Die einzige "Einschränkung" ist, dass die IE-Unterstützung für IE9 und neuer ist, wenn der ältere IE ein Deal Breaker für Sie ist.

Es ist auch kostenlos, Open Source und kann ohne Einschränkungen in kommerziellen Projekten verwendet werden.

Installation: Laden Sie noUiSlider herunter, extrahieren Sie die CSS- und JS-Datei irgendwo in Ihrem Site-Dateisystem und verknüpfen Sie das CSS von head und das JS von body:

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

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

Anwendungsbeispiel: Erstellt einen Schieberegler, der von 0 bis 100 reicht und auf 20-80 eingestellt ist.

HTML:

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

JS:

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

noUiSlider.create(slider, {
    start: [20, 80],
    connect: true,
    range: {
        'min': 0,
        'max': 100
    }
});
dario_ramos
quelle
Wow, großartig!! Genau das haben wir gebraucht und es ist wunderbar entwickelt! WHITOUT jQuery
DavidTaubmann
Es sollte jedoch ziemlich einfach sein, dies selbst hinzuzufügen und eine Pull-Anfrage an das Projekt zu senden.
dario_ramos
3
Ich habe mich nicht damit beschäftigt, aber ich könnte den Schieberegler mit der Tastatur verwenden, also denke ich, dass er jetzt @ptrin implementiert ist :)
Edu Ruiz
21

Natürlich können Sie einfach zwei Schieberegler verwenden, die sich überlagern, und ein bisschen Javascript hinzufügen (eigentlich nicht mehr als 5 Zeilen), damit die Selektoren die Min / Max-Werte (wie in @ Garys) nicht überschreiten.

Im Anhang finden Sie einen kurzen Ausschnitt aus einem aktuellen Projekt, der einige CSS3-Stile enthält, um zu zeigen, was Sie tun können (nur Webkit). Ich habe auch einige Beschriftungen hinzugefügt, um die ausgewählten Werte anzuzeigen.

Es verwendet JQuery, aber eine Vanillajs-Version ist keine Magie.

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

user1532132
quelle
7
Hey sieht gut aus! In Firefox funktioniert dies jedoch nicht. Sie können nur die maximale Eingabe ziehen. Haben Sie es geschafft, das Problem zu beheben?
Toni Michel Caubet
5
Oh Mann. Ich bin hergekommen, um fast genau das Gleiche hinzuzufügen! simple.gy/blog/range-slider-two-handles Meine Version stellt die Eingänge nebeneinander, verwendet aber auch zwei Eingänge.
Einfach
5

Eigentlich habe ich mein Skript direkt in HTML verwendet. Wenn Sie jedoch in Javascript einen Eingabe-Ereignis-Listener für dieses Ereignis hinzufügen, werden die Daten automatisch angezeigt. Sie müssen nur den Wert gemäß Ihren Anforderungen zuweisen.

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

Himabindu
quelle