bugfix> javascript > 投稿

catコンストラクターがあり、すべてのcatオブジェクトにeventListenerを追加したいので、それらをクリックすると、カウンターが増加します。手動でイベントを1つずつ追加したくありません。すべての新しいオブジェクトにイベントを追加する方法はありますか?ありがとう

var counter = document.getElementById("counter").innerHTML;
var Cat = function(name , source , width) {
    this.name = name;
    this.image = new Image(width);
    this.image.src = source;
    document.body.appendChild(this.image);
}
var poplinre = new Cat("Poplinre" , "images/poplinre.jpg" , 500);
var chewie = new Cat("Chewie" , "images/chewie.jpg" , 500);

回答 3 件
  • クリックイベントをグローバルにリッスンし、目的の画像のみをターゲットにできます。この方法は呼ばれますイベントの委任、この記事では説明をします。

    短くするには、 click を聞きます  共通の親ノードでのイベントで、必要な要素のみを対象としますあなたの状況では、次のようなものを実装する必要があります。

    document.body.addEventListener('click', e => {
       if (e.target && e.target.nodeName === 'IMG' &&  e.target.classList.contains('cat')) {
           //only the image is targeted
        }
    });
    var Cat = function(name , source , width) {
        this.name = name;
        this.image = new Image(width);
        this.image.src = source;
        this.image.classList.add('cat'); 
        document.body.appendChild(this.image);
    }
    
    

  • 基本的に2つの選択肢があります。

    Cat 内にハンドラーを個別に追加します  コンストラクタ

    function incrementCounter() {
        document.getElementById("counter").innerHTML = ++counter;
    }
    var Cat = function(name , source , width) {
        this.name = name;
        this.image = new Image(width);
        this.image.src = source;
        this.addEventListener("click", incrementCounter);
        document.body.appendChild(this.image);
    }
    
    

    使用するイベントの委任:猫の画像に特定の特性(クラス名など)を追加し、追加するコンテナに単一のハンドラーを設定します( body  この場合)、ハンドラーを body に配置します 、ただし、イベントが猫の画像の1つを通過した場合にのみインクリメントを実行します。

    document.body.addEventListener("click", function(e) {
        if (e.target.closest(".cat")) {
            document.getElementById("counter").innerHTML = ++counter;
        }
    });
    var Cat = function(name , source , width) {
        this.name = name;
        this.image = new Image(width);
        this.image.src = source;
        this.className = "cat";
        document.body.appendChild(this.image);
    }
    
    

    上記の#2は Element#closest を使用します 、これは漠然と新しいものですが、古い環境ではポリフィルできます。

    実際に、明確な ケース、あなたは Element#closest を必要としません   img 以来  要素には子孫要素を含めることができないため、 e.target.className を見ることができます。  直接。 closest  より一般的なソリューションです(ここでも機能します)。

  • イベントの委任を参照してください。

    Event delegation allows you to avoid adding event listeners to specific nodes; instead, the event listener is added to one parent.

    JavaScriptイベント委任の仕組み

あなたの答え