איך להעביר אירוע כארגומנט למטפל אירועים מקוון ב-JavaScript?


// this e works
document.getElementById("p").oncontextmenu = function(e) {
  e = e || window.event;
  var target = e.target || e.srcElement;
  console.log(target);
};

// this e is undefined
function doSomething(e) {
  e = e || window.event;
  var target = e.target || e.srcElement;
  console.log(target);
}
<p id="p" onclick="doSomething(e)">
  <a href="#">foo</a>
  <span>bar</span>
</p>

יש כמה שאלות דומות שנשאלו.

אבל בקוד שלי, אני מנסה לקבל את האלמנטים הבנים שנלחצו, כמו a או span.

אז מהי הדרך הנכונה להעביר event כארגומנט למטפל באירוע, או איך לקבל את האירוע בתוך המטפל בלי להעביר ארגומנט?

ערוך

אני מודע ל-addEventListener ול-jQuery, אנא ספק פתרון להעברת אירוע ל-inline handler של אירוע.

תשובה #1

עבר את אובייקט event:

<p id="p" onclick="doSomething(event)">

לקבל את האלמנט הילד שנלחץ element (יש להשתמש עם הפרמטר event: )

function doSomething(e) {
    e = e || window.event;
    var target = e.target || e.srcElement;
    console.log(target);
}

לעבור את element עצמו (DOMElement):

<p id="p" onclick="doThing(this)">

ראה דוגמה חיה ב-jsFiddle.

אתה יכול לציין את השם של event כפי שמופיע למעלה, אבל בנוסף המאזין שלך יכול לגשת לפרמטר event כפי שמתואר כאן: "כאשר מטפל האירוע מוגדר כמאפיין HTML, הקוד שצוין נארז לפונקציה עם הפרמטרים הבאים". יש הרבה יותר תיעוד נוסף בקישור.

תשובה #2

אתה לא צריך להעביר את this, כבר יש את אובייקט event שעובר כברירת מחדל אוטומטית, שמכיל את event.target שיש בו את האובייקט שממנו הוא מגיע. אתה יכול להקל על התחביר שלך:

זה :

<p onclick="doSomething()">

יעבוד עם זה:

function doSomething(){
  console.log(event);
  console.log(event.target);
}

אתה לא צריך ליצור מופע של האובייקט event, הוא כבר קיים. נסה את זה. ו-event.target יכיל את כל האובייקט שקרא לו, שאליו הפנית כ"this" קודם.

עכשיו אם אתה מפעיל באופן דינמי את doSomething() ממקום כלשהו בקוד שלך, תבחין ש-event לא מוגדר. זאת בגלל שזה לא הופעל מאירוע של לחיצה. אז אם אתה עדיין רוצה להפעיל באופן מלאכותי את האירוע, פשוט השתמש ב-dispatchEvent:

document.getElementById('element').dispatchEvent(new CustomEvent("click", {'bubbles': true}));

אז doSomething() יראה את event ואת event.target כרגיל!

אין צורך להעביר את this בכל מקום, ואתה יכול לשמור על חתימות הפונקציות שלך נקיות ממידע על חיבור ולפשט את הדברים.

עדכון 2022-10-30:

אני יצרתי קשר עם מישהו מ-WHATWG, ודרך נוספת שבה ניתן לבצע זאת היא למטה, למרות שחלק מה-IDE מדווחים על זה כ"מיושן" למרות שזה לא כזה. אתה יכול להעביר את מילת המפתח "event" (ללא E גדולה) ברשימת הארגומנטים של הקורא שלך, בכל מיקום, ולהשתמש בה כך.

להלן זה יעבוד, a, b, c ו-d הם ארגומנטים נוספים להעביר אם יש, כדי להדגים שהסדר לא חשוב:

<p onclick="doSomething(a,b,event,c,d)">

ובעיצוב הפונקציה שלך, תתפוס זאת בהתאם:

function doSomething(arg1, arg2, arg3, arg4, arg5){} //arg3 would contain the event

ולגשת למאפיינים הרגילים, במקרה זה מכיוון שחיברנו אירוע עם arg3:

console.log(arg3.target)

תשובה #3

מאחר שאירועים מקוונים מבוצעים כפונקציות, ניתן פשוט להשתמש ב-arguments.

<p id="p" onclick="doSomething.apply(this, arguments)">

ו

function doSomething(e) {
  if (!e) e = window.event;
  // 'e' is the event.
  // 'this' is the P element
}

ה'סיבה' שמוזכרת בתשובה המתקבלת היא בעצם השם של הפרמטר שמועבר לפונקציה. אין לה קשר לאירוע הגלובלי.