Eu quero fazer um eventHandler que passa o evento e alguns parâmetros. O problema é que a função não obtém o elemento. Aqui está um exemplo:
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
});
O 'elem' deve ser definido fora da função anônima. Como posso obter o elemento passado para usar na função anônima? Existe uma maneira de fazer isso?
E quanto ao addEventListener? Parece que não consigo passar o evento por um addEventListener, não é?
Atualizar
Parece que resolvi o problema com 'isso'
doClick = function(func){
var that = this;
this.element.onclick = function(e){
func(e, that);
}
}
Onde ele contém este elemento que posso acessar na função.
O addEventListener
Mas estou me perguntando sobre o addEventListener:
function doClick(elem, func){
element.addEventListener('click', func(event, elem), false);
}
javascript
events
event-handling
handler
sebas2day
fonte
fonte
e.target
/e.currentTarget
?Respostas:
Não entendo exatamente o que seu código está tentando fazer, mas você pode disponibilizar variáveis em qualquer manipulador de eventos usando as vantagens de encerramentos de função:
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); }
Dependendo da sua situação de codificação exata, você pode quase sempre fazer algum tipo de fechamento para preservar o acesso às variáveis para você.
A partir de seus comentários, se o que você está tentando realizar é o seguinte:
element.addEventListener('click', func(event, this.elements[i]))
Então, você poderia fazer isso com uma função autoexecutável (IIFE) que captura os argumentos que você deseja em um encerramento à medida que executa e retorna a função real do manipulador de eventos:
element.addEventListener('click', (function(passedInElement) { return function(e) {func(e, passedInElement); }; }) (this.elements[i]), false);
Para obter mais informações sobre como funciona um IIFE, consulte estas outras referências:
Código de empacotamento Javascript dentro da função anônima
Expressão de Função Imediatamente Invocada (IIFE) em JavaScript - Passando jQuery
Quais são bons casos de uso para funções anônimas autoexecutáveis de JavaScript?
Esta última versão talvez seja mais fácil de ver o que está fazendo assim:
// 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]));
Também é possível usar
.bind()
para adicionar argumentos a um retorno de chamada. Quaisquer argumentos que você passar.bind()
serão acrescentados aos argumentos que o próprio retorno de chamada terá. Então, você pode fazer isso: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));
fonte
element.addEventListener('click', func(event, this.elements[i]))
. Javascript simplesmente não funciona dessa forma. Existem outras maneiras de contornar isso, usando encerramentos, mas você não pode fazer da maneira que escreveu. addEventListener chama seu retorno de chamada com exatamente um argumento (o evento) e você não pode alterar isso de forma alguma.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]))
Observe que o argumento do evento é sempre o último nos argumentos da função e não é declarado explicitamente no método de vinculação.É uma pergunta antiga, mas comum. Então, deixe-me adicionar este aqui.
Com a sintaxe da função de seta, você pode obtê-la de maneira mais sucinta, pois é ligada lexicamente e pode ser encadeada.
Uma expressão de função de seta é uma alternativa sintaticamente compacta para uma expressão de função regular, embora sem seus próprios vínculos com as palavras-chave this, arguments, super ou new.target.
const event_handler = (event, arg) => console.log(event, arg); el.addEventListener('click', (event) => event_handler(event, 'An argument'));
Se você precisar limpar o ouvinte de evento:
// 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);
Aqui está uma frase maluca:
// You can replace console.log with some other callback function el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));
Versão mais dócil : Mais apropriada para qualquer trabalho sensato.
el.addEventListener('click', (event) => ((arg) => { console.log(event, arg); })('An argument'));
fonte
this
e o manipulador pode acessar o que precisa.Algo que você pode tentar é usar o método bind, acho que isso atinge o que você estava pedindo. No mínimo, ainda é muito ú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);
fonte
Dada a atualização da pergunta original, parece que há problemas com o contexto ("this") ao passar os manipuladores de eventos. Os princípios básicos são explicados, por exemplo, aqui http://www.w3schools.com/js/js_function_invocation.asp
Uma versão simples de trabalho do seu exemplo poderia ler
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);
Veja também Javascript call () & apply () vs bind ()?
fonte
Resposta curta:
x.addEventListener("click", function(e){myfunction(e, param1, param2)}); ... function myfunction(e, param1, param1) { ... }
fonte
param1
ouparam2
. Se esses valores mudarem, eles não serão configurados com o valor que estavam durante o tempo em que o manipulador de eventos foi criado. Eles serão definidos apenas para o valor atual. Além disso, isso não é diferente de definir uma variável fora do escopo da função de ouvinte de evento e fazer referência a essa variável no manipulador de eventos, portanto, não é possível passar parâmetros.param1
fornoodle
a primeira vez que addEventListener é chamado, e a segunda vez que você o chama,param
écheese
sempre que o ouvinte de eventoclick
dispara,param1
será definido comocheese
e nãonoodle
. Portanto, ele não usa um "encerramento" para lembrar o valor que existia no momento da inclusão do ouvinte de evento. Existem cenários em que o ouvinte de evento deve ser adicionado várias vezes que não precisam ser ilustrados para que meu argumento seja válido.this
dentro dedoThings
está o objeto janela. Em vez disso, tente isto:var doThings = function (element) { var eventHandler = function(ev, func){ if (element[ev] == undefined) { return; } element[ev] = function(e){ func(e, element); } }; return { eventHandler: eventHandler }; };
fonte
let obj = MyObject(); elem.someEvent( function(){ obj.func(param) } ); //calls the MyObject.func, passing the param.
fonte