Quiero hacer un eventHandler que pase el evento y algunos parámetros. El problema es que la función no obtiene el elemento. Aquí hay un ejemplo:
doClick = function(func){
var elem = .. // the element where it is all about
elem.onclick = function(e){
func(e, elem);
}
}
doClick(function(e, element){
// do stuff with element and the event
});
El 'elem' debe definirse fuera de la función anónima. ¿Cómo puedo usar el elemento pasado dentro de la función anónima? ¿Hay alguna forma de hacer esto?
¿Y qué pasa con addEventListener? Parece que no puedo pasar el evento a través de un addEventListener en absoluto, ¿verdad?
Actualizar
Parecía solucionar el problema con 'esto'
doClick = function(func){
var that = this;
this.element.onclick = function(e){
func(e, that);
}
}
Donde esto contiene este elemento al que puedo acceder en la función.
El addEventListener
Pero me pregunto sobre addEventListener:
function doClick(elem, func){
element.addEventListener('click', func(event, elem), false);
}
javascript
events
event-handling
handler
sebas2day
fuente
fuente
e.target
/e.currentTarget
?Respuestas:
No entiendo exactamente qué está tratando de hacer su código, pero puede hacer que las variables estén disponibles en cualquier controlador de eventos utilizando las ventajas de los cierres de funciones:
function addClickHandler(elem, arg1, arg2) { elem.addEventListener('click', function(e) { // in the event handler function here, you can directly refer // to arg1 and arg2 from the parent function arguments }, false); }
Dependiendo de su situación exacta de codificación, casi siempre puede hacer algún tipo de cierre para preservar el acceso a las variables.
De sus comentarios, si lo que está tratando de lograr es esto:
element.addEventListener('click', func(event, this.elements[i]))
Luego, puede hacer esto con una función autoejecutable (IIFE) que captura los argumentos que desea en un cierre a medida que se ejecuta y devuelve la función del controlador de eventos real:
element.addEventListener('click', (function(passedInElement) { return function(e) {func(e, passedInElement); }; }) (this.elements[i]), false);
Para obtener más información sobre cómo funciona un IIFE, consulte estas otras referencias:
Código de envoltura de Javascript dentro de una función anónima
Expresión de función invocada inmediatamente (IIFE) en JavaScript - Pasando jQuery
¿Cuáles son los buenos casos de uso para las funciones anónimas autoejecutables de JavaScript?
Esta última versión es quizás más fácil de ver lo que está haciendo así:
// return our event handler while capturing an argument in the closure function handleEvent(passedInElement) { return function(e) { func(e, passedInElement); }; } element.addEventListener('click', handleEvent(this.elements[i]));
También es posible usarlo
.bind()
para agregar argumentos a una devolución de llamada. Cualquier argumento que pase.bind()
se antepondrá a los argumentos que tendrá la devolución de llamada. Entonces, podrías hacer esto:elem.addEventListener('click', function(a1, a2, e) { // inside the event handler, you have access to both your arguments // and the event object that the event handler passes }.bind(elem, arg1, arg2));
fuente
element.addEventListener('click', func(event, this.elements[i]))
. Javascript simplemente no funciona de esa manera. Hay otras formas de evitar eso, usando cierres, pero no puede hacerlo de la forma en que escribió. addEventListener llama a su devolución de llamada con exactamente un argumento (el evento) y no puede cambiar eso de ninguna manera.function eventFunction (arg, evt) { console.log(arg[0],arg[1],arg[2]) console.log(evt) } var el = document.getElementById('elementID'); el.addEventListener('click', eventFunction.bind(el,[1,2,3]))
Tenga en cuenta que el argumento del evento siempre es el último en los argumentos de la función y no se declara explícitamente en el método de vinculación.Es una pregunta antigua pero común. Así que déjame agregar este aquí.
Con la sintaxis de la función de flecha , puede lograrlo de una manera más sucinta, ya que está enlazado léxicamente y puede encadenarse.
Una expresión de función de flecha es una alternativa sintácticamente compacta a una expresión de función regular, aunque sin sus propios enlaces a las palabras clave this, argumentos, super o new.target.
const event_handler = (event, arg) => console.log(event, arg); el.addEventListener('click', (event) => event_handler(event, 'An argument'));
Si necesita limpiar el detector de eventos:
// Let's use use good old function sytax function event_handler(event, arg) { console.log(event, arg); } // Assign the listener callback to a variable var doClick = (event) => event_handler(event, 'An argument'); el.addEventListener('click', doClick); // Do some work... // Then later in the code, clean up el.removeEventListener('click', doClick);
Aquí hay una frase loca:
// You can replace console.log with some other callback function el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));
Versión más dócil : más apropiada para cualquier trabajo en su sano juicio.
el.addEventListener('click', (event) => ((arg) => { console.log(event, arg); })('An argument'));
fuente
this
y el controlador pudo acceder a lo que necesita.Algo que puedes probar es usar el método de vinculación, creo que esto logra lo que estabas pidiendo. Si nada más, sigue siendo muy útil.
function doClick(elem, func) { var diffElem = document.getElementById('some_element'); //could be the same or different element than the element in the doClick argument diffElem.addEventListener('click', func.bind(diffElem, elem)) } function clickEvent(elem, evt) { console.log(this); console.log(elem); // 'this' and elem can be the same thing if the first parameter // of the bind method is the element the event is being attached to from the argument passed to doClick console.log(evt); } var elem = document.getElementById('elem_to_do_stuff_with'); doClick(elem, clickEvent);
fuente
Dada la actualización de la pregunta original, parece que hay problemas con el contexto ("esto") al pasar los controladores de eventos. Los conceptos básicos se explican, por ejemplo, aquí http://www.w3schools.com/js/js_function_invocation.asp
Una versión funcional simple de su ejemplo podría leer
var doClick = function(event, additionalParameter){ // do stuff with event and this being the triggering event and caller } element.addEventListener('click', function(event) { var additionalParameter = ...; doClick.call(this, event, additionalParameter ); }, false);
Consulte también Javascript call () & apply () vs bind ()?
fuente
Respuesta corta:
x.addEventListener("click", function(e){myfunction(e, param1, param2)}); ... function myfunction(e, param1, param1) { ... }
fuente
param1
oparam2
. Si esos valores cambian, no se establecerán en el valor que tenían durante el tiempo que se creó el controlador de eventos. Se establecerán solo en el valor actual. Además, esto no es diferente de establecer una variable fuera del alcance de la función de escucha de eventos y hacer referencia a esa variable en el controlador de eventos, por lo que no logra pasar parámetros en absoluto.param1
esnoodle
la primera vez que se llama a addEventListener, y la segunda vez que lo llama,param
escheese
entonces cuando el detector de eventos se activaclick
,param1
se establecerá encheese
y nonoodle
. Por lo tanto, no utiliza un "cierre" para recordar el valor que existía en el momento en que se agregó el detector de eventos. Hay escenarios en los que el detector de eventos debe agregarse varias veces y no es necesario ilustrarlo para que mi punto sea válido.this
dentro dedoThings
está el objeto de la ventana. Prueba esto en su lugar:var doThings = function (element) { var eventHandler = function(ev, func){ if (element[ev] == undefined) { return; } element[ev] = function(e){ func(e, element); } }; return { eventHandler: eventHandler }; };
fuente
let obj = MyObject(); elem.someEvent( function(){ obj.func(param) } ); //calls the MyObject.func, passing the param.
fuente