- Sim, a função espera receber
event
, mas você não tem um event
pra passar pra ela. - Não, o argumento
event
não vai ser sempre passado pra uma função que tenha declarado que aceita recebê-lo, até porque uma função pode aceitar receber qualquer coisa como argumento, o nome não importa. - Esse objeto
event
que é passado para sua função não é uma característica do JavaScript. Quem cuida disso é o navegador.
No navegador, eventos estão acontecendo (sendo disparados) a todo instante: quando uma página termina de carregar, quando uma tecla do teclado é pressionada, quando o ponteiro do mouse passa por cima de elementos, etc.
Eventos são objetos com várias propriedades, são informações sobre uma ação que ocorreu dentro do navegador. Por exemplo, em um evento de click
, o navegador cria um objeto event
que vai ter informações como: coordenadas da tela onde o click aconteceu (event.screenX
/ event.screenY
), o elemento que foi alvo do click (event.target
), entre outos.
Estes eventos são disparados em elementos do DOM, DOM é a sigla para Document Object Model (Modelo de objeto de documento), ou seja, é uma representação em memória, e em objeto, de uma página HTML. Cada nó desse objeto é um elemento da página representado como objeto. É exatamente por isso que você consegue fazer botao.addEventListener
, addEventListener
é uma das propriedades do elemento do DOM que você guardou na variável botao
.
Veja a seguinte página em HTML:
<html>
<head>
</head>
<body>
<button id="botao">Meu Botão</button>
</body>
</html>
É muito mais complexo, mas tente imaginar que o DOM é simplesmente um objeto que a representa dessa maneira:
window = {
document: {
childNodes: {
0: {
localName: "html",
childNodes: {
0: { localName: "head" },
1: {
localName: "body",
childNodes: {
0: {
localName: "button",
id: "botao",
innerText: "Meu Botão",
addEventListener: function () {}
}
}
}
}
}
}
}
}
Coloquei a propriedade addEventListener
no elemento 0
que representa o botão, para ficar mais simples de entender, no entanto a propriedade addEventListener não está ali. Justamanete por ser uma função que é igual pra vários elementos do DOM, ela está em um outro objeto, neste caso os elementos do DOM delegam a responsabilidade de chamar essa função para esse objeto.
Esse objeto que possui a função addEventListener
é um objeto EventTarget
(alvo de evento). Ele também possui as funções removeEventListener
e dispatchEvent
.
Muitos elementos do DOM delegam para este objeto, por isso podemos dizer que estes elementos também são EventTarget
's, isso é um pouco parecido com o conceito de herança em outras linguagens orientadas a objetos, como Java e C#.
No exemplo do botão, um elemento button
é um EventTarget
, por isso você pode adicionar ouvidores de eventos a ele, remover ouvidores de eventos, e despachar eventos a partir dele.
No site da Mozilla, há um exemplo de implementação do objeto EventTarget
.
A função addEventListener
basicamente cria um array para o tipo de evento que você passou pra ela, e guarda a sua função ouvidora nesse array.
Veja a função dispatchEvent
:
EventTarget.prototype.dispatchEvent = function(event) {
if (!(event.type in this.listeners)) {
return true;
}
var stack = this.listeners[event.type];
for (var i = 0, l = stack.length; i < l; i++) {
stack[i].call(this, event);
}
return !event.defaultPrevented;
};
Veja que essa função recebe um event
como argumento, ela basicamente irá passar pelo array de ouvidores (funções que foram previamente adicionadas como ouvidoras deste elemento), e executará essas funções ouvidoras, passando pra elas o mesmo event
que ela havia recebido como argumento.
Então esse é o cara que passa o event
pra sua função.
Mas quem passou o event
pra dispatchEvent
? O navegador. É uma lógica implementada pelo navegador que quando um evento acontecer ele cria um objeto de evento e dispara o evento ocorrido usando a função dispathcEvent
. Nesse momento os ouvidores serão executados e receberão event
.
E se você achar necessário (mas acredito que isso não costuma acontecer muito) você pode criar seus eventos e despachá-los em um momento, caso você tenha adicionado ouvidores a este evento, eles serão executados. Se tiver interesse dê uma olhada na página Creating and triggering events da Mozilla.