addEventListenerが効かなくて困ったことはありませんか?
本記事では、addEventListenerが効かない事例とその解決策について、わかりやすく解説します。特に「addEventListenerでは、getElementsByClassNameが使えない」点に注意が必要です。
「税込金額計算ツール」を例に、エラーと解決策を見ていきましょう。

addEventListenerが効かないのはメソッドを持っていないから
どのようなときにaddEventListenerでgetElementsByClassNameが使えなくなるのか、「税込金額計算ツール」の実装過程から見ていきます。
※OS環境はMacOS、エディタはVisual Studio Codeを使用
- HTML・CSSで、入力ボックス・計算結果の外観を作成します。今回は、”item_price”クラス内に金額を入力し、”total_price”クラスで計算値を出力します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>税込価格を表示する</title>
<style>
input{
width: 200px;
font-size: 16px;
padding: 8px;
margin-bottom: 8px;
}
</style>
</head>
<body>
<input type="number" class="item_price" placeholder="金額を入力してください">
<div class="total_price"></div>
</body>
</html>
- 税込金額を自動計算・表示させるために、以下のJavaScriptを入力します。
<script>
// "item_price" クラスの要素(入力した値)を、変数:inputPrice と定義//
const inputPrice = document.getElementsByClassName("item_price");
// "total_price" クラスの要素(税込で表示する値)を、変数:totalPrice と定義//
const totalPrice = document.getElementsByClassName("total_price");
// "item_price" クラスに値が入力されたときの処理を、addEventListenerで指定//
inputPrice.addEventListener('input', function() {
//入力された値が空白の場合は、空白で返す(NaNと表示されるのを防止)//
if (inputPrice.value === '') {
totalPriceDisplay.textContent = '';
return;
}
//税率を設定する(今回は10%)//
const taxRate = 0.1;
//変数:totalPriceに、「税込価格:”入力値の税込金額”円」(小数点第2位まで)を代入する=>"total_price"クラスに税込金額を表示//
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
</script>
- ボックスに数値を入力しても、なぜか税込金額は表示されません。

-
検証画面でエラー内容を確認したところ、Uncaught TypeError: inputPrice.addEventListener is not a functionが表示されています。

「inputPrice は関数ではない」=「addEventListener メソッドを持っていない」ことから、メソッドを呼び出すことができないようです。
getElementsByClassName で取得した要素にはaddEventListener が使えない
document.getElementsByClassName() で取得した inputPrice の値は、関数ではなくHTMLコレクションです。HTMLコレクションは「HTMLの要素の集合を表す複数オブジェクト」であることから、addEventListener メソッドが存在しません。
一方で、addEventListener は単一の要素に対してイベントリスナーを追加します。そのため、getElemntsByClassName で取得した要素に対して addEventListener を直接適用できないのです。
コラム:HTMLコレクションの使用例:男女数の自動カウントツール
HTMLコレクションについて、男女数の自動カウントツールを例に解説します。

- 以下の通り、HTM・CSSコードを入力します。 liタグより、男性にはmanクラスを、女性にはwomenクラスをそれぞれ設定しています。
<ul> <!-- 男性にはmanクラスを、女性にはwomenクラスをそれぞれ設定 --> <li class="man">山田太郎</li> <li class="woman">田中花子</li> <li class="man">鈴木次郎</li> <li class="woman">佐藤優子</li> <li class="woman">渡辺由美</li> </ul> <div id="result"></div>
- 以下の通り、JavaScriptを実装します。
- manクラスに一致するすべての要素を、変数:menと定義
- womanクラスに一致するすべての要素を、変数:womenと定義
- “result”IDのHTML要素に、カウントした数を表示する
<script>
//manクラスの要素を取得し、変数:menと定義
const men = document.getElementsByClassName('man');
//womanクラスを持つ要素を取得し、変数:womenと定義
const women = document.getElementsByClassName('woman');
//id="result"のHTML内に、「男性は "menの要素数" 人、女性は "womenの要素数" 人です。」を代入//
document.getElementById('result').innerHTML = `男性は ${(men.length)} 人、女性は ${(women.length)} 人です。`;
</script>
-
すると、名簿の一覧に対する男女の人数を表示できます。

HTMLコレクションは「HTMLの要素の集合を表す複数オブジェクト」なので、getElementsByClassName()を用いることで、指定されたクラス名に一致するすべての要素を取得できるのです。
解決策1:document.getElementsByClassName() の代わりにquerySelector を使用する
以下の通り、item_price クラスと total_price クラスの値を取得する際に、querySelector を使用すると、正しく表示されます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>税込価格を表示</title>
<style>
input {
width: 200px;
font-size: 16px;
padding: 8px;
margin-bottom: 8px;
}
</style>
</head>
<body>
<input type="number" class="item_price" placeholder="金額を入力してください">
<div class="total_price"></div>
<script>
const inputPrice = document.querySelector(".item_price");
const totalPrice = document.querySelector(".total_price");
inputPrice.addEventListener('input', function () {
if (inputPrice.value === '') {
totalPrice.textContent = '';
return;
}
const taxRate = 0.1;
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
</script>
</body>
</html>

querySelector() とは、指定されたCSSセレクタに一致する最初のHTML要素を取得するメソッドです。単一の要素が取得されることから、直接 addEventListener を適用できます。
解決策2:クラスの代わりにIDを取得させる
以下の通り、item_price と total_price をクラスではなく id に設定し、getElementById() で id の要素を取得すると、正しく表示されます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>税込価格を表示</title>
<style>
input {
width: 200px;
font-size: 16px;
padding: 8px;
margin-bottom: 8px;
}
</style>
</head>
<body>
<input type="number" id="item_price" placeholder="金額を入力してください">
<div id="total_price"></div>
<script>
const inputPrice = document.getElementById("item_price");
const totalPrice = document.getElementById("total_price");
inputPrice.addEventListener('input', function () {
if (inputPrice.value === '') {
totalPrice.textContent = '';
return;
}
const taxRate = 0.1;
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
</script>
</body>
</html>

HTML文書内で要素に付けられるIDは単一であり、重複してはいけません。もし同じIDが複数の要素で使われている場合、メソッドは最初に見つかった要素を返します。
このように単一の要素が取得されることから、直接 addEventListener を適用できるのです。
addEventListener 使用時に注意したい他のエラー
addEventListener を使用した際に発生するエラーは、他にもあります。先ほどと同じ「税込金額計算ツール」を例にして、見ていきましょう。
複数の箇所に同じクラスを設定した場合、2つ目以降のクラスでaddEventListenerが動作しない
以下の通り、HTMLで価格を入力する欄を追加したとき、下段のボックスに数値を入力しても税込金額が表示されません。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>税込価格を表示</title>
<style>
input {
width: 200px;
font-size: 16px;
padding: 8px;
margin-bottom: 8px;
}
</style>
</head>
<body>
<div class="price">
<p>価格1</p>
<input type="number" class="item_price" placeholder="金額を入力してください">
<div class="total_price"></div>
</div>
<div class="price">
<p>価格2</p>
<input type="number" class="item_price" placeholder="金額を入力してください">
<div class="total_price"></div>
</div>
<script>
const inputPrice = document.querySelector(".item_price");
const totalPrice = document.querySelector(".total_price");
inputPrice.addEventListener('input', function () {
if (inputPrice.value === '') {
totalPrice.textContent = '';
return;
}
const taxRate = 0.1;
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
</script>
</body>
</html>

querySelector() は「最初のHTML要素を取得するメソッド」です。そのためこのエラーは、下段に設定された “item_price” クラスと “total_price” クラスでは無効なのが原因です。
そこで、以下の通りJavaScriptを入力します。
<script>
const prices = document.querySelectorAll(".price");
prices.forEach(price => {
const inputPrice = price.querySelector(".item_price");
const totalPrice = price.querySelector(".total_price");
inputPrice.addEventListener('input', function () {
if (inputPrice.value === '') {
totalPrice.textContent = '';
return;
}
const taxRate = 0.1;
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
});
</script>
まずは、querySelectorAll メソッドで「指定されたCSSセレクターに一致するすべての要素を取得」します。次に、pricesクラスに含まれる各要素に対して、以下のループ処理を設定します。
- priceクラス内の”item_price”の要素を取得して、”inputPrice”と定義する
- priceクラス内の”total_price”の要素を取得して、”totalPrice”と定義する
- “item_price” クラスに値が入力されたときの処理を、addEventListenerで指定
これでエラーが解消され、価格1と価格2の両方に対して正しい税込価格が表示できるようになります。

イベントリスナーが重複した場合、後から書いた処理に上書きされる
以下の通り、ダブルクリックした際に入力金額が消去される動作を2つ追加します。
- 入力した価格と税込価格の欄を消去する
- 入力した価格を消去したあとに、税込価格の欄に「金額がクリアされました!」と表示する
<script>
const prices = document.querySelectorAll(".price");
prices.forEach(price => {
const inputPrice = price.querySelector(".item_price");
const totalPrice = price.querySelector(".total_price");
inputPrice.addEventListener('input', function () {
if (inputPrice.value === '') {
totalPrice.textContent = '';
return;
}
const taxRate = 0.1;
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
//金額が消去された後は、何も表示されない
inputPrice.addEventListener('dblclick', function () {
inputPrice.value = '';
totalPrice.textContent = '';
});
//金額が消去された後に、「金額がクリアされました!」と表示
inputPrice.addEventListener('dblclick', function () {
inputPrice.value = '';
totalPrice.textContent = '金額がクリアされました!';
});
});
</script>
すると、①の設定が②の設定に上書きされてしまいます。

addEventListener は、イベントリスナーが追加された順番に実行されます。そのため、先に追加されたリスナーが実行された後に、次に追加されたリスナーが実行されてしまい、その結果上書きされてしまうのです。
これを解決するには、コードを理解しやすくするために、1つのイベントリスナー内で必要な処理をまとめて実行しましょう。
<script>
const prices = document.querySelectorAll(".price");
prices.forEach(price => {
const inputPrice = price.querySelector(".item_price");
const totalPrice = price.querySelector(".total_price");
inputPrice.addEventListener('input', function () {
if (inputPrice.value === '') {
totalPrice.textContent = '';
return;
}
const taxRate = 0.1;
totalPrice.textContent = `税込価格: ${(inputPrice.value * (1 + taxRate)).toFixed(2)} 円`;
});
inputPrice.addEventListener('dblclick', function () {
inputPrice.value = '';
totalPrice.textContent = '';
});
});
</script>
コラム:JavaScriptのイベント
JavaScriptで使えるイベントは、とてもたくさんあります。その中でも実際によく使われる、代表的なイベントは以下のようなものです。
| click | クリックされたとき |
| dblclick | ダブルクリックされたとき |
| drag | ドラッグされたとき |
| input | 入力されたとき |
| keydown | キーが押されたとき |
| keyup | キーが離されたとき |
| load | ページや画像などのロードが完了したとき |
| mousedown | マウスボタンが押されたとき |
| mousemove | マウスポインタが移動したとき |
| mouseout | マウスポインタが入ってきたとき |
| mouseover | マウスポインタが離れたとき |
| mouseup | マウスボタンが離されたとき |
まとめ
getElementsByClassName で取得した要素は、HTMLコレクションになるため、addEventListener を呼び出せません。そのため、以下のメソッドでエラーを解消させましょう。
- querySelector() を使用する
- クラスではなくidに設定し、getElementById() を使用する
他にも「複数の箇所に同じクラスを設定する場合は、querySelectorAll メソッドを用いてforeach文でループさせる」「イベントリスナーを重複させない」ことも覚えておくと良いです。
addEventListener への理解を深めて、実装バリエーションを増やしましょう。
関連記事
テキストボックスの値を別のテキストボックスへ反映させる方法【HTML・JavaScript】
2024.1.10
2025.4.28
最新記事
-
ノーコードで簡単!Difyを使ったAIチャットボットの作り方
2025.10.1
-
営業のレスポンスが遅いと何が起きる?機会損失の原因と対処
2025.9.29
-
フォーム営業の返信率を上げる方法│平均値と改善手順
2025.9.9
-
Claudeプロジェクトの使い方|基本からすぐに使えるサンプルまで
2025.8.29
-
生成AI資格のメリットは?初心者におすすめの生成AIパスポートも解説!
2025.8.28
