JavaScriptのonclickを使う|addEventListenerメソッドを使ったほうがいい

onclickは、ユーザーがウェブページ上の要素をクリックしたときに実行されるイベントハンドラー。

勉強がてら、その使い方をざざっとまとめてみました。

ただ、結論から言うと、onclickを使わずにaddEventListenerを最初から使ったほうがいいと思います。

目次
    スポンサーリンク

    JavaScriptのonclickとは?

    onclickは「HTMLの要素がクリックされたときに、JavaScriptの処理を実行するイベント属性

    「on(〜のとき) + click(クリック)」で「クリックのとき」という意味らしい。ボタン、リンク、画像などあらゆるHTML要素に使うことができる。

    onclickの基本的な使い方

    onclickイベントを要素に追加する方法は大きく分けて2つある。HTMLにonclick属性として直接記述する方法と、JavaScriptのonclickプロパティを使って動的に追加する方法。

    HTMLに直接記述する方法は簡単で手軽に実装することができる。初心者の私にやさしい。また、JavaScriptで定義した関数を呼び出す方法も簡単なコードで再利用しやすい。

    一方、JavaScriptで動的に設定する方法は少々難しく感じるので、どうせならaddEventListenerメソッドを使ったほうがいい。

    なので、addEventListenerメソッドを使う例も後述する。

    HTMLにonclick属性追加で直接指定する方法

    HTML要素の属性としてonclickを直接記述する最もシンプルな方法。HTMLタグの中にonclick属性を追加して、JavaScriptのコードや関数を指定する。

    基本的な使い方

    HTML要素にonclick属性を記述し、直接JavaScriptのコードを書くだけで実行することができる。

    <button onclick="alert('こんにちは!')">クリック</button>

    関数を呼び出す使い方

    JavaScriptに関数を定義しておき、HTML要素のonclick属性でその関数を呼び出す方法。

    次のコードでは、ボタンがクリックされるとJavaScriptで定義した関数のsayHello()またはsayMorning()が実行され、アラートが表示される。より複雑な処理を行いたい場合は、このように関数を定義して呼び出すのが一般的。

    ちなみに、() は必須でそれがないと関数は実行されない。() は「この関数を今すぐ実行して」という命令の記号。

    <button onclick="sayHello()">昼だよ!</button>
    <button onclick="sayMorning()">朝だよ!</button>
    
    <script>
    function sayHello() {
      alert('こんにちは!');
    }
    function sayMorning() {
      alert('おはよう!');
    }
    </script>

    eventオブジェクトを使う使い方

    イベントオブジェクトを使いたい場合は、次のように記述できる。

    <button onclick="showEventInfo(event)">イベント情報</button>
    
    <script>
    function showEventInfo(event) {
      console.log('クリック位置: ', event.clientX, event.clientY);
      console.log('クリックされた要素: ', event.target);
      console.log('イベントタイプ: ', event.type);
    }
    </script>
    ▼擬似Consoleログ▼

    引数を渡す使い方

    関数に引数を渡したい場合は、次のように記述できる。

    <button onclick="greet('田中')">田中さんに挨拶</button>
    <button onclick="greet('佐藤')">佐藤さんに挨拶</button>
    
    <script>
    function greet(name) {
      alert(`こんにちは、${name}さん!`);
    }
    </script>

    this参照の使い方

    クリックした要素自体を参照したい場合はthisを使う。

    次の例は、クリックされた要素自体をthisで参照し関数に渡している。ボタンをクリックするたびに背景色がランダムに変わる。

    <button onclick="changeColor(this)">背景色を変える</button>
    
    <script>
    function changeColor(element) {
      // ランダムな色を生成
      const randomColor = '#' + Math.floor(Math.random()*16777215).toString(16);
      element.style.backgroundColor = randomColor;
    }
    </script>

    ちなみに、changeColor(element)の()内のelementはただの変数名(引数名)であり、好きな名前に変更可能。

    return falseを使う

    リンクのデフォルト動作(ページ遷移)を防ぎたいときは、return falseを使う。
    SEOやアクセシビリティのためにリンクのhref属性は残しつつ、JavaScriptが有効な環境では別の動作をさせたい時に使用する。
    また、JavaScriptが無効な環境では通常のリンクとして機能するため、フォールバック対応にもなる。

    <a href="https://example.com" onclick="return false;">クリックしても移動しない</a>
    
    <!-- または -->
    <a href="https://example.com" onclick="preventDefault(); return false;">クリックしても移動しない</a>
    
    <script>
    function preventDefault() {
      console.log('デフォルト動作がキャンセルされました');
    }
    </script>

    複数の処理を行う使い方(HTMLのみ)

    セミコロンで区切ることで、複数の処理が記述できる。ただし、複雑な処理は次に記述の関数にまとめる方が望ましいかなと。

    <button onclick="console.log('ログを出力'); alert('アラートを表示'); this.textContent = 'クリック済み'; this.style.backgroundColor = 'lightblue'">
      複数処理
    </button>
    ▼擬似Consoleログ▼

    複数の処理を行う使い方(関数呼び込み)

    <button onclick="handleClick(this)">複数処理(関数呼び込み)</button>
    
    <script>
    function handleClick(element) {
      console.log('ログを出力');
      alert('アラートを表示');
      element.textContent = 'クリック済み';
      element.style.backgroundColor = 'lightblue';
    }
    </script>
    ▼擬似Consoleログ▼

    JavaScriptのonclickプロパティで動的に追加する方法

    HTMLには何も書かず、JavaScriptのコードでイベントを追加する方法。JavaScriptのonclickプロパティを使う。

    基本的な使い方

    シンプルに実装できる。

    <button id="myButton">クリック</button>
    
    <script>
    // 要素を取得
    const button = document.getElementById('myButton');
    
    // onclickプロパティに関数を代入
    button.onclick = function() {
      alert('ボタンがクリックされました!');
    };
    </script>

    関数を参照する使い方

    <button id="functionButton">クリック</button>
    
    <script>
    function showMessage() {
      alert('クリックされました!');
    }
    
    // 関数を参照として代入(括弧なし)
    document.getElementById('functionButton').onclick = showMessage;
    </script>

    アロー関数を使う使い方

    <button id="arrowButton">アロー関数</button>
    <button id="arrowButton2">アロー関数2</button>
    
    <script>
    // アロー関数を使用
    document.getElementById('arrowButton').onclick = () => {
      alert('アロー関数が実行されました');
    };
    document.getElementById('arrowButton2').onclick = () => {
      alert('アロー関数その2が実行されました');
    };
    </script>

    複数処理を行う使い方

    <button id="severalButton">複数処理</button>
    
    <script>
    // アロー関数を使用
    document.getElementById('severalButton').onclick = () => {
      console.log('1つ目の処理が実行されました');
      alert('2つ目の処理が実行されました');
      document.getElementById('severalButton').textContent = '処理完了';
    };
    </script>
    ▼擬似Consoleログ▼

    onclickは関数は1つだけ

    上の例では確かに複数の処理が実行されているが、これは「1つの関数内に複数の処理を書いた」だけで、厳密には「複数のイベントリスナーを追加した」わけではないことに注意が必要。

    つまり、onclick属性・onclickプロパティは「複数のイベントリスナー」ではなく「1つのイベントリスナー内での複数処理」しかできないということ。

    「複数のイベントリスナー」を設定したいのであれば、addEventListenerメソッドを使うしかない。

    また、onclick属性・onclickプロパティの場合、新しい処理を設定すると、前の処理は完全に消えてしまう。そう、上書きされてしまうのだ。
    一方のaddEventListenerの場合は、複数の処理を追加でき、すべてが順番に実行される。

    なので、簡単にクリックイベントを実装したいのであればonclickだが、複数イベント設定・オプション指定・保守性などを考えると最初からaddEventListenerを使って実装したほうがいい。

    onclick(後の関数が前の関数を上書き)

    // JavaScript
    const btn = document.getElementById("btn");
    
    btn.onclick = () => {
      console.log("処理1");
    };
    
    btn.onclick = () => {
      console.log("処理2");
    };

    ➡ 実行結果:処理2 だけ(※ 最初の「処理1」は消されてしまう)

    addEventListener(すべての処理が実行される)

    // JavaScript
    const btn = document.getElementById("btn");
    
    btn.addEventListener("click", () => {
      console.log("処理1");
    });
    
    btn.addEventListener("click", () => {
      console.log("処理2");
    });

    ➡ 実行結果:処理1→処理2

    onclick属性<onclickプロパティ

    HTMLのonclick属性で設定した処理は、JavaScriptのonclickプロパティで上書きされてしまう。

    下の例では、onclick属性で設定したalert()は実行されず、onclickプロパティだけが実行される。

    <!-- HTML -->
    <button onclick="alert('こんにちは')">ボタン</button>
    
    <script>
    // 後からJavaScriptで設定すると...
    document.querySelector('button').onclick = function() {
        console.log('こっちだけだよ!');
    };
    // → alert()は実行されなくなる!
    </script>
    ▼擬似Consoleログ▼
    スポンサーリンク

    addEventListenerメソッドを使う

    同じ要素に「複数のイベントリスナー」を追加するなら、addEventListenerメソッドを使う。
    というか、onclickを使わずに最初からaddEventListenerを使ったほうがいい。addEventListenerメソッドは、clickイベントに限らず、すべてのイベント処理において推奨される。

    addEventListenerは、HTML要素にイベント(クリック、キーボード入力、マウス移動など)が発生した時の処理をJavaScriptに登録するメソッド。

    メソッドとは?

    メソッドとは「オブジェクトにくっついている関数」のこと。

    document.querySelector("h1").addEventListener("click", function() {
      alert("クリックされた!");
    });

    この中の「document.querySelector("h1")」 が「h1要素」というオブジェクト。
    そのオブジェクトに付いている関数が addEventListener()。

    つまり、「h1要素に対して、イベントを追加する」機能を持った関数という意味で、
    addEventListener() は h1要素の「メソッド」ということになる。

    基本形

    <button id="eventButton">addEventListener</button>
    
    <script>
    const button = document.getElementById('eventButton');
    
    // addEventListenerを使ってイベントを追加
    button.addEventListener('click', function() {
      alert('addEventListenerでイベントが追加されました!');
    });
    </script>

    複数のイベントリスナーを追加する

    <button id="multiButton">複数のイベント</button>
    
    <script>
    const button = document.getElementById('multiButton');
    
    button.addEventListener('click', function() {
      console.log('1つ目のリスナーが実行されました');
      alert('2つ目のリスナーが実行されました');
      button.textContent = '処理完了';
    });
    </script>
    ▼擬似Consoleログ▼

    イベントオブジェクトを使う

    <button id="eventInfoButton">イベント情報</button>
    
    <script>
    document.getElementById('eventInfoButton').addEventListener('click', function(event) {
      console.log('イベントタイプ:', event.type);
      console.log('クリック位置 X:', event.clientX);
      console.log('クリック位置 Y:', event.clientY);
      console.log('クリックされた要素:', event.target);
    });
    </script>
    ▼擬似Consoleログ▼

    イベントリスナーを削除する

    <button id="removeButton">一度だけクリック可能</button>
    
    <script>
    function oneTimeClick(event) {
      alert('クリックされました!');
      // クリックされたら自分自身を削除
      event.target.removeEventListener('click', oneTimeClick);
    }
    
    document.getElementById('removeButton').addEventListener('click', oneTimeClick);
    </script>

    クリックされた要素を特定する

    「イベント委譲」と呼ばれる手法で、親要素に1つのイベントリスナーを設定するだけで、子要素のクリックを検出できる。

    <div id="container">
      <button class="btn">ボタン1</button>
      <button class="btn">ボタン2</button>
      <button class="btn">ボタン3</button>
    </div>
    
    <script>
    document.getElementById('container').addEventListener('click', function(event) {
      // クリックされた要素を取得
      const clickedElement = event.target;
      
      // ボタンがクリックされた場合のみ処理
      if (clickedElement.classList.contains('btn')) {
        console.log('クリックされたのは: ', clickedElement.textContent);
      }
    });
    </script>
    ▼擬似Consoleログ▼

    複数要素に一括でイベントを追加する

    <div id="buttonsContainer">
      <button class="colorButton">赤</button>
      <button class="colorButton">青</button>
      <button class="colorButton">緑</button>
      <button class="colorButton">黄</button>
    </div>
    
    <script>
    // 全てのボタンを取得
    const buttons = document.querySelectorAll('.colorButton');
    
    // 各ボタンにイベントリスナーを追加
    buttons.forEach(function(button) {
      button.addEventListener('click', function() {
        // ボタンのテキストに応じて色を変更
        if (this.textContent === '赤') {
          this.style.backgroundColor = 'red'; this.style.color = 'white';
        } else if (this.textContent === '青') {
          this.style.backgroundColor = 'blue'; this.style.color = 'white';
        } else if (this.textContent === '緑') {
          this.style.backgroundColor = 'green'; this.style.color = 'white';
        } else if (this.textContent === '黄') {
          this.style.backgroundColor = 'yellow';
        }
      });
    });
    </script>

    動的に生成した要素にイベントを追加する

    <div id="dynamicContainer">
      <button id="addButton">新しいボタンを追加</button>
    </div>
    
    <script>
    document.getElementById('addButton').addEventListener('click', function() {
      // 新しいボタン要素を作成
      newButton.textContent = 'newボタン';
      const newButton = document.createElement('button');
      alert('新しいボタンを追加するよ!');
      
      // ボタンにクリックイベントを追加
      newButton.addEventListener('click', function() {
        alert('newボタンがクリックされたよ!');
      });
      
      // ボタンをDOMに追加
      document.getElementById('dynamicContainer').appendChild(newButton);
    });
    </script>