addEventListener vs onclick

704

Qual é a diferença entre addEventListenere onclick?

var h = document.getElementById("a");
h.onclick = dothing1;
h.addEventListener("click", dothing2);

O código acima reside juntos em um arquivo .js separado, e ambos funcionam perfeitamente.

William Sham
fonte

Respostas:

956

Ambos estão corretos, mas nenhum deles é "melhor" por si só, e pode haver um motivo para o desenvolvedor escolher usar as duas abordagens.

Ouvintes de Eventos (addEventListener e attachEvent do IE)

As versões anteriores do Internet Explorer implementam o javascript de maneira diferente de praticamente qualquer outro navegador. Com versões menores que 9, você usa o método attachEvent[ doc ], assim:

element.attachEvent('onclick', function() { /* do stuff here*/ });

Na maioria dos outros navegadores (incluindo o IE 9 e superior), você usa addEventListener[ doc ], assim:

element.addEventListener('click', function() { /* do stuff here*/ }, false);

Usando essa abordagem ( eventos DOM Nível 2 ), você pode anexar um número teoricamente ilimitado de eventos a qualquer elemento. A única limitação prática é a memória do lado do cliente e outras preocupações de desempenho, que são diferentes para cada navegador.

Os exemplos acima representam o uso de uma função anônima [ doc ]. Você também pode adicionar um ouvinte de evento usando uma referência de função [ doc ] ou um encerramento [ doc ]:

var myFunctionReference = function() { /* do stuff here*/ }

element.attachEvent('onclick', myFunctionReference);
element.addEventListener('click', myFunctionReference , false);

Outra característica importante addEventListeneré o parâmetro final, que controla como o ouvinte reage a eventos de bolhas [ doc ]. Passei falso nos exemplos, o que é padrão para provavelmente 95% dos casos de uso. Não há argumento equivalente para attachEvent, ou ao usar eventos embutidos.

Eventos embutidos (HTML onclick = "" propriedade e element.onclick)

Em todos os navegadores que suportam javascript, você pode colocar um ouvinte de eventos em linha, o que significa diretamente no código HTML. Você provavelmente já viu isso:

<a id="testing" href="#" onclick="alert('did stuff inline');">Click me</a>

Os desenvolvedores mais experientes evitam esse método, mas ele faz o trabalho; é simples e direto. Você não pode usar encerramentos ou funções anônimas aqui (embora o próprio manipulador seja uma espécie de função anônima) e seu controle do escopo seja limitado.

O outro método que você menciona:

element.onclick = function () { /*do stuff here */ };

... é o equivalente a javascript embutido, exceto que você tem mais controle do escopo (já que está escrevendo um script em vez de HTML) e pode usar funções anônimas, referências de função e / ou fechamentos.

A desvantagem significativa dos eventos embutidos é que, diferentemente dos ouvintes de eventos descritos acima, você pode ter apenas um evento embutido atribuído. Eventos embutidos são armazenados como um atributo / propriedade do elemento [ doc ], o que significa que ele pode ser substituído.

Usando o exemplo <a>do HTML acima:

var element = document.getElementById('testing');
element.onclick = function () { alert('did stuff #1'); };
element.onclick = function () { alert('did stuff #2'); };

... quando você clica no elemento, você vê apenas "Did stuff # 2" - você substituiu o primeiro atribuído da onclickpropriedade pelo segundo valor e também substituiu a onclickpropriedade HTML embutida original . Confira aqui: http://jsfiddle.net/jpgah/ .

De um modo geral, não use eventos embutidos . Pode haver casos de uso específicos, mas se você não tiver 100% de certeza de que possui esse caso de uso, não precisará e não deverá usar eventos em linha.

Javascript moderno (angular e similares)

Desde que esta resposta foi postada originalmente, as estruturas javascript como Angular tornaram-se muito mais populares. Você verá um código como este em um modelo Angular:

<button (click)="doSomething()">Do Something</button>

Parece um evento embutido, mas não é. Esse tipo de modelo será transpilado para um código mais complexo que usa ouvintes de eventos nos bastidores. Tudo o que escrevi sobre eventos aqui ainda se aplica, mas você é removido do âmago da questão por pelo menos uma camada. Você deve entender as porcas e os parafusos, mas se as práticas recomendadas da estrutura JS moderna envolvem a gravação desse tipo de código em um modelo, não sinta que você está usando um evento embutido - não está.

Qual é melhor?

A questão é uma questão de compatibilidade e necessidade do navegador. Você precisa anexar mais de um evento a um elemento? Você vai no futuro? As probabilidades são, você vai. attachEvent e addEventListener são necessários. Caso contrário, um evento em linha pode parecer que eles resolveriam o problema, mas você está muito melhor preparado para um futuro que, embora possa parecer improvável, é previsível pelo menos. Há uma chance de você precisar mudar para ouvintes de eventos baseados em JS, então é melhor começar por aí. Não use eventos embutidos.

O jQuery e outras estruturas javascript encapsulam as diferentes implementações de navegador dos eventos do nível DOM 2 em modelos genéricos, para que você possa escrever código compatível com o navegador sem ter que se preocupar com a história do IE como rebelde. O mesmo código com o jQuery, todo o navegador e pronto para o rock:

$(element).on('click', function () { /* do stuff */ });

Porém, não se esgote e obtenha uma estrutura apenas para isso. Você pode facilmente rolar seu próprio pequeno utilitário para cuidar dos navegadores mais antigos:

function addEvent(element, evnt, funct){
  if (element.attachEvent)
   return element.attachEvent('on'+evnt, funct);
  else
   return element.addEventListener(evnt, funct, false);
}

// example
addEvent(
    document.getElementById('myElement'),
    'click',
    function () { alert('hi!'); }
);

Experimente: http://jsfiddle.net/bmArj/

Levando tudo isso em consideração, a menos que o script que você está vendo tenha levado em consideração as diferenças do navegador de outra maneira (no código não mostrado na sua pergunta), a parte usada addEventListenernão funcionaria nas versões do IE inferiores a 9.

Documentação e Leitura Relacionada

Chris Baker
fonte
14
desculpe a bater, mas só queria dar uma versão condensada da sua função (violino: jsfiddle.net/bmArj/153 ) -function addEvent(element, myEvent, fnc) { return ((element.attachEvent) ? element.attachEvent('on' + myEvent, fnc) : element.addEventListener(myEvent, fnc, false)); }
Deryck
10
@Gaurav_soni No. O nome da função e todo o código que ela contém já estão expostos no arquivo javascript, que está em texto sem formatação. Qualquer pessoa pode abrir um console da web e executar ou manipular qualquer javascript. Se o seu javascript contiver algo que possa ser um risco de segurança se for exposto ao público, você terá um grande problema porque já está exposto ao público.
Chris Baker
4
Enquanto estivermos condensando esse algoritmo, podemos ir até o fim: function addEvent(e,n,f){return e.attachEvent?e.attachEvent('on'+n,f):e.addEventListener(n,f,!!0)}<< Com 98 caracteres, este é mais do que 40% menor!
Trevor
3
@ Trevor Por curiosidade, por que !! 0? Por que não! 1 ou apenas 0?
Chris Baker
2
@AdrianMoisa Esta resposta foi escrita no momento em que o AngularJS era algo novo em ascensão, e a prática comum ainda era "aprimoramento progressivo" - ou seja, escrever um documento HTML de uma maneira que funcionasse com ou sem javascript. Nessa perspectiva, a associação de eventos do javascript seria uma prática recomendada. Hoje em dia, acho que muitas pessoas não se preocupam muito com o aprimoramento progressivo, principalmente sem considerar a prevalência de coisas como o Angular. Ainda há argumentos de separação de preocupações sobre eventos em linha (não usando Angular), mas isso é mais estilo do que substância.
Chris Baker
193

A diferença que você poderia ver se tivesse outras funções:

var h = document.getElementById('a');
h.onclick = doThing_1;
h.onclick = doThing_2;

h.addEventListener('click', doThing_3);
h.addEventListener('click', doThing_4);

As funções 2, 3 e 4 funcionam, mas 1 não. Isso ocorre porque addEventListenernão substitui os manipuladores de eventos existentes, enquanto onclicksubstitui os onclick = fnmanipuladores de eventos existentes .

A outra diferença significativa, é claro, é que onclicksempre funcionará, enquanto addEventListenernão funciona no Internet Explorer antes da versão 9. Você pode usar o análogo attachEvent(que tem sintaxe um pouco diferente) no IE <9.

lonesomeday
fonte
18
Essa é uma explicação muito clara! Direito ao ponto. Portanto, se eu precisar de várias funções para um evento, fico com addEventListener e preciso escrever mais código para o attachEvent apenas para acomodar o IE.
William Sham
4
2, 3 e 4 devem ser nomeados como algo. 1 é substituído por 2 e nunca é chamado.
DragonLord 07/01
De fato, uma explicação muito clara e objetiva. Seja ele que iria realmente fazer muito mais sentido para citar as funções 'doThing_1', etc. (Se você ainda quer atender a IE <9, ver a resposta de Chris.)
Frank Conijn
61

Nesta resposta, descreverei os três métodos de definição de manipuladores de eventos DOM.

element.addEventListener()

Exemplo de código:

element.addEventListener() tem várias vantagens:

  • Permite registrar manipuladores de eventos ilimitados e removê-los com element.removeEventListener().
  • Possui useCaptureparâmetro, que indica se você deseja manipular o evento em sua fase de captura ou bolha . Consulte: Não é possível entender o atributo useCapture em addEventListener .
  • Se preocupa com a semântica . Basicamente, torna o registro de manipuladores de eventos mais explícito. Para um iniciante, uma chamada de função torna óbvio que algo acontece , enquanto a atribuição de evento a alguma propriedade do elemento DOM é pelo menos não intuitiva.
  • Permite separar a estrutura do documento (HTML) e a lógica (JavaScript) . Em aplicações web pequenas possa não parecer à matéria, mas faz importa com qualquer projeto maior. É muito mais fácil manter um projeto que separa estrutura e lógica do que um projeto que não.
  • Elimina a confusão com nomes de eventos corretos. Devido ao uso de ouvintes de eventos em linha ou à atribuição de ouvintes de eventos a .oneventpropriedades de elementos DOM, muitos programadores JavaScript inexperientes pensam que o nome do evento é por exemplo onclickou onload. oné não uma parte do nome do evento . Os nomes de eventos corretos são clicke load, e é assim que os nomes dos eventos são passados .addEventListener().
  • Funciona em quase todos os navegadores . Se você ainda precisar oferecer suporte ao IE <= 8, poderá usar um polyfill do MDN .

element.onevent = function() {}(por exemplo onclick, onload)

Exemplo de código:

Essa era uma maneira de registrar manipuladores de eventos no DOM 0. Agora é desencorajado, porque:

  • Permite registrar apenas um manipulador de eventos. A remoção do manipulador atribuído também não é intuitiva, porque para remover o manipulador de eventos atribuído usando esse método, você deve reverter a oneventpropriedade de volta ao seu estado inicial (ou seja null).
  • Não responde a erros adequadamente. Por exemplo, se você atribuir uma sequência por engano a window.onload, por exemplo:, window.onload = "test";ela não emitirá erros. Seu código não funcionaria e seria muito difícil descobrir o porquê. .addEventListener()no entanto, geraria um erro (pelo menos no Firefox): TypeError: O argumento 2 do EventTarget.addEventListener não é um objeto .
  • Não fornece uma maneira de escolher se você deseja manipular o evento em sua fase de captura ou bolha.

Manipuladores de eventos embutidos ( oneventatributo HTML)

Exemplo de código:

Da mesma forma element.onevent, agora é desencorajado. Além dos problemas que element.oneventtem, ele:

  • É um possível problema de segurança , porque torna o XSS muito mais prejudicial. Atualmente, os sites devem enviar o Content-Security-Policycabeçalho HTTP adequado para bloquear scripts embutidos e permitir scripts externos apenas de domínios confiáveis. Vejo Como a política de segurança de conteúdo funciona?
  • Não separa a estrutura e a lógica do documento .
  • Se você gerar sua página com um script do lado do servidor e, por exemplo, gerar cem links, cada um com o mesmo manipulador de eventos embutido, seu código será muito mais longo do que se o manipulador de eventos fosse definido apenas uma vez. Isso significa que o cliente teria que baixar mais conteúdo e, como resultado, seu site seria mais lento.

Veja também

Michał Perłakowski
fonte
22

Embora onclickfuncione em todos os navegadores, addEventListenernão funciona em versões mais antigas do Internet Explorer, que usa em seu attachEventlugar.

A desvantagem onclické que só pode haver um manipulador de eventos, enquanto os outros dois acionarão todos os retornos de chamada registrados.

Magnar
fonte
12

Até onde eu sei, o evento "load" do DOM ainda funciona apenas muito limitado. Isso significa que ele só vai disparar para o window object, imagese <script>elementos por exemplo. O mesmo vale para a onloadatribuição direta . Não há diferença técnica entre os dois. Provavelmente.onload = tem uma melhor disponibilidade entre navegadores.

No entanto, você não pode atribuir um load eventa um <div>ou <span>elemento ou outros enfeites.

jAndy
fonte
9

Resumo:

  1. addEventListenerpode adicionar vários eventos, enquanto que com onclickisso não pode ser feito.
  2. onclickpode ser adicionado como um HTMLatributo, enquanto um addEventListenersó pode ser adicionado dentro de <script>elementos.
  3. addEventListener pode aceitar um terceiro argumento que pode interromper a propagação do evento.

Ambos podem ser usados ​​para manipular eventos. No entanto, addEventListenerdeve ser a escolha preferida, pois pode fazer tudo onclick e muito mais. Não use inline onclickcomo atributos HTML, pois isso mistura o javascript e o HTML, o que é uma prática ruim. Isso torna o código menos sustentável.

Willem van der Veen
fonte
E como é feito, principalmente, o direcionamento do seu elemento? Quero dizer, eu não vou usar pessoalmente onclickhandlrs em linha com medo de rir da sala - mas geralmente os eventos são vinculados de maneiras muito piores e menos fáceis nos últimos anos. Classes como js-link, js-form-validationou atributos de dados com data-jspackage="init", não são de forma alguma melhores ... E com quantos anos você realmente usa a bolha de eventos? Pessoalmente, eu adoraria poder escrever um manipulador sem verificar se o alvo é realmente compatível com o meu elemento - ou ter que interromper a propagação em vários lugares devido a erros aleatórios.
Christoffer Bubach 01/12/19
3

Um detalhe ainda não foi observado: os navegadores de desktop modernos consideram que diferentes pressionamentos de botão são "cliques" para AddEventListener('click'e onclickpor padrão.

  • No Chrome 42 e IE11, ambos onclicke AddEventListenerclique em disparar no clique esquerdo e do meio.
  • No Firefox 38, é onclickacionado apenas no clique esquerdo, mas o AddEventListenerclique é acionado nos cliques esquerdo, central e direito.

Além disso, o comportamento do clique do meio é muito inconsistente entre os navegadores quando há cursores de rolagem:

  • No Firefox, os eventos do meio do mouse sempre são acionados.
  • No Chrome, eles não serão acionados se o clique do meio abrir ou fechar um cursor de rolagem.
  • No IE, eles disparam quando o cursor de rolagem é fechado, mas não quando ele é aberto.

Também é importante notar que os eventos "clique" para qualquer elemento HTML selecionável pelo teclado, como inputtambém são acionados no espaço ou entram quando o elemento é selecionado.

um convidado
fonte
2

Javascript tende a misturar tudo em objetos e isso pode torná-lo confuso. Tudo em um é a maneira JavaScript.

Essencialmente, onclick é um atributo HTML. Por outro lado, addEventListener é um método no objeto DOM que representa um elemento HTML.

Nos objetos JavaScript, um método é meramente uma propriedade que tem uma função como valor e que funciona contra o objeto ao qual está anexado (usando isso por exemplo).

No JavaScript, o elemento HTML representado pelo DOM terá seus atributos mapeados para suas propriedades.

É aqui que as pessoas ficam confusas porque o JavaScript mescla tudo em um único contêiner ou espaço para nome sem nenhuma camada de indireção.

Em um layout OO normal (que mescla pelo menos o espaço para nome das propriedades / métodos), você pode ter algo como:

domElement.addEventListener // Object(Method)
domElement.attributes.onload // Object(Property(Object(Property(String))))

Existem variações como ele poderia usar um getter / setter para onload ou HashMap para atributos, mas, no final das contas, seria assim. O JavaScript eliminou essa camada de indireção na expectativa de saber o que é o que há entre outras coisas. Ele mesclou domElement e atributos.

Para impedir a compatibilidade, como prática recomendada, use addEventListener. Como outras respostas falam sobre as diferenças a esse respeito, e não sobre as diferenças programáticas fundamentais, vou renunciar a isso. Essencialmente, em um mundo ideal, você realmente deve usar apenas * do HTML, mas em um mundo ainda mais ideal, você não deve fazer nada parecido com o HTML.

Por que é dominante hoje? É mais rápido de escrever, mais fácil de aprender e tende a funcionar.

O ponto principal da carga no HTML é conceder acesso ao método ou funcionalidade addEventListener em primeiro lugar. Ao usá-lo em JS, você está passando por HTML quando pode aplicá-lo diretamente.

Hipoteticamente, você pode criar seus próprios atributos:

$('[myclick]').each(function(i, v) {
     v.addEventListener('click', function() {
         eval(v.myclick); // eval($(v).attr('myclick'));
     });
});

O que JS faz é um pouco diferente disso.

Você pode equiparar a algo como (para cada elemento criado):

element.addEventListener('click', function() {
    switch(typeof element.onclick) {
          case 'string':eval(element.onclick);break;
          case 'function':element.onclick();break;
     }
});

Os detalhes reais da implementação provavelmente diferem com uma variedade de variações sutis, tornando os dois ligeiramente diferentes em alguns casos, mas essa é a essência.

É sem dúvida um hack de compatibilidade que você pode fixar uma função em um atributo on, pois, por padrão, os atributos são todos strings.

jgmjgm
fonte
2

De acordo com a MDN , a diferença é a seguinte:

addEventListener:

O método EventTarget.addEventListener () adiciona o objeto compatível compatível com EventListener especificado à lista de ouvintes de eventos para o tipo de evento especificado no EventTarget no qual é chamado. O destino do evento pode ser um elemento em um documento, o próprio documento, uma janela ou qualquer outro objeto que suporte eventos (como XMLHttpRequest).

onclick:

A propriedade onclick retorna o código do manipulador de eventos click no elemento atual. Ao usar o evento click para acionar uma ação, também considere adicionar essa mesma ação ao evento de pressionamento de tecla, para permitir o uso dessa mesma ação por pessoas que não usam mouse ou tela sensível ao toque. Sintaxe element.onclick = functionRef; onde functionRef é uma função - geralmente o nome de uma função declarada em outro lugar ou uma expressão de função. Consulte o "Guia JavaScript: Funções" para obter detalhes.

Há também uma diferença de sintaxe em uso, como você vê nos códigos abaixo:

addEventListener:

// Function to change the content of t2
function modifyText() {
  var t2 = document.getElementById("t2");
  if (t2.firstChild.nodeValue == "three") {
    t2.firstChild.nodeValue = "two";
  } else {
    t2.firstChild.nodeValue = "three";
  }
}

// add event listener to table
var el = document.getElementById("outside");
el.addEventListener("click", modifyText, false);

onclick:

function initElement() {
    var p = document.getElementById("foo");
    // NOTE: showAlert(); or showAlert(param); will NOT work here.
    // Must be a reference to a function name, not a function call.
    p.onclick = showAlert;
};

function showAlert(event) {
    alert("onclick Event detected!");
}
Alireza
fonte
1

Se você não estiver muito preocupado com o suporte ao navegador, existe uma maneira de religar a referência 'this' na função chamada pelo evento. Normalmente, ele apontará para o elemento que gerou o evento quando a função é executada, o que nem sempre é o que você deseja. A parte complicada é ao mesmo tempo remover o mesmo ouvinte de evento, conforme mostrado neste exemplo: http://jsfiddle.net/roenbaeck/vBYu3/

/*
    Testing that the function returned from bind is rereferenceable, 
    such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
    // the following is necessary as calling bind again does 
    // not return the same function, so instead we replace the 
    // original function with the one bound to this instance
    this.swap = this.swap.bind(this); 
    this.element = document.createElement('div');
    this.element.addEventListener('click', this.swap, false);
    document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
    element: null,
    swap: function() {
        // now this function can be properly removed 
        this.element.removeEventListener('click', this.swap, false);           
    }
}

O código acima funciona bem no Chrome e, provavelmente, há alguma restrição em tornar o "bind" compatível com outros navegadores.

Lars Rönnbäck
fonte
1

O uso de manipuladores embutidos é incompatível com a Política de Segurança de Conteúdo, portanto, a addEventListenerabordagem é mais segura desse ponto de vista. É claro que você pode habilitar os manipuladores em linha unsafe-inline, mas, como o nome sugere, não é seguro, pois traz de volta toda a horda de explorações de JavaScript que o CSP impede.

kravietz
fonte
1
Nota: esta restrição de segurança aplica-se apenas ao desenvolvimento de extensões e as justificativas de segurança oferecidas no documento vinculado aplicam-se amplamente ao desenvolvimento de extensões de navegador. O único argumento exposto no documento vinculado, que também é válido para o desenvolvimento da web, geralmente, é separar conteúdo do comportamento. Essa é uma boa prática geral.
Chris Baker
1

Também deve ser possível estender o ouvinte através da criação de protótipos (se tivermos uma referência a ele e não for uma função anônima) - ou fazer o 'onclick' chamar uma chamada para uma biblioteca de funções (uma função chamando outras funções)

gostar

    elm.onclick = myFunctionList
    function myFunctionList(){
      myFunc1();
      myFunc2();
    }

isso significa que nunca precisamos chocar a chamada onclick, basta alterar a função myFunctionList () para fazer o que quisermos, mas isso nos deixa sem controle das fases de captura / captura, portanto, isso deve ser evitado nos navegadores mais recentes.

caso alguém encontre esse tópico no futuro ...

patrik
fonte
1

element.onclick = function () {/ * faça coisas * /}

element.addEventListener ('clique', function () {/ * faz coisas * /}, false);

Aparentemente, eles fazem o mesmo: ouvem o evento click e executam uma função de retorno de chamada. No entanto, eles não são equivalentes. Se você precisar escolher entre os dois, isso poderá ajudá-lo a descobrir qual é o melhor para você.

A principal diferença é que o onclick é apenas uma propriedade e, como todas as propriedades do objeto, se você escrever mais de uma vez, ele será substituído . Com addEventListener () , podemos simplesmente ligar um manipulador de eventos ao elemento, e podemos chamá-lo sempre que precisarmos, sem nos preocuparmos com propriedades sobrescritas. Exemplo é mostrado aqui,

Tente: https://jsfiddle.net/fjets5z4/5/

Em primeiro lugar, fiquei tentado a continuar usando o onclick, porque é mais curto e parece mais simples ... e na verdade é. Mas não recomendo mais usá-lo. É como usar o JavaScript embutido. Atualmente, o uso de algo como - que é o JavaScript embutido - é altamente desencorajado (o CSS embutido também é desencorajado, mas esse é outro tópico).

No entanto, a função addEventListener (), apesar de padrão, simplesmente não funciona em navegadores antigos (Internet Explorer abaixo da versão 9), e essa é outra grande diferença. Se você precisar oferecer suporte a esses navegadores antigos, siga o caminho do onclick. Mas você também pode usar o jQuery (ou uma de suas alternativas): basicamente simplifica o seu trabalho e reduz as diferenças entre os navegadores, portanto, você pode economizar muito tempo.

var clickEvent = document.getElementByID("onclick-eg");
var EventListener = document.getElementByID("addEventListener-eg");

clickEvent.onclick = function(){
    window.alert("1 is not called")
}
clickEvent.onclick = function(){
    window.alert("2 is not called")
}

EventListener.addEventListener("click",function(){
    window.alert("1 is called")
})
EventListener.addEventListener("click",function(){
    window.alert("2 is also called")
})
Arham Chowdhury
fonte
0

addEventListener permite definir vários manipuladores, mas não é suportado no IE8 ou inferior.

O IE tem attachEvent, mas não é exatamente o mesmo.

user113716
fonte
0

O contexto referenciado pela 'this'palavra-chave no JavasSript é diferente.

veja o seguinte código:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>

</head>
<body>
    <input id="btnSubmit" type="button" value="Submit" />
    <script>
        function disable() {
            this.disabled = true;
        }
        var btnSubmit = document.getElementById('btnSubmit');
        btnSubmit.onclick = disable();
        //btnSubmit.addEventListener('click', disable, false);
    </script>
</body>
</html>

O que ele faz é realmente simples. quando você clica no botão, o botão será desativado automaticamente.

Primeiro, quando você tenta conectar os eventos dessa maneira, o button.onclick = function(), evento onclick será acionado clicando no botão; no entanto, o botão não será desativado porque não há uma ligação explícita entre o manipulador de eventos button.onclick e onclick. Se você depurar ver o 'this'objeto, poderá ver que ele se refere ao 'window'objeto.

Em segundo lugar, se você comentar btnSubmit.onclick = disable();e descomentar, //btnSubmit.addEventListener('click', disable, false);poderá ver que o botão está desativado, pois dessa maneira há uma ligação explícita entre o evento button.onclick e o manipulador de eventos onclick. Se você depurar na função de desativação, poderá ver que 'this'se refere ao button controle não aowindow .

Isso é algo que eu não gosto no JavaScript, que é inconsistência. Btw, se você estiver usando jQuery ( $('#btnSubmit').on('click', disable);), ele usa ligação explícita.

Larry
fonte
8
Você precisa escrever btnSubmit.onclick = disable;(atribuir função, não chamá-lo). Em ambos os casos this, consultará o elemento button.
Pasha
-1

onclick é basicamente um addEventListener que executa especificamente uma função quando o elemento é clicado. Portanto, útil quando você tem um botão que executa operações simples, como um botão da calculadora. O addEventlistener pode ser usado para várias coisas, como executar uma operação quando o DOM ou todo o conteúdo é carregado, semelhante a window.onload, mas com mais controle.

Observe que você pode realmente usar mais de um evento com embutido ou, pelo menos, usando onclick, separando cada função com um ponto-e-vírgula, como este ....

Eu não escreveria uma função com inline, pois você pode ter problemas mais tarde e isso seria uma bagunça. Basta usá-lo para chamar funções já executadas no seu arquivo de script.

Qual você usa, suponho que depende do que você deseja. addEventListener para operações complexas e clique para simplificar. Eu já vi alguns projetos não anexarem um específico a elementos e, em vez disso, implementaria um listener de eventos mais global que determinaria se um toque estava em um botão e executaria determinadas tarefas, dependendo do que foi pressionado. Imo que poderia levar a problemas que eu pensaria e, embora pequeno, provavelmente, um desperdício de recursos, se o eventlistener tivesse que lidar com cada clique

ThatOneNoob
fonte