HTML5: suwak z dwoma wejściami możliwy?

102

Czy można zrobić suwak HTML5 z dwiema wartościami wejściowymi, na przykład w celu wybrania przedziału cenowego? Jeśli tak, jak można to zrobić?

częsty
źródło

Odpowiedzi:

65

Nie, dane wejściowe z zakresu HTML5 przyjmują tylko jedno dane wejściowe. Zalecałbym użycie czegoś takiego jak suwak zakresu interfejsu użytkownika jQuery do tego zadania.

Martin Buberl
źródło
Dzięki za link i informacje. Muszę sprawdzić, czy mogę to uruchomić na urządzeniach mobilnych.
częste
34
Jakiś czas temu… ale udało mi się „sfałszować” podwójny suwak umieszczając dwa suwaki dokładnie jeden na drugim. Jeden zaczyna się od wartości minimalnej, a drugi od wartości maksymalnej. Myślę, że to oszustwo, ale ... na mnie działa.
częste
CoWG przynajmniej dyskutuje o jego wdrożeniu: html.spec.whatwg.org/multipage/ ...
kunambi
7
Osobiście lubię ionRangeSlider trochę lepiej niż suwak interfejsu użytkownika jQuery: ionden.com/a/plugins/ion.rangeSlider/en.html
Charlotte
4
Innym podejściem jest „sfałszowanie” podwójnego suwaka z bocznymi kontrolkami wprowadzania danych: simple.gy/blog/range-slider-two-handles
SimplGy
81

Od jakiegoś czasu szukałem lekkiego, wolnego od zależności podwójnego suwaka (importowanie jQuery tylko w tym celu wydawało się szalone) i wydaje się, że nie ma tam wielu. Skończyło się na tym, że trochę zmodyfikowałem kod @ Wildhoney i bardzo mi się to podoba.

Gary
źródło
Niestety nie działa z przeglądarką Android 4.0.4 Mobile Safari 4.0. :-(
erik
@erik Naprawdę nie mam dobrego sposobu na testowanie tych wersji, ale działa dla mnie na Androidzie 5.0 z najnowszą wersją Safari (która według Google Play to 1.2, więc jestem zdezorientowany co do twojego 4.0). Jeśli to wymyślisz, chciałbym wiedzieć.
Gary,
1
To naprawdę sprytne! Zastanawiam się, dlaczego nie jest oznaczona jako poprawna odpowiedź, ponieważ rozwiązuje problem z wdziękiem bez żadnej zależności. Dodanie jQuery tylko w tym celu jest oczywiście przesadą.
zanona
@zanona Dzięki, ale poprawna odpowiedź została zaznaczona 4 lata wcześniej, więc nie sądzę, by OP zależało zbytnio na innym rozwiązaniu.
Gary
12
Bardzo podoba mi się twoje podejście i próbowałem dostosować je do mojego przypadku użycia, ale musiałem z niego zrezygnować, gdy zdałem sobie sprawę, że niektóre specyfikacje projektowe, które mam (np. Kolorowanie "aktywnej" części zakresu inaczej niż reszta toru ) nie są możliwe do wykonania z tym. Szukałem więc innego rozwiązania i znalazłem ten naprawdę fajny projekt: refreshless.com/nouislider Jest wolny od zależności, ma ładne i czyste API, jest kompatybilny z AMD i oferuje wiele opcji. Jak dotąd jestem z tego całkiem zadowolony.
Felix Wienberg
38

Spóźnianie się , ale noUiSlider unika zależności jQuery-ui, czego nie ma zaakceptowana odpowiedź. Jedynym „zastrzeżeniem” jest obsługa IE dla IE9 i nowszych, jeśli starsza wersja IE jest dla Ciebie rozwiązaniem.

Jest również darmowy, open source i może być używany w projektach komercyjnych bez ograniczeń.

Instalacja: Pobierz noUiSlider, wyodrębnij plik CSS i JS gdzieś w systemie plików witryny, a następnie połącz z CSS z nagłówka i do JS z treści:

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

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

Przykładowe użycie: tworzy suwak, który przesuwa się od 0 do 100 i zaczyna od wartości 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
    }
});
dario_ramos
źródło
Wow niesamowite!! To jest dokładnie to, czego potrzebowaliśmy i jest wspaniale opracowane! WHITOUT jQuery
DavidTaubmann
Jednak powinno być dość łatwo dodać to samodzielnie i wysłać żądanie ściągnięcia do projektu?
dario_ramos
3
Nie zagłębiłem się w to, ale mogłem użyć suwaka z klawiaturą, więc myślę, że jest teraz zaimplementowany @ptrin :)
Edu Ruiz
21

Oczywiście możesz po prostu użyć dwóch suwaków nakładających się na siebie i dodać trochę javascript (właściwie nie więcej niż 5 linii), że selektory nie przekraczają wartości min / max (jak w rozwiązaniu @Garys).

W załączeniu znajdziesz krótki fragment zaadaptowany z aktualnego projektu, w tym styl CSS3, pokazujący, co możesz zrobić (tylko webkit). Dodałem również kilka etykiet, aby wyświetlić wybrane wartości.

Używa JQuery, ale wersja vanillajs nie jest magiczna.

    (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
źródło
7
Hej, wygląda świetnie! ale to nie działa w Firefoksie, możesz tylko przeciągnąć maksymalne wejście. Czy udało ci się to naprawić?
Toni Michel Caubet
5
O stary. Przyszedłem tutaj, aby dodać prawie dokładnie to samo! simple.gy/blog/range-slider-two-handles Moja wersja umieszcza wejścia obok siebie, ale także używa podwójnych wejść.
SimplGy
6

Właściwie użyłem mojego skryptu bezpośrednio w html. Ale w javascript, kiedy dodajesz detektor zdarzeń oninput dla tego zdarzenia, dane są przekazywane automatycznie. Wystarczy przypisać wartość zgodnie z wymaganiami.

[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
źródło