【问题标题】:Customizing HTML range input with a floating DIV that contains current value使用包含当前值的浮动 DIV 自定义 HTML 范围输入
【发布时间】:2025-12-04 22:00:01
【问题描述】:

我想创建一个范围滑块,它有一个 div 元素跟随范围拇指。此 div 元素将包含范围输入的当前值。我将如何去做这样的事情?我研究了滑块的样式,但不知道如何将实际元素添加到拇指上。它看起来像这样,请原谅我糟糕的绘图能力:

编辑:以下 div 应在拖动滑块时更新。 更新:我有一个很好的原型,但似乎无法让它完美地跟随滑块。它会偏离中心几个像素,具体取决于它在轨道上的位置。 Heres my codepen

更新代码

HTML

<div id="slider-cntnr">
  <input type="range" id="frame-slider" oninput="updateFollowerValue(this.value)"/>
  <div id="slider-follow">
    <div id="slider-val-cntnr">
      <span id="slider-val"></span>
    </div>
  </div>
</div>

CSS

html, body {
  width: 100%;
  height: 100%;
}

#slider-cntnr {
  width: 50%;
  margin: 40px;
  position: relative;
}

#frame-slider {
  width: 100%;
  margin: 0;
}

#slider-follow {
  margin-left: -14px;
  background-color: black;
  width: 30px;
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
}

#slider-val-cntnr {
  background-color: white;
  width: 25px;
  height: 20px;
}

JS

var follower = document.getElementById('slider-follow');
var follower_val = document.getElementById('slider-val');
var slider = document.getElementById('frame-slider');

var updateFollowerValue = function(val) {
  follower_val.innerHTML = val;
  follower.style.left = val + '%';
};

updateFollowerValue(slider.value);

【问题讨论】:

  • 创建一个&lt;div&gt;,将其设置为position: absolute,并在滑块滑动回调中,更新div的坐标。或者查看滑块缩略图的 HTML,找到一个 CSS 类并使用该类添加到滑块的 HTML。
  • @JohannesJander 您如何使用该类添加到拇指的 html 中?有内容属性?
  • $('.slider-thumb').append('&lt;div&gt;myDiv&lt;/div'); - 如果 slider-thumb 是 thumbs CSS 类。
  • 那幅画太棒了

标签: javascript html css range uislider


【解决方案1】:

如果您不支持旧浏览器,则可以利用

<input type="range"> 

和一些 JavaScript 跟随它。查看我的 Codepen:http://codepen.io/abhisharma2/pen/wMOpqz

【讨论】:

    【解决方案2】:

    自定义output的示例

    拖动输入时它会更新。

    var el, newPoint, newPlace, offset;
     
    $('input[type=range]').on('input', function () {
        $(this).trigger('change');
    });
    // Select all range inputs, watch for change
    $("input[type='range']").change(function() {
    
     // Cache this for efficiency
     el = $(this);
     
     // Measure width of range input
     width = el.width();
     
     // Figure out placement percentage between left and right of input
     newPoint = (el.val() - el.attr("min")) / (el.attr("max") - el.attr("min"));
      
      offset = -1;
    
     // Prevent bubble from going beyond left or right (unsupported browsers)
     if (newPoint < 0) { newPlace = 0; }
     else if (newPoint > 1) { newPlace = width; }
     else { newPlace = width * newPoint + offset; offset -= newPoint; }
     
     // Move bubble
     el
       .next("output")
       .css({
         left: newPlace,
         marginLeft: offset + "%"
       })
         .text(el.val());
     })
     // Fake a change to position bubble at page load
     .trigger('change');
    output { 
      position: absolute;
      background-image: linear-gradient(#444444, #999999);
      width: 40px; 
      height: 30px; 
      text-align: center; 
      color: white; 
      border-radius: 10px; 
      display: inline-block; 
      font: bold 15px/30px Georgia;
      bottom: 175%;
      left: 0;
      margin-left: -1%;
    }
    output:after { 
      content: "";
      position: absolute;
      width: 0;
      height: 0;
      border-top: 10px solid #999999;
      border-left: 5px solid transparent;
      border-right: 5px solid transparent;
      top: 100%;
      left: 50%;
      margin-left: -5px;
      margin-top: -1px;
    }
    form { 
      position: relative; 
      margin: 50px;
    }
    body {
      padding: 20px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
    <form>
    <input type="range" name="foo" min="0" max="100">
    <output for="foo" onforminput="value = foo.valueAsNumber;"></output>
    </form>
    
    <form>
    <input type="range" name="foo" min="0" max="100" style="width: 300px;">
    <output for="foo" onforminput="value = foo.valueAsNumber;"></output>
    </form>
    
    <form>
    <input type="range" name="foo" min="0" max="100">
    <output for="foo" onforminput="value = foo.valueAsNumber;"></output>
    </form>

    参考https://css-tricks.com/value-bubbles-for-range-inputs/

    【讨论】:

      【解决方案3】:

      基本上 ypu 可以这样搭配:

      重点是;

      不要忘记将包装器定位为相对。 为您的以下徽章提供绝对位置,并将负边距左值作为徽章的宽度/2。(如果您的徽章为 50px,则为 margin-left -25px); 范围滑块必须有 100% 的宽度。

      HTML:

      <div class="range-slider">
          <input type="range" min="0" max="100" step="1" />
          <div class="range-badge"></div>
      </div>
      

      CSS:

      .range-slider{
          position: relative;
          width: 200px;
      }
      
      .range-slider > input.range{
        width: 100%;
      }
      
      .range-slider > .range-badge{
          position: absolute;
          left: 0%;
          top: 20px;
          background: #000;
          color: #fff;
          width: 20px;
          text-align: center;
          margin-left: -10px;
          padding: 5px 0;
      }
      

      JS:

      $(document).ready(function(){
          var badge = $('.range-badge');
      
        $('.range').on('change', function(){
          var current = $(this).val();
      
          badge.text(current).animate({
            'left': current+'%'
          });
        });
      });
      

      在这里测试: https://jsfiddle.net/dmnzugh8/6/

      【讨论】:

      • 我不会给你写所有的代码,你必须自己做。
      • @stack_pooper 如果您使用 'input' 事件而不是 'change' 可能会有所帮助