HTML5: Có thể có thanh trượt với hai đầu vào?


99

Có thể tạo thanh trượt HTML5 với hai giá trị đầu vào, chẳng hạn để chọn phạm vi giá không? Nếu vậy, nó có thể được thực hiện như thế nào?

Câu trả lời:


64

Không, đầu vào phạm vi HTML5 chỉ chấp nhận một đầu vào. Tôi khuyên bạn nên sử dụng thứ gì đó như thanh trượt phạm vi giao diện người dùng jQuery cho tác vụ đó.


Cảm ơn vì liên kết và thông tin. Tôi phải kiểm tra xem tôi có thể chạy ứng dụng này trên thiết bị di động hay không.
thường xuyên

33
Cách đây một thời gian ... nhưng tôi đã cố gắng "giả" một thanh trượt đôi bằng cách đặt chính xác hai thanh trượt chồng lên nhau. Một cái bắt đầu ở giá trị tối thiểu, cái kia bắt đầu ở giá trị tối đa. Tôi đoán đó là gian lận nhưng ... nó hiệu quả với tôi.
thường xuyên

WhatWG ít nhất đang thảo luận về việc triển khai nó: html.spec.whatwg.org/multipage/…
kunambi

7
Tôi thích ionRangeSlider hơn một chút so với thanh trượt giao diện người dùng jQuery: ionden.com/a/plugins/ion.rangeSlider/en.html
Charlotte

4
Một cách tiếp cận khác là "giả mạo" thanh trượt đôi với các điều khiển đầu vào cạnh nhau: simple.gy/blog/range-slider-two-handles
SimplGy

79

Tôi đã tìm kiếm một thanh trượt kép nhẹ, không phụ thuộc trong một thời gian (có vẻ điên rồ khi nhập jQuery chỉ cho điều này) và dường như không có nhiều ở đó. Tôi đã sửa đổi mã của @ Wildhoney một chút và thực sự thích nó.


Thật không may, nó không hoạt động với trình duyệt Android 4.0.4 Mobile Safari 4.0. :-(
erik

@erik Tôi không thực sự có cách tốt để kiểm tra các phiên bản đó, nhưng nó hoạt động với tôi trên Android 5.0 với phiên bản Safari mới nhất (mà google play nói là 1.2, vì vậy tôi bối rối về 4.0 của bạn). Nếu bạn hiểu ra, tôi rất muốn biết.
Gary

1
Thật là thông minh! Tôi tự hỏi làm thế nào nó không được đánh dấu là câu trả lời đúng vì nó giải quyết vấn đề một cách duyên dáng mà không có bất kỳ loại phụ thuộc nào. Thêm jQuery chỉ để làm điều đó rõ ràng là quá mức cần thiết.
zanona

@zanona Cảm ơn nhưng câu trả lời chính xác đã được đánh dấu 4 năm trước, vì vậy tôi không nghĩ OP quan tâm nhiều đến giải pháp khác.
Gary

11
Tôi thực sự thích cách tiếp cận của bạn và đã cố gắng điều chỉnh nó cho phù hợp với trường hợp sử dụng của tôi nhưng phải từ bỏ nó khi tôi nhận ra rằng một số thông số kỹ thuật thiết kế mà tôi có (ví dụ: tô màu phần "hoạt động" của dải ô khác với phần còn lại của bản nhạc ) không thể thực hiện với điều này. Vì vậy, tôi đã tìm kiếm một giải pháp khác và nhận thấy dự án thực sự gọn gàng này: refreshless.com/nouislider Nó không phụ thuộc, có API đẹp và sạch, tương thích với AMD và cung cấp rất nhiều tùy chọn. Cho đến nay tôi khá hài lòng với nó.
Felix Wienberg

37

Đến muộn, nhưng noUiSlider tránh có phụ thuộc jQuery-ui, mà câu trả lời được chấp nhận thì không. "Cảnh báo" duy nhất của nó là hỗ trợ IE dành cho IE9 và mới hơn, nếu IE cũ là một công cụ phá vỡ thỏa thuận cho bạn.

Nó cũng miễn phí, mã nguồn mở và có thể được sử dụng trong các dự án thương mại mà không bị hạn chế.

Cài đặt: Tải xuống noUiSlider, giải nén tệp CSS và JS ở đâu đó trong hệ thống tệp trang web của bạn, sau đó liên kết đến CSS từ head và tới JS từ body:

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

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

Cách sử dụng ví dụ: Tạo một thanh trượt từ 0 đến 100 và bắt đầu được đặt thành 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, tuyệt vời !! Đây chính xác là những gì chúng tôi cần và nó được phát triển một cách tuyệt vời! WHITOUT jQuery
DavidTaubmann

Tuy nhiên, sẽ khá dễ dàng để thêm chính bạn và gửi một yêu cầu kéo đến dự án?
dario_ramos

3
Tôi không tìm hiểu kỹ về nó, nhưng tôi có thể sử dụng thanh trượt với bàn phím, vì vậy tôi nghĩ rằng nó đã được triển khai ngay bây giờ @ptrin :)
Edu Ruiz

21

Chắc chắn bạn có thể chỉ cần sử dụng hai thanh trượt chồng lên nhau và thêm một chút javascript (thực tế không quá 5 dòng) mà các bộ chọn không vượt quá giá trị tối thiểu / tối đa (như trong giải pháp @Garys).

Đính kèm, bạn sẽ tìm thấy một đoạn mã ngắn được điều chỉnh từ một dự án hiện tại bao gồm một số kiểu CSS3 để hiển thị những gì bạn có thể làm (chỉ dành cho webkit). Tôi cũng đã thêm một số nhãn để hiển thị các giá trị đã chọn.

Nó sử dụng JQuery nhưng một phiên bản vanijs không có gì kỳ diệu.

    (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
Này có vẻ tuyệt vời! nhưng nó không hoạt động trong Firefox, bạn chỉ có thể kéo đầu vào tối đa. Bạn đã quản lý để sửa chữa nó?
Toni Michel Caubet

5
Trời ơi. Tôi đến đây để thêm gần như chính xác điều tương tự! simple.gy/blog/range-slider-two-handles Phiên bản của tôi đặt các đầu vào cạnh nhau, nhưng cũng sử dụng các đầu vào kép.
SimplGy

5

Trên thực tế, tôi đã sử dụng trực tiếp tập lệnh của mình trong html. Nhưng trong javascript khi bạn thêm trình xử lý sự kiện oninput cho sự kiện này, nó sẽ tự động cung cấp dữ liệu. Bạn chỉ cần gán giá trị theo yêu cầu của mình.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.