Несколько ползунка ввода с диапазонами на одной странице - PullRequest
0 голосов
/ 18 марта 2020

У меня есть этот ползунок ввода формы с маркерами и словами для каждого шага, но когда я добавляю другие диапазоны на той же странице, маркеры складываются слева.

Или, возможно, есть способ добавить отзывчивый видимый более простые шаги для ползунков ...

Ссылка на кодовое перо:

https://codepen.io/jvelezr/pen/poJKNro

HTML:

<div class="tone-option">
    <div class="slider-titles">
        <div class="label-slider">
            <label>Individual</label>
        </div>
        <div class="label-slider">
            <lable>Grupal</lable>
        </div>
    </div>
    <input type="range" class="tone-input" id="step-slider" min="-30" max="30" step="10" value="0"
           aria-describedby="month-desc">
    <div class="slider-tickmarks" aria-hidden="true">
        <label data-step="1">mucho</label>
        <label data-step="2">bastante</label>
        <label data-step="3">un poco</label>
        <label data-step="4">neutro</label>
        <label data-step="5">un poco</label>
        <label data-step="6">bastante</label>
        <label data-step="7">mucho</label>
    </div>
</div>

JS:

// Polyfill for IE11
if (window.NodeList && !NodeList.prototype.forEach) {
    NodeList.prototype.forEach = function (callback, thisArg) {
        thisArg = thisArg || window;
        for (var i = 0; i < this.length; i++) {
            callback.call(thisArg, this[i], i, this);
        }
    };
}

var step_slider = document.querySelector('.tone-input');
var step_slider_alt = document.querySelector('.tone-input-alt');
var floating_value = document.querySelector('.slider-value-floating');

// calculate the width of a step
var thumbWidth = 20;
var left = step_slider.offsetLeft;
var width = step_slider.offsetWidth;
var min = parseInt(step_slider.getAttribute("min"), 10);
var max = parseInt(step_slider.getAttribute("max"), 10);
var step = parseInt(step_slider.getAttribute("step"), 10);
var numberOfStops = ((max - min) / step) + 1;

// this is the width "between steps"
// because graphically each step has the width of the thumb
var adjustedStepWidth = (width - (thumbWidth * numberOfStops)) / (numberOfStops - 1);

// Calculate the position of a step tickmark given a slider value
var getTickmarkPosition = function(value) {
    var valueIndex = ((value - min) / step);
    return Math.round(left + (adjustedStepWidth + thumbWidth) * valueIndex + thumbWidth/2);
}

// Move the floating bubble to follow the thumb
var updateFloatingValuePosition = function() {
    floating_value.style.left = getTickmarkPosition(step_slider.value) - (floating_value.offsetWidth / 2) + 'px';
}

// Draw the tickmarks and position the labels
var drawTickmarks = function() {
    var tickmarksList = document.querySelector('.slider-tickmarks');

    // Create a <span> for each stop
    if(tickmarksList.querySelectorAll('span').length == 0) {
        for(var i = 0; i < numberOfStops; i++) {
            tickmark = document.createElement('span');
            tickmarksList.appendChild(tickmark);
        }
    }

    // Position each span according to its index
    tickmarksList.querySelectorAll('span').forEach(function(el, i) {
        el.style.left = getTickmarkPosition(min + step * i) + 'px';
    });

    // Position the min/max labels
    tickmarksList.querySelectorAll('label').forEach(function(el) {
        var i = parseInt(el.getAttribute('data-step'), 10) - 1;
        el.style.left = getTickmarkPosition(min + step * i) + 'px';

        // optional - a nice UI touch would be to add an event handler
        // on each tick to move the slider there
        // (it is not necessary or suggested to make this keyboard focusable
        // as it is doable within the slider already and would add tab stops)
        el.addEventListener("click", function(e) {
            step_slider.value = step_slider_alt.value = min + step * i;
            updateFloatingValuePosition();
        });
    });
};

// Call these on the first draw
drawTickmarks();
updateFloatingValuePosition();


step_slider.addEventListener("input", function(e) {
    step_slider_alt.value = step_slider.value;
    updateFloatingValuePosition();
});

// IE only fires a "change" event for sliders
step_slider.addEventListener("change", function(e) {
    step_slider_alt.value = step_slider.value;
    updateFloatingValuePosition();
});

// Updating the text field updates the slider too
step_slider_alt.addEventListener("change", function(e) {
    step_slider.value = step_slider_alt.value;
    updateFloatingValuePosition();
});

// Update position of elements if viewport is resized
window.addEventListener("resize", function() {
    left = step_slider.offsetLeft;
    width = step_slider.offsetWidth;
    adjustedStepWidth = (width - (thumbWidth * numberOfStops)) / (numberOfStops - 1)

    drawTickmarks();
    updateFloatingValuePosition();
});

var rangeSlider = document.getElementById("rs-range-line");
var rangeBullet = document.getElementById("rs-bullet");

rangeSlider.addEventListener("input", showSliderValue, false);

function showSliderValue() {
  rangeBullet.innerHTML = rangeSlider.value;
  var bulletPosition = (rangeSlider.value /rangeSlider.max);
  rangeBullet.style.left = (bulletPosition *  578) + "px";
}
...