JavaScriptを学んだとき、私が読んだ本やインターネットの記事はすべて、下のコードブロックなどのJavaScriptイベントを処理する関数にパラメーターe
を渡すコードを示していました。
function myEvent(e) {
var evtType = e.type
alert(evtType)
// displays click, or whatever the event type was
}
私はいつもそれをありのままに受け入れてきましたが、今、いくつかの質問があります(これは私にとって非常に紛らわしいです):
e
はどこから来たのですか? JavaScriptファイル全体を見ると、e
がまったく存在していないようです。e
を関数に渡すのはなぜですか? e
を渡さない場合、関数は動作しなくなりますか?以下のコードブロックを検討してください。匿名の内部関数に渡されるイベント変数(e
)があります。無名関数の外部でイベントオブジェクトを使用するとします(element.onkeypress
行の上/下の行にある可能性があります)。これどうやってするの?
element.onkeypress = function(e) {
if(e.keyCode) {
element.keyCode = e.keyCode;
} else {
element.keyCode = e.charCode;
}
};
e
はevent
の略です
イベントを作成する最も簡単な方法は、ページ上のどこかをクリックすることです。
クリックすると、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 を参照してください
求めるパラメーターe
は Event
オブジェクトであり、関数を実行させる原因となったイベントを表します。本当にe
である必要はありません。他のすべての関数パラメーターと同じように、好きな名前を付けることができます。
このe
変数は、javascriptファイルにはまったくありませんが、コールバック関数を実行するjavascriptエンジンから取得されるため、見つけることができません。
いくつかのイベントにコールバック関数(たとえばelement.onkeypress = function(e) { ... }
)を与えると、そのイベントが発生したときにコールバック関数を実行/呼び出すときにJavaScriptエンジンに関数を与えます。発生したイベントを表すEvent
オブジェクト。 Javascriptは、コールバック関数を呼び出すために次のようなことをしている可能性があります。
var e = new Event();
callbackFunction(e);
そして、それがEvent
オブジェクトe
の由来です。
e
パラメーターがなくても、関数は動作を停止しません。ただし、関数の実行を引き起こしたイベントに関する詳細にアクセスする必要がある場合は、e
パラメーターを使用してそれらを取得する必要があります。
コールバック関数のスコープ外の変数に保存しても、これができるとは思いません。これは、関数が宣言されたときにすぐに実行されるのではなく、イベントが発生したとき(たとえば、キーが押され、「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
できるだけ抽象的な方法で説明できるように最善を尽くします。実際の実装は、おそらくはるかに複雑です。したがって、私が使用しようとしている名前は架空のものですが、物事を説明するための良い目的に役立つと思います;)
ブラウザのすべてのノードは、EventEmitter
クラスの実装です。このクラスは、events
(キー)のペアkey:valueを含むオブジェクトeventType
を保持します。 listener
関数(値)。
EventEmitterクラスで定義されている2つの関数は、addEventListener
とfire
です。
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を使用してリスナーを追加する場合、関数に渡される最初の引数はEventオブジェクトであるため、eパラメーター(または任意の名前が付けられたもの)に割り当てられます関数の最初のパラメーター)。
それを保存することにより、その匿名関数の外で使用できます。例:
var myEvent;
element.onkeypress = function(e) {
myEvent = e;
if(e.keyCode) {
element.keyCode = e.keyCode;
} else {
element.keyCode = e.charCode;
}
};
console.log(myEvent);
ただし、イベントオブジェクトは発生した特定のイベントにのみ関連するものであり、本当にそれを行う必要があるかどうかを判断する必要があることを考慮する必要があります。