HTML5 : 두 개의 입력이 가능한 슬라이더?


102

예를 들어 가격 범위를 선택하기 위해 두 개의 입력 값으로 HTML5 슬라이더를 만들 수 있습니까? 그렇다면 어떻게 할 수 있습니까?

답변:


65

아니요, HTML5 범위 입력 은 하나의 입력 만 허용합니다. 해당 작업에 jQuery UI 범위 슬라이더 와 같은 것을 사용하는 것이 좋습니다 .


링크와 정보에 감사드립니다. 모바일 장치에서 실행할 수 있는지 확인해야합니다.
빈번한

34
얼마 전에 ...하지만 두 개의 슬라이더를 정확히 서로 위에 배치하여 이중 슬라이더를 "가짜"할 수있었습니다. 하나는 최소값에서 시작하고 다른 하나는 최대 값에서 시작합니다. 속임수 인 것 같지만 ...
빈번한

: 논의를 구현 적어도 WHATWG는 html.spec.whatwg.org/multipage/...
kunambi

7
나는 ionRangeSlider를 jQuery UI 슬라이더보다 조금 더 좋아합니다. ionden.com/a/plugins/ion.rangeSlider/en.html
Charlotte

4
또 다른 접근 방식은 병렬 입력 컨트롤을 사용하여 이중 슬라이더를 "가짜"하는 것입니다. simple.gy/blog/range-slider-two-handles
SimplGy

81

나는 한동안 가볍고 의존성이없는 듀얼 슬라이더를 찾고 있었는데 (이를 위해 jQuery를 가져 오는 것은 미친 것처럼 보였지만) 거기에는 많지 않은 것 같습니다. 결국 @Wildhoney의 코드 를 약간 수정 하고 정말 좋아했습니다.


안타깝게도 Android 4.0.4 Mobile Safari 4.0 브라우저에서는 작동하지 않습니다. :-(
erik

@erik 나는 그 버전을 테스트하는 좋은 방법이 없지만 최신 버전의 Safari가 설치된 Android 5.0에서 작동합니다 (구글 플레이에서 1.2라고 말 했으므로 4.0에 대해 혼란 스럽습니다). 당신이 그것을 이해한다면, 나는 알고 싶습니다.
Gary

1
정말 영리합니다! 어떤 종류의 의존도없이 우아하게 문제를 해결하기 때문에 어떻게 정답으로 표시되지 않는지 궁금합니다. 이를 위해 jQuery를 추가하는 것은 분명히 과잉입니다.
zanona

@zanona 감사하지만 정답은 4 년 전에 표시되었으므로 OP가 다른 솔루션을 많이 신경 쓰지 않았다고 생각합니다.
Gary

12
나는 당신의 접근 방식을 정말 좋아하고 그것을 내 사용 사례에 적용하려고 노력했지만 내가 가진 일부 디자인 사양 (예 : 범위의 "활성"부분을 나머지 트랙과 다르게 채색하는 것을 깨달았을 때 포기해야했습니다. )는이를 구현할 수 없습니다. 그래서 저는 다른 솔루션을 찾고 정말 깔끔한 프로젝트를 찾았습니다. refreshless.com/nouislider 의존성이없고 멋지고 깨끗한 API를 가지고 있으며 AMD와 호환되며 많은 옵션을 제공합니다. 지금까지 나는 그것에 아주 만족합니다.
Felix Wienberg 2016 년

38

늦었지만 noUiSlider 는 허용 된 답변이 아닌 jQuery-ui 종속성을 피합니다. 유일한 "주의 사항"은 IE 지원이 IE9 이상에 대한 것입니다. 만약 레거시 IE가 당신을위한 거래 중단 자라면.

또한 무료 오픈 소스이며 제한없이 상용 프로젝트에 사용할 수 있습니다.

설치 : noUiSlider를 다운로드하고 사이트 파일 시스템 어딘가에 CSS 및 JS 파일을 추출한 다음 헤드에서 CSS로, 본문에서 JS로 링크합니다.

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

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

사용 예 : 0에서 100까지의 슬라이더를 만들고 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
    }
});

와우, 대단해 !! 이것이 바로 우리가 필요로하는 것이며 훌륭하게 개발되었습니다! WHITOUT jQuery를
DavidTaubmann

직접 추가하고 프로젝트에 풀 리퀘스트를 보내는 것은 꽤 쉬울 것입니다.
dario_ramos

3
나는 그것을 파헤 치지 않았지만 키보드와 함께 슬라이더를 사용할 수 있었으므로 지금 구현되었다고 생각합니다 @ptrin :)
Edu Ruiz 19

21

물론 서로 겹치는 두 개의 슬라이더를 사용하고 선택기가 최소 / 최대 값 (예 : @Garys) 솔루션을 초과하지 않는 약간의 자바 스크립트 (실제로 5 줄 이하)를 추가 할 수 있습니다.

첨부 된 당신은 당신이 무엇을 할 수 있는지 보여주는 CSS3 스타일을 포함하여 현재 프로젝트에서 수정 된 짧은 스 니펫을 찾을 수있을 것입니다 (웹킷에만 해당). 또한 선택한 값을 표시하기 위해 몇 가지 레이블을 추가했습니다.

JQuery를 사용하지만 vanillajs 버전은 마법이 아닙니다.

    (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
안녕하세요! 그러나 Firefox에서는 작동하지 않으며 최대 입력 만 드래그 할 수 있습니다. 당신은 그것을 고칠 수 있었습니까?
Toni Michel Caubet

5
오 이런. 나는 거의 똑같은 것을 추가하기 위해 여기에 왔습니다! simple.gy/blog/range-slider-two-handles 내 버전은 입력을 나란히 배치하지만 이중 입력도 사용합니다.
SimplGy

6

사실 저는 HTML로 직접 스크립트를 사용했습니다. 그러나 자바 스크립트에서이 이벤트에 대한 oninput 이벤트 리스너를 추가하면 데이터가 자동으로 제공됩니다. 요구 사항에 따라 값을 할당하면됩니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.