質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

リファクタリング

リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

4576閲覧

同じ処理を重複して記述せず、簡潔にまとめる方法

k373

総合スコア17

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

リファクタリング

リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2018/09/06 11:41

編集2018/09/06 12:05

前提・実現したいこと

Javascriptを綺麗に書くことに関する質問です。
レンジスライダーを3つ使用し、それぞれのスライダーの横にレンジの値を表示させています。
ソースコードに同じ処理を3つずつ書いており、一つにまとめたいのですがわかりません。
初心者ですみませんが、よろしくお願いいたします。

該当のソースコード

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="utf-8"> 6 <title>数値入力のサンプル</title> 7 <script src="js/main.js" charset="utf-8"></script> 8</head> 9 10<body> 11 12 <input type="range" id="range1" class="range" min="0" max="255" step="1" value="0"> 13 <span id="value1" class="value">0</span> 14 <input type="range" id="range2" class="range" min="0" max="255" step="1" value="0"> 15 <span id="value2" class="value">0</span> 16 <input type="range" id="range3" class="range" min="0" max="255" step="1" value="0"> 17 <span id="value3" class="value">0</span> 18 19</body> 20 21</html>

Javascript

1(window.onload = function() { 2 'use strict'; 3 4 var range1 = document.getElementById('range1'); 5 var value1 = document.getElementById('value1'); 6 var rangeValue1 = function(){ 7 value1.innerHTML = range1.value; 8 }; 9 10 var range2 = document.getElementById('range2'); 11 var value2 = document.getElementById('value2'); 12 var rangeValue2 = function(){ 13 value2.innerHTML = range2.value; 14 }; 15 16 var range3 = document.getElementById('range3'); 17 var value3 = document.getElementById('value3'); 18 var rangeValue3 = function(){ 19 value3.innerHTML = range3.value; 20 }; 21 22 range1.addEventListener('input', rangeValue1); 23 range2.addEventListener('input', rangeValue2); 24 range3.addEventListener('input', rangeValue3); 25 26})();

試したこと

Javascript

1(window.onload = function() { 2 'use strict'; 3 4 var range = document.getElementsByClassName('range'); 5 6 range.addEventListener('input', function(){ 7 this.nextElementSibling.innerHTML = this.value; 8 }); 9 10})();

試したことを実行した結果、レンジの値が表示されませんでした。
開発ツールでは、Uncaught TypeError: range.addEventListener is not a functionと表示されます。

以上、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/09/06 11:52

「コードレビュー」「リファクタリング」もタグに追加されたほうが要件には合っているように思います。
k373

2018/09/06 11:54

ご指摘ありがとうございます!追加させていただきました。
m.ts10806

2018/09/06 11:58

ちょっと見逃してたのでお聞きしたいのですが、「試したこと」のコードではどうなりましたか?パッと見た感じ、そこまで悪いようには見えないのですが。
k373

2018/09/06 12:02

レンジの値が表示されません。開発ツールでは、Uncaught TypeError: range.addEventListener is not a functionと表示されます。ありがとうございます。
m.ts10806

2018/09/06 12:08

あ、なるほど。わかりました。ちょっとこれで回答してみます。少々お待ちを。
guest

回答3

0

ベストアンサー

「試したこと」は結構惜しいように思います。
getElementsByClassName()はその名の通りclass名からElementの情報を取得するものです。

メソッド名をよく見てみましょう。
get Element"s" By Class Name

複数形ですね。
classは1ページに幾つも出てくるものであるため、取得できるのはHTMLCollectionで、要素はそれらがその文書ツリーに現れる順番に得られます(ドキュメントから引用)

一方addEventListener()は Element, Document, Window などが対象です。
Elementなので「このElement」と特定できてなければなりません。

では、どうすればいいか。
下記はやり方の1つですが、例えばforで回してそれぞれにイベントをaddするとかです。
※未検証につき実装イメージだけ伝わればと思います。

js

1var range = document.getElementsByClassName('range'); 2for(var i=0;i<range.length;i++){ 3 range[i].addEventListener('input', function(){ 4 this.nextElementSibling.innerHTML = this.value; 5 }); 6}

投稿2018/09/06 12:19

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k373

2018/09/06 12:25

早速の回答ありがとうございます。 また、解説も非常にわかりやすく、感謝します。 回答いただいたコードで、問題なく動きました。 初めてここで質問しましたが、モチベーションが上がりました。 今後とも、どうぞよろしくお願いいたします。
m.ts10806

2018/09/06 12:29

解決できたようで何よりです。 質問内容も分かりやすく、私の確認にも快く応じてくださったのでスムーズな回答につながりました。 こちらこそありがとうございました。 jun68yktさんの回答も私があまり使えていない機能を使ってらっしゃるので勉強になると思います。 そちらもぜひ参考にしてください。
guest

0

解決済みですが、こんなのもアリかなーっと。
HTML側もちょこっとだけいじりましたが。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="utf-8"> 6 <title>数値入力のサンプル</title> 7 <script src="js/main.js" charset="utf-8"></script> 8</head> 9 10<body> 11 12 <input type="range" id="range1" class="range" min="0" max="255" step="1" value="0"> 13 <label id="value1" class="value" for="range1">0</label> 14 <input type="range" id="range2" class="range" min="0" max="255" step="1" value="0"> 15 <label id="value2" class="value" for="range2">0</label> 16 <input type="range" id="range3" class="range" min="0" max="255" step="1" value="0"> 17 <label id="value3" class="value" for="range3">0</label> 18 19</body> 20 21</html>

js

1(window.onload = function() { 2 'use strict'; 3 4 document.body.addEventListener('input', function(e) { 5 var target = e.target; 6 if (!target.classList.contains('range')) return; 7 8 var label = document.querySelector(`[for="${target.id}`); 9 label.textContent = target.value; 10 }); 11 12})();

投稿2018/09/06 13:32

spookybird

総合スコア1803

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k373

2018/09/06 14:00

ご回答ありがとうございます! この方法も、まだ初心者の私には難しいですが、可能性を広げられそうでありがたいです。 内容を理解し、展開できるようにいたします。 ありがとうございます!
spookybird

2018/09/06 14:13

特に難しいことはやってなくてですね、覚えちゃえば簡単な話です。DOMのイベントっていうのは意図的に止めない限りバブリングといって祖先に向かって伝播していくようになってます。なので、イベント発火する本人じゃなくて親でイベント捕まえちゃえば、その親の中にいるすべての要素から発火される指定のイベントを捕まえてくれるわけです。で、とりあえず誰でもいいからイベント捕まえちゃってるので、必要なものだけに厳選するためのif文を挟んでます。spanをfor属性つけたlabelに変更したのは、用途的にlabelの方が適切だと思ったのと、イベント捕まえたrangeに対応するlabelが誰なのかを特定するためです。
k373

2018/09/06 14:21

ご返信ありがとうございます。 なるほど、すべてのイベントから狙っているもの以外排除しているわけですね。 使ったことのない方法だったので、引き出しが増え、とても勉強になります。 また、labelの使用方法もとても参考になります。 ぜひ使ってみます!ありがとうございました。
guest

0

こんにちは。
以下のような感じでいかがでしょうか。

javascript

1var rangeInputs = document.getElementsByClassName('range'); 2 3for (let i = 0; i < rangeInputs.length; i++) { 4 rangeInputs[i].addEventListener('input', (e) => { 5 const valueSpan = document.getElementById(`value${i+1}`); 6 valueSpan.innerHTML = e.target.value; 7 }); 8}

以下、上記を試すサンプルです。

https://jsfiddle.net/jun68ykt/b19mr5n6/3/

または、forEachで回すなら

javascript

1[].forEach.call(document.getElementsByClassName('range'), (node, i) => { 2 node.addEventListener('input', e => { 3 const valueSpan = document.getElementById(`value${i+1}`); 4 valueSpan.innerHTML = e.target.value; 5 }); 6});

サンプル: https://jsfiddle.net/jun68ykt/b19mr5n6/4/

投稿2018/09/06 12:13

編集2018/09/06 12:23
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k373

2018/09/06 12:28

ご回答ありがとうございます! ご回答いただきましたコードで、問題なく動作しました。 様々な解決方法があることが非常に勉強になります。 (e) =>のあたりが、まだ私の知らない知識なので勉強し、精進いたします。 今後ともどうぞよろしくお願いいたします。
jun68ykt

2018/09/06 15:15 編集

ご返信ありがとうございます。 > (e) =>のあたりが、まだ私の知らない知識なので勉強し、精進いたします。 アロ−関数と呼ばれる書き方です。以下をご参照ください。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/arrow_functions さらに簡潔に書こうと思えば、対になる<input>と<span>の共通の親となる要素を追加したうえで、JQuery を使うところかなと思います。以下はその場合の例です。 https://jsfiddle.net/jun68ykt/b19mr5n6/5/
k373

2018/09/06 13:01

ご返信ありがとうございます。 アロー構文というのですね。可能性が広がりそうなので、ぜひ勉強いたします! 確かにjQueryも使うともっと簡単に解決できそうですね。 非常に参考になるご回答と、ご解説ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問