具有 2 个输入的基础范围滑块?

Foundation Range Slider with 2 Inputs?

是否可以使用 2 个不同的输入来控制 Foundation 范围滑块?我需要添加一个字段来设置特定的分数(像这样):https://codepen.io/jinch/pen/OaKpZX?editors=1000

<div class="row">
        <div class="small-2 columns">Width:</div>
  <div class="small-5 columns">
          <div class="slider" data-slider data-initial-start="20" data-options="precision:3; decimal:3; start:8; end:36;" style="margin-top: 12px;">
            <span class="slider-handle slideWidth"  data-slider-handle role="slider" tabindex="1" aria-controls="customPort-2-width"></span>
              <span class="slider-fill" data-slider-fill></span>
          </div>
  </div>
  <div class="small-5 columns">
    <input type="number" step="1" id="customPort-2-width" style="border: 1px solid #999999; display:inline-block; width:39%;">
    <select class="fractions fractionWidth" name="WidthFraction" style="border: 1px solid #999999; display:inline-block; width:39%;">
      <option value="0" selected="">0</option>
      <option value="1/8">1/8</option>
      <option value="1/4">1/4</option>
      <option value="3/8">3/8</option>
      <option value="1/2">1/2</option>
      <option value="5/8">5/8</option>
      <option value="3/4">3/4</option>
      <option value="7/8">7/8</option>
            </select>
    <span class="small">in.</span>
  </div>

TL;DR 好消息是这是可以做到的!坏消息是您需要稍微调整一下代码。我在午夜过后十分钟输入此内容,因此您很可能需要重构此内容,但我希望这是一个起点。

我将深入探讨实现的原因,但如果您想直接了解它,我创建了一个代码笔 https://codepen.io/jamie-endeavour/pen/zyxPaY?editors=1010

一些背景知识

当我第一次发现这个问题时,我查看了 Slider 文档并注意到有关 'Reflow' - https://foundation.zurb.com/sites/docs/slider.html#reflow 的部分 - 在阅读了此方法后,我决定查看 Foundation 源代码:

  _reflow() {
    this.setHandles();
  }

然后,我调查了 setHandles()...

  setHandles() {
    if(this.handles[1]) {
      this._setHandlePos(this.$handle, this.inputs.eq(0).val(), true, () => {
        this._setHandlePos(this.$handle2, this.inputs.eq(1).val(), true);
      });
    } else {
      this._setHandlePos(this.$handle, this.inputs.eq(0).val(), true);
    }
  }

请注意,_setHandlePos() 引用了 属性 中名为 inputs 的值。

初始化滑块 class 时设置以下内容:

this.inputs = this.$element.find('input');

this.$input = this.inputs.length ? this.inputs.eq(0) : $(`#${this.$handle.attr('aria-controls')}`);

在您的示例中,您没有提供输入元素。正如您所看到的,代码使用 aria-controls 的值来构建 'input' 的选择器。这是您的限制所在,因为您将无法通过这种方式将两个输入字段与滑块相关联。

解决方案

所以,还记得 this.$input 中使用的三元组吗?如果我们在您的 .slider 元素中添加一个 <input>,那么我们可以将其用作滑块的参考点。

<div class="slider" data-slider data-initial-start="20" data-options="precision:3; decimal:3; start:8; end:36;" style="margin-top: 12px;">
  <input type="hidden" id="slider-reference" value="8" />
  ...

现在您有了一个可以在两个输入字段之间使用的引用。然后,您可以在针对每个元素的更改回调后更新此引用字段的值,然后 Slider 将读取此值并进行相应更新。

number 输入所需的 JS 非常简单,因为我们提供了 Slider 计算宽度位置所需的绝对数字。

分数输入有点古怪,因为您需要 return 最小值和最大值 (28) 之差的一小部分,而不是最大值(在本例中为 36)的一小部分。这就是为什么我包含额外的计算以确保您获得相对于 Slider 元素的正确位置。这也是我觉得可以用新眼光重构的部分

最后,一旦您在每个更改处理程序中获取了新值,您只需调用 _reflow 方法,这将相应地更新 Slider 插件,而无需重新初始化插件或类似的麻烦!