¿Cómo pasar un evento como argumento a un controlador de eventos en línea en 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>Se han hecho algunas preguntas similares.
Pero en mi código, estoy intentando obtener los elementos hijo que han sido clickeados, como a o span.
¿Cuál es la manera correcta de pasar event como argumento al controlador de eventos, o cómo obtener el evento dentro del controlador sin pasar un argumento?
editar
Estoy al tanto de addEventListener y jQuery, por favor proporciona una solución para pasar un evento al manejador de eventos inline.
Respuesta #1
para pasar el objeto event:
<p id="p" onclick="doSomething(event)">
para obtener el elemento hijo clicado (debe usarse con el parámetro event:
function doSomething(e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(target);
}
pasar el elemento en sí (DOMElement):
<p id="p" onclick="doThing(this)">
ver ejemplo en vivo en jsFiddle.
Puedes especificar el nombre del evento como se indicó arriba, pero alternativamente tu manejador puede acceder al parámetro evento como se describe aquí: "Cuando el manejador de eventos se especifica como un atributo HTML, el código especificado se envuelve en una función con los siguientes parámetros". Hay mucha más documentación adicional en el enlace.
Respuesta #2
No necesitas pasar this, ya que el objeto event se pasa automáticamente por defecto, el cual contiene event.target que tiene el objeto desde el cual proviene. Puedes simplificar tu sintaxis:
Esto :
<p onclick="doSomething()">
Trabajará con esto:
function doSomething(){
console.log(event);
console.log(event.target);
}
No necesitas instanciar el objeto event, ya está ahí. Pruébalo. Y event.target contendrá todo el objeto que lo llama, al que antes te referías como "this".
Ahora, si activas dinámicamente doSomething() desde algún lugar de tu código, notarás que event está indefinido. Esto se debe a que no se activó desde un evento de clic. Por lo tanto, si aún deseas activar el evento de manera artificial, simplemente usa dispatchEvent:
document.getElementById('element').dispatchEvent(new CustomEvent("click", {'bubbles': true}));
¡Entonces doSomething() verá event y event.target como de costumbre!
No es necesario pasar this por todas partes, y puedes mantener las firmas de tus funciones libres de información de conexión y simplificar las cosas.
Actualización 30-10-2022:
He contactado a alguien de WHATWG, y otra forma en que podría hacerse está a continuación, aunque algunos IDE lo reportan como "obsoleto", lo cual no es. Podrías pasar la palabra clave "event" (sin E mayúscula) en la lista de argumentos de tu llamada, en cualquier posición, y usarla como tal.
Lo siguiente funcionaría, siendo a, b, c y d argumentos adicionales a pasar si los hay, para demostrar que el orden no importa:
<p onclick="doSomething(a,b,event,c,d)">
Y en la definición de tu función, lo capturarías en consecuencia:
function doSomething(arg1, arg2, arg3, arg4, arg5){} //arg3 would contain the event
Y accede a las propiedades habituales, en este caso, ya que conectamos el evento con arg3:
console.log(arg3.target)
Respuesta #3
Dado que los eventos en línea se ejecutan como funciones, simplemente puedes usar arguments.
<p id="p" onclick="doSomething.apply(this, arguments)">
y
function doSomething(e) {
if (!e) e = window.event;
// 'e' is the event.
// 'this' is the P element
}
El 'evento' que se menciona en la respuesta aceptada es en realidad el nombre del argumento pasado a la función. No tiene nada que ver con el evento global.
