Hvordan sende et event som argument til en inline event-handler i 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>

Det har blitt stilt noen lignende spørsmål.

Men i koden min prøver jeg å få tak i barneelementer som har blitt klikket, som a eller span.

Så hva er den riktige måten å sende event som et argument til en hendelseshåndterer, eller hvordan få tak i event inne i håndtereren uten å sende et argument?

rediger

Jeg er klar over addEventListener og jQuery, vennligst gi en løsning for å sende hendelse til inline hendelsesbehandler.

Svar #1

å sende event-objektet:

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

for å få det klikkede barn element (bør brukes med event-parameteren:

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

å sende selve elementet (DOMElement):

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

se levende eksempel på jsFiddle.

Du kan spesifisere navnet på event som ovenfor, men alternativt kan din håndterer få tilgang til event-parameteren som beskrevet her: «Når hendelseshåndtereren er spesifisert som et HTML-attributt, pakkes den spesifiserte koden inn i en funksjon med følgende parametere». Det finnes mye mer ekstra dokumentasjon på lenken.

Svar #2

Du trenger ikke å sende this, det er allerede event-objektet som sendes automatisk som standard, som inneholder event.target som har objektet det kommer fra. Du kan forenkle syntaksen din:

Dette :

<p onclick="doSomething()">

Vil jobbe med dette:

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

Du trenger ikke å instansiere event-objektet, det er allerede der. Prøv det ut. Og event.target vil inneholde hele objektet som kaller det, som du tidligere refererte til som «this».

Nå, hvis du dynamisk utløser doSomething() fra et sted i koden din, vil du legge merke til at event er udefinert. Dette er fordi det ikke ble utløst fra en klikkehendelse. Så hvis du fortsatt ønsker å kunstig utløse hendelsen, kan du enkelt bruke dispatchEvent:

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

Da vil doSomething() se event og event.target som vanlig!

Ingen behov for å sende this overalt, og du kan holde funksjonssignaturene dine fri for koblingsinformasjon og forenkle ting.

Oppdatering 2022-10-30:

Jeg har kontaktet noen fra WHATWG, og en annen måte det kan gjøres på er nedenfor, selv om noen IDE-er rapporterer det som "utdatert", noe det ikke er. Du kan sende "event"-nøkkelordet (ingen stor E) i argumentlisten til den som kaller, i hvilken som helst posisjon, og bruke det som sådan.

Nedenfor vil fungere, a, b, c og d er ekstra argumenter som kan sendes hvis noen, for å demonstrere at rekkefølgen ikke spiller noen rolle:

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

Og i funksjonsdefinisjonen din vil du fange det tilsvarende:

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

Og få tilgang til de vanlige egenskapene, i dette tilfellet siden vi koblet hendelsen med arg3:

console.log(arg3.target)

Svar #3

Siden inline-hendelser kjøres som funksjoner, kan du enkelt bruke arguments.

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

og

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

'Hendelsen' som nevnes i det aksepterte svaret er faktisk navnet på argumentet som sendes til funksjonen. Det har ingenting å gjøre med den globale hendelsen.

Relaterte artikler