`<input type="range">`のstepを可変にする方法

2 min read

仕様

input range はstepが指定でき、整数や浮動小数の指定によって、スライダーが段階的に変更できる。

stepを5に指定

ただ、今回は等差数列ではなく 0, 100, 500, 1000, 1500, 2000... と規則性のないような数値でstepを変えていきたい。

完成デモ

実装

手続き的に書いているが、こんな感じで実装できる。

<input id="range" type="range" value="0" />
<div id="output">0</div>
const RANGE_VALUES = [
  0, 100, 500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 5000, 6000, 7000, 8000,
  9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000, 60000,
  70000, 80000, 90000, 100000, 150000, 200000, 250000, 300000,
];

const output = document.querySelector("#output");
const range = document.querySelector("#range");

// init
range.setAttribute("min", RANGE_VALUES[0]);
range.setAttribute("max", RANGE_VALUES[RANGE_VALUES.length - 1]);

/**
 * Returns the closest number in the array.
 * @param {Number} num
 * @param {Array}  array
 * @return {Number}
 */
function closestNumber(num, array) {
  return array.reduce((prev, current) => {
    return Math.abs(current - num) < Math.abs(prev - num) ? current : prev;
  });
}

range.addEventListener("input", function () {
  output.innerText = closestNumber(Number(this.value), RANGE_VALUES);
});

input[type="range"]の入力値と RANGE_VALUESの定数を比較して、近似値を取得して表示している。input イベントで都度処理を実行してしまっているので、実際はライブラリなどでキャッシュしながら実行すると良さそう。

参考