HTML
JavaScript
Range
input
スライダー
0
どのような問題がありますか?

投稿日

inputタグのスライダーについて

今回は、HTMLの「form」タグ等でたまに使用する、
「input」タグについてやっていきたいと思います。
それではまずはHTMLに記述していきます。

HTMLコード

<body>
  <input type="range">
</body>

1.png
HTMLに「input」タグを、typeには「range」を入れることで、
上記画像のようなユーザー側で動かすスライダーが出現しました。

このスライダーに対して

CSSコード

input{
  width: 400px;
}

2.png
幅をCSSで設定すると、画像のようにスライダーが横に長くなります。

HTML内で設定できるものは、「input」タグ内の属性で記述します。

HTMLコード

<body>
  <input type="range" min="#" max="#" step="#" value="#">
</body>

属性はこのように記述します。属性の意味はそれぞれ

「min」→「最小値」
(スライダーを左端に移動させた時の値)
「max」→「最大値」
(スライダーを右端に移動させた時の値)
「step」→「移動幅」
(スライダーを移動させた時の移動単位(最小値「0」、最大値「10」で移動幅を「2」に設定した時、スライダーは5段階に分けて「2」ずつ値が変化していく))
「value」→「初期値」
(ブラウザを表示させた時の最初の状態での値)

という意味で、属性を設定していないデフォルトの状態ではそれぞれ

「min」→「0」
「max」→「100」
「step」→「1」
「value」→「50」

となっており、上記コード内の「#」の値を変更することでそれぞれ属性値を変更することができます。
例えば「value」を「0」にすると
3.png
このように初期値が一番左にいきました。
これは、左端の値が「0」、右端の値が「100」のスライダーで初期値が「0」と設定したため、
このようになったということです。

このスライダーの値というのは何も設定しなければブラウザ上で表示することができず、
「input」タグのtypeが「submit」のもの等で活用することができます。

次はこのスライダーの値を表示していきます。
この値を表示するためにはJavaScriptを使います。

HTMLコード

<body>
  <input type="range" min="1" max="10" step="1" value="1" id="iptJS">
  <span id="valueJS">1</span>
</body>

4.png
まずJSを使用する事前準備として、「input」タグに対してJSで使用する「id」を設定し、
JSで値を表示させるので、表示させる土台として「span」タグを記述します。
この時の「span」タグには「input」タグの「value」属性の値を書いておきます。
すると4画像のようになりました。
この出現した数値は今はただの不可変の数値なのでスライダーをいくら動かしても変化しませんが、
この数値「span」とスライダー「input」をJSで連動させて、数値を変更していくということをやります。
それではコードを記述していきますが、今回は短いコードなのでHTMLの「script」タグ内で記述していきます。

HTMLコード

<body>

  <input type="range" min="1" max="10" step="1" value="1" id="iptJS">
  <span id="valueJS">1</span>
  
  <script>
    let ipt=document.getElementById("iptJS"); //1
    let spn=document.getElementById("spnJS"); //2
    let rangeValue=function(ipt,spn){         
      return function(){                      
        spn.innerHTML=ipt.value;              //3
      }
    }
    ipt.addEventListener("input",rangeValue(ipt,spn));  //4
    </script>

</body>

5.png
こんな感じでコードを記述し、スライダーの値により数値を変更しています。
JS部分を上から説明していくと、
1、idが「iptJS」である「input」を取得し、変数「ipt」へ代入。
2、idが「spnJS」である「span」を取得し、変数「spn」へ代入。
3、関数「rangeValue」を作成し、引数も設定、「spn.innerHTML」により「span」タグ内の文字を、「ipt.value」により「input」タグの値に変更、その変更した値を戻り値として設定。
4、「ipt」要素に対して「addEventListener」を使用し、inputイベント(「input」「select」「textarea」の各要素の「value」が変更されたとき)で「rangeValue」関数を行うよう設定。

この記述を一回書くと、次からは「rangeValue」は使い回せるので、

HTMLコード

<body>

  <input type="range" min="1" max="10" step="1" value="1" id="iptJS">
  <span id="spnJS">1</span>

  <input type="range" min="1" max="10" step="1" value="1" id="iptJS2">
  <span id="spnJS2">1</span>                                                              //追加
  
  <script>
    let ipt=document.getElementById("iptJS");
    let spn=document.getElementById("spnJS");
    let rangeValue=function(ipt,spn){
      return function(){
        spn.innerHTML=ipt.value;
      }
    }
    ipt.addEventListener("input",rangeValue(ipt,spn));

    let ipt2=document.getElementById("iptJS2");            //追加
    let spn2=document.getElementById("spnJS2");            //追加
    ipt2.addEventListener("input",rangeValue(ipt2,spn2));  //追加
    </script>

</body>

スクリーンショット 2022-04-22 16.48.21.png
この追加記述のように、新しく「input」タグでスライダーを作成しても、JavaScript側は関数を使い回して使用することができます。

ですがこのスライダーが10個も20個もあったらJavascriptの行が30行にも60行にもなります。
そこでfor文を使用して1つのコードブロックで全てのスライダーに適用できるようにしていきます。

HTMLコード

<body>
  <div class="rangeGroup">   //1
    <input type="range" min="1" max="10" step="1" value="1" id="iptJS">
    <span id="spnJS">1</span>
  </div>
  <div class="rangeGroup">   //1
    <input type="range" min="1" max="10" step="1" value="1" id="iptJS2">
    <span id="spnJS2">1</span>
  </div>
  <div class="rangeGroup">   //1
    <input type="range" min="1" max="10" step="1" value="1" id="iptJS3">
    <span id="spnJS3">1</span>
  </div>
  
  <script>

    let rangeValue=function(ipt,spn){
      return function(){
        spn.innerHTML=ipt.value;
      }
    }   //2
    let rangeG=document.getElementsByClassName("rangeGroup");   //3
    for(let i=0;i<rangeG.length;i++){   //4
      var ipt=rangeG[i].getElementsByTagName("input")[0];   //5
      var spn=rangeG[i].getElementsByTagName("span")[0];   //6
      ipt.addEventListener("input",rangeValue(ipt,spn))   //7
    }

    </script>

</body>

スクリーンショット 2022-04-22 17.03.51.png
1、まず今まで作成してきた「input」「span」を1つのまとまりとして「div」で囲い、「rangeGroup」とクラス名をつけます。(今回は3つスライダーを設置しています。)
2、前回作成したような、「span」タグの文字列に対して文字を変更する関数を作成。この引数「ipt」には「input」タグの情報、「spn」には「span」タグの情報がそれぞれ入るようになります。
3、次に先ほどクラス名を付与した「rangeGroup」を取得、変数「rangeG」に代入します。
4、ここでfor文を作成、「i」の数は「rangeGroup」クラス数とします。(今回クラス数は3つ)
5、クラス「rangeG」(インデックス番号に[i]を追加することで、for文により0から指定の数まで繰り返す)に対し、「getElementsByTagName」により「input」タグを取得(("input")[0]とすることでクラス「rangeG」内の最初の「input」を取得という意味になる)、それを変数「ipt」に代入します。
6、クラス「rangeG」に対し、「getElementsByTagName」により「span」タグを取得、それを変数「spn」に代入します。
7、変数「ipt」に対して「addEventListener」を使用し、inputイベントで「rangeValue」関数を行うよう設定。この文をfor文内に入れてしまうことでクラス数だけイベント処理が繰り返され、この時の「rangeValue」関数の受け渡し変数は「ipt」と「spn」にすることで、ただ繰り返すだけではなくクラス「rangeG」を記述の上から1つずつ適用していくことになります。

このように記述することで上記画像のように、1つのコードブロックで全てのスライダーに適用することができました。
ちなみになぜ今回はスライダーが横並びではなく縦並びになっているかというと、
前回の横並び状態の時は、「input」タグも「span」タグもインライン要素であり、今回囲っている「div」タグはブロック要素であるため、このような違いになります。

今回はここまでです。
ご購読ありがとうございました!

ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
tagotyan

コメント

同じパターンの繰り返しであれば、全体を括る要素にひとつだけイベントリスナーを設定してtargetやclosestで処理する方法もあります。

<body>
  <div class='container'>
    <div class='rangeGroup'>
      <input type='range' min='1' max='10' value='1' id='range1'>
      <span>1</span>
    </div>
    <div class='rangeGroup'>
      <input type='range' min='1' max='10' value='1' id='range2'>
      <span>1</span>
    </div>
    <div class='rangeGroup'>
      <input type='range' min='1' max='10' value='1' id='range3'>
      <span>1</span>
    </div>
  </div>
  
  <script>
    document.querySelector('.container').addEventListener('input', e =>
      e.target.closest('.rangeGroup').querySelector('span').textContent = e.target.value);
  </script>
</body>
0
どのような問題がありますか?
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
新人プログラマ応援 - みんなで新人を育てよう!
~
データに関する記事を書こう!
~
0
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー