web-dev-qa-db-ja.com

パラメーターe(イベント)とは正確に何で、なぜJavaScript関数に渡すのですか?

JavaScriptを学んだとき、私が読んだ本やインターネットの記事はすべて、下のコードブロックなどのJavaScriptイベントを処理する関数にパラメーターeを渡すコードを示していました。

function myEvent(e) {
    var evtType = e.type
    alert(evtType)
    // displays click, or whatever the event type was
}

私はいつもそれをありのままに受け入れてきましたが、今、いくつかの質問があります(これは私にとって非常に紛らわしいです):

  1. このeはどこから来たのですか? JavaScriptファイル全体を見ると、eがまったく存在していないようです。
  2. このパラメーターeを関数に渡すのはなぜですか? eを渡さない場合、関数は動作しなくなりますか?
  3. 以下のコードブロックを検討してください。匿名の内部関数に渡されるイベント変数(e)があります。無名関数の外部でイベントオブジェクトを使用するとします(element.onkeypress行の上/下の行にある可能性があります)。これどうやってするの?

    element.onkeypress = function(e) {
        if(e.keyCode) {
            element.keyCode = e.keyCode;
        } else {
            element.keyCode = e.charCode;
        }
    };
    
30
Lord Yggdrasill

eeventの略です

イベントを作成する最も簡単な方法は、ページ上のどこかをクリックすることです。

クリックすると、clickイベントがトリガーされます。このeventは、実際に発生したアクションに関する情報を含むオブジェクトです。この例の場合、イベントにはクリックの座標(_event.screenX_など)、クリックした要素(_event.target_)などの情報が含まれます。

現在、イベントは常に発生しますが、発生するすべてのイベントに関心があるわけではありません。ただし、何らかのイベントに興味がある場合は、イベントリスナーをイベントに作成することがわかっている要素に追加するときになります[1]。たとえば、ユーザーが「サブスクライブ」ボタンをクリックしたときを知りたい場合何かしたい場合このイベントが発生したとき。

このイベントについて何かを行うには、イベントハンドラーを興味のあるボタンにバインドします。ハンドラーを要素にバインドする方法はelement.addEventListener(eventName, handler)を実行します。

eventNameは文字列であり、関心のあるイベントの名前です。この場合、_'click'_(clickイベントの場合)になります。

ハンドラーは単純にfunctionであり、イベントが発生したときに何かを実行します(実行されます)。ハンドラー関数は、デフォルトでは、実行されるとeventオブジェクトが渡されます(対象のイベント/アクションのときに作成されます)起こった)引数として

eventをハンドラー関数のパラメーターとして定義することはオプションですが、場合によっては(ほとんどの場合)、ハンドラー関数が発生したイベントを知っていると便利です。あなたがdoそれを定義するときこれはあなたがあなたのような関数で見るeです前述の。覚えておいてください、eventは通常のjavascriptオブジェクトであり、多くのプロパティがあります。

お役に立てば幸いです。

詳細については、 イベントの作成とトリガー を参照してください。

eはイベントが発生したときにのみ存在するため、3番目の質問については、これができないことを知っておく必要があります。ハンドラー関数を使用して、実行時にeオブジェクトにアクセスし、グローバル変数に格納して処理することができます。

[1]それは正確ではありませんが、理解するのは簡単です。より正確に言うと、「イベントリスナーを、イベントが通過することがわかっている要素に追加する」です。詳細については、 this を参照してください

51

求めるパラメーターeEvent オブジェクトであり、関数を実行させる原因となったイベントを表します。本当にeである必要はありません。他のすべての関数パラメーターと同じように、好きな名前を付けることができます。

  1. これはどこから来たのですか? javascriptファイル全体を見ると、eはまったく存在していないようです

このe変数は、javascriptファイルにはまったくありませんが、コールバック関数を実行するjavascriptエンジンから取得されるため、見つけることができません。

いくつかのイベントにコールバック関数(たとえばelement.onkeypress = function(e) { ... })を与えると、そのイベントが発生したときにコールバック関数を実行/呼び出すときにJavaScriptエンジンに関数を与えます。発生したイベントを表すEventオブジェクト。 Javascriptは、コールバック関数を呼び出すために次のようなことをしている可能性があります。

var e = new Event();
callbackFunction(e);

そして、それがEventオブジェクトeの由来です。

  1. このパラメーターeを関数に渡す理由eを渡さないと、機能は停止しますか?

eパラメーターがなくても、関数は動作を停止しません。ただし、関数の実行を引き起こしたイベントに関する詳細にアクセスする必要がある場合は、eパラメーターを使用してそれらを取得する必要があります。

  1. 以下のコードブロックを検討してください。匿名の内部関数に渡されるイベント変数(e)があります。無名関数の外でイベントオブジェクトを使用したいとしましょう(おそらくelement.onkeypress行の上/下の行にあります)、どうすればいいですか?

コールバック関数のスコープ外の変数に保存しても、これができるとは思いません。これは、関数が宣言されたときにすぐに実行されるのではなく、イベントが発生したとき(たとえば、キーが押され、「keypress」イベントが発生したとき)にのみ実行されるためです。

var event;

element.onkeypress = function(e) {
    event = e;
    ...
};

console.log(event); // => undefined

これが機能する唯一の方法は、event変数を使用するコードも後で、特にonkeypressに指定された匿名関数が実行された後に実行される場合です。したがって、以下のコードが機能します。

var event;

element.onkeypress = function(e) {
    event = e;
    ...
};

setTimeout(function() {
    console.log(event); // => the event object, if the `keypress` event
                        //    fired before `setTimeout` calls this function
}, 100000); // <= set to very large value so that it gets run way way later
9
Arnelle Balane

できるだけ抽象的な方法で説明できるように最善を尽くします。実際の実装は、おそらくはるかに複雑です。したがって、私が使用しようとしている名前は架空のものですが、物事を説明するための良い目的に役立つと思います;)


ブラウザのすべてのノードは、EventEmitterクラスの実装です。このクラスは、events(キー)のペアkey:valueを含むオブジェクトeventTypeを保持します。 listener関数(値)。

EventEmitterクラスで定義されている2つの関数は、addEventListenerfireです。

class EventEmitter {
  constructor(id) {
    this.events = {};
    this.id = id;
  }

  addEventListener(eventType, listener) {
    if (!this.events[eventType]) {
      this.events[eventType] = [];
    }

    this.events[eventType].Push(listener);
  }

  fire(eventType, eventProperties) {
    if (this.events[eventType]) {
      this.events[eventType].forEach(listener => listener(eventProperties));
    }
  }
}

プログラマは、addEventListenerを使用して、目的のlistenerの実行時に起動する目的のeventType関数を登録します。

個別のeventTypeごとに、個別の配列があることに注意してください。この配列は、同じlistenerに対して複数のeventType関数を保持できます。


fireは、ユーザーの操作に応じてブラウザーによって呼び出されます。ブラウザは、実行された対話の種類と実行されたノードを認識します。その知識を使用して、fireおよびeventTypeである適切なパラメーターを使用して、適切なノードでeventPropertiesを呼び出します。

fireは、特定のeventTypeに関連付けられた配列をループします。配列を調べて、listenerを渡しながら、配列内のすべてのeventProperties関数を呼び出します。

これは、特定のeventTypeにのみ登録されているlistener関数が、fireが呼び出されると呼び出される方法です。


以下はデモンストレーションです。このデモには3人の俳優がいます。プログラマー、ブラウザー、およびユーザー。

let button = document.getElementById("myButton"); // Done by the Programmer
let button = new EventEmitter("myButton"); // Done by the Browser somewhere in the background. 


button.addEventListener("click", () =>
  console.log("This is one of the listeners for the click event. But it DOES NOT need the event details.")
); // Done By the Programmer


button.addEventListener("click", e => {
  console.log(
    "This is another listener for the click event! However this DOES need the event details."
  );
  console.log(e);
}); // Done By the Programmer


//User clicks the button


button.fire("click", {
  type: "click",
  clientX: 47,
  clientY: 18,
  bubbles: true,
  manyOthers: "etc"
}); // Done By the Browser in the background

ユーザーがボタンをクリックすると、ブラウザはボタン上のfireを呼び出し、eventTypeおよびeventPropertiesを保持するオブジェクトとして「クリック」を渡します。これにより、「クリック」listenerの下に登録されているすべてのeventType関数が呼び出されます。

ご覧のとおり、ブラウザ[〜#〜] always [〜#〜]eventPropertiesを起動します。プログラマーとして、listener関数でこれらのプロパティを使用しても使用しなくてもかまいません。


Stackoveflowで役立つとわかった回答:

addEventListenerで登録されたイベントはどこに保存されますか?

Javascriptイベントハンドラはどこに保存されますか?

1
Haris Ghauri

addEventListenerを使用してリスナーを追加する場合、関数に渡される最初の引数はEventオブジェクトであるため、eパラメーター(または任意の名前が付けられたもの)に割り当てられます関数の最初のパラメーター)。

0
RobG
  1. これは、JSの仕組みです。イベントコールバックごとにイベントオブジェクトを取得します。イベントに関する多くの情報が含まれています。
  2. 渡さない場合、関数は動作を停止しません。オプションです。続けて、イベントをconsole.log(e)し、イベントオブジェクトとそのプロパティを確認します。それが何であるかを見るとより明確になります。
  3. それを保存することにより、その匿名関数の外で使用できます。例:

    var myEvent;
    
    element.onkeypress = function(e) {
        myEvent = e;
        if(e.keyCode) {
            element.keyCode = e.keyCode;
        } else {
            element.keyCode = e.charCode;
        }
    };
    
    console.log(myEvent);
    

    ただし、イベントオブジェクトは発生した特定のイベントにのみ関連するものであり、本当にそれを行う必要があるかどうかを判断する必要があることを考慮する必要があります。

0
Bata