最終更新日:
公開日:
レシピ
フォーム
スライダーを特定の範囲で動かせないように設定する
スライダーによる選択範囲を指定した範囲にする方法を解説します。
この記事のポイント
- input要素の入力中に発生するイベントinputを検知してリアルタイムで値をチェックする
スライダーで選択できる範囲を限定する
フォームのスライダーは最小値と最大値を指定することができますが、特定の条件下ではその範囲内でさらに範囲を指定する必要のあるケースがあります。
そこで今回は、JavaScriptを使ってスライダーの選択できる範囲を制御する方法を解説していきます。
以下のHTMLコードを解説用に使います(CSSの表記は省略)。
赤字の箇所になっている箇所が、スライダーになるinput要素です。
HTMLコード例
<form method="post" action="">
<div>
<label for="input_type1"><input id="input_type1" type="radio" name="type" value="1">タイプ1</label>
<label for="input_type2"><input id="input_type2" type="radio" name="type" value="2">タイプ2</label>
<label for="input_type3"><input id="input_type3" type="radio" name="type" value="3">タイプ3</label>
</div>
<label for="input_volume">Volume</label>
<input type="range" id="input_volume" name="volume" min="0" max="10" value="3">
</form>
ブラウザで表示すると、ラジオボタンが3つ、スライダーが1つ表示されます。
スライダーは0〜10まで選択できるようにmin属性に0、max属性に10を設定します。
そして選択したタイプによってスライダーの設定できる範囲を動的に変更するため、タイプ1〜タイプ3の3つのラジオボタンも用意しています。
まずはラジオボタンによる動的な範囲設定は置いておき、スライダーの選択範囲を固定で設定してみます。
以下のコードは0〜10の範囲で選択できるスライダーに対して、選択範囲を5〜8に設定します。
コード例
window.addEventListener('DOMContentLoaded', function(){
let volume = document.getElementById("input_volume");
let min_limit = 5;
let max_limit = 8;
// 最初に最小値へセット
volume.value = min_limit;
volume.addEventListener('input',function(){
if( volume.value < min_limit ) {
volume.value = min_limit;
}
if( max_limit < volume.value ) {
volume.value = max_limit;
}
});
});
まずはスライダーのinput要素をid属性で取得し、変数volumeに入れます。
その後に宣言している変数min_limitは選択できる最小値、もう1つの変数max_limitは選択できる最大値をそれぞれ指定しておきます。
続いて、スライダーのinput要素でイベント「input」が発生したら指定した処理を実行できるように、addEventListenerメソッドを実行してイベントリスナーに登録します。
このイベントは入力中に継続的に発生するため、スライダーを動かしている最中にその時点の値をチェックしたりすることができます。
イベントリスナーに登録している処理では、スライダーの値が最小値より低いか、または最大値より大きいかをチェックしています。
もし値が最小値(min_limit)よりも小さい場合は、スライダーの値をmin_limitに設定することで最小値のラインより低い値が入力されないようになっています。
最大値(max_limit)についても同様に、スライダーの値が最大値より大きくなったときはスライダーの値にmax_limitを設定しているため、最大値のラインより大きい値は入力できません。
このスライダーの値のチェックを入力中に行うことで、指定した最小値と最大値の間に収まる範囲でのみ入力できる機能を実装しています。
ラジオボタンの選択によってスライダーの選択範囲を設定する
続いて、あらかじめ用意していたラジオボタンを使って、選択したタイプによってスライダーの選択範囲が動的に設定されるようにしていきます。
タイプ1、タイプ2、タイプ3で選択できる範囲は次のように設定します。
- タイプ1 – 0〜3
- タイプ2 – 4〜7
- タイプ3 – 8〜10
以下のコードは、ラジオボタンが選択されたときの処理を実装した内容になります。
赤字の箇所が先ほどのコードに追記している部分です。
コード例
window.addEventListener('DOMContentLoaded', function(){
let volume = document.getElementById("input_volume");
let min_limit = 5;
let max_limit = 8;
// 最初に最小値へセット
volume.value = min_limit;
volume.addEventListener('input',function(){
if( volume.value < min_limit ) {
volume.value = min_limit;
}
if( max_limit < volume.value ) {
volume.value = max_limit;
}
});
// (1)全てのラジオボタンのinput要素を取得
let input_types = document.querySelectorAll("input[name=type]");
for(var type of input_types) {
// (2)それぞれのラジオボタンにイベントリスナーを登録
type.addEventListener('change', function(){
// (3)選択したラジオボタンによって最小値と最大値を変更する
switch(this.value) {
case "1":
min_limit = 0;
max_limit = 3;
break;
case "2":
min_limit = 4;
max_limit = 7;
break;
case "3":
min_limit = 8;
max_limit = 10;
break;
}
// (4)スライダーの現在の値を確認(最小値)
if( volume.value < min_limit ) {
volume.value = min_limit;
}
// (5)スライダーの現在の値を確認(最大値)
if( max_limit < volume.value ) {
volume.value = max_limit;
}
});
}
});
追加したコードの流れを上から順に解説していきます。
「(1)全てのラジオボタンのinput要素を取得」では、querySelectorAllメソッドを使って全てのラジオボタンを取得します。
変数input_typesには取得したラジオボタンが配列形式で入ります。
そこで、続くfor…of文でラジオボタンの数だけループ処理を実行するようにします。
ループ内の処理を開始する度に、input_typesからラジオボタンのinput要素を1つ取り出して変数typeに入れます。
続いて、「(2)それぞれのラジオボタンにイベントリスナーを登録」の箇所でラジオボタンに対してイベントリスナー「change」を登録します。
このイベントはラジオボタンの選択状態が変わったときに発生します。
「(3)選択したラジオボタンによって最小値と最大値を変更する」では、switch文を使ってラジオボタンの値に応じて最小値と最大値を更新します。
例えば、「タイプ1」が選択されたときは「case “1”」が該当するため、min_limitに0、max_limitに3が設定されます。
「(4)スライダーの現在の値を確認(最小値)」はスライダーの現在の値をチェックして、最小値より小さい値になっていないかチェックします。
もし最小値より小さい値になっていたら、先ほどmin_limitに設定した値をスライダーにセットします。
「(5)スライダーの現在の値を確認(最大値)」は反対に、最大値より大きい値になっていないかをチェックします。
もし大きい値になっていたらmax_limitの値をスライダーにセットします。
お気づきの方もいらっしゃるかと思いますが、(4)と(5)の処理はスライダーのイベントリスナー「load」で実行する処理と全く同じことをしています。
やや冗長になってしまうため、関数化をして重複を避ける書き方もあるかと思いますが、今回は解説をシンプルにするためそのような書き方をしていない点をご容赦ください。
ここまでに書いたコードを実際にブラウザで実行すると、ラジオボタンを選択する度にスライダーの選択可できる範囲が動的に設定されることを確認できると思います。