具有 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 插件,而无需重新初始化插件或类似的麻烦!
是否可以使用 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 插件,而无需重新初始化插件或类似的麻烦!