<
Menu

Tableless


feature5

Reveal.js: criando apresentações no navegador

menu-retratil

Menu Retrátil com CSS e jQuery

jquery

Tudo que você gostaria de saber sobre plugins jQuery e ninguém teve paciência de explicar

adobe-edge

Adobe Edge


Imagem post: jQuery: conheça os métodos on() e off()

jQuery: conheça os métodos on() e off()

A versão 1.7 do framework jQuery implementa dois novos métodos que pretendem acabar de vez com a confusão gerada em torno da associação de eventos.

Em outubro de 2010 escrevi um artigo aqui mesmo no Tableless sobre a associação dinâmica de eventos. Na época, reinava uma confusão sobre quais métodos utilizar e quando utilizá-los. Eram três as opções: bind(), live() e delegate().

Com o lançamento da versão 1.7 do jQuery, dois métodos definitivos (assim espero) devem acabar com a confusão em torno da associação de eventos: os métodos on() e off().

Eventos diretos

A associação direta de eventos ocorre quando o seletor (ou escopo) é omitido nos parâmetros do on(). Por exemplo:

function exibeMenu(e) {
  e.preventDefault();
  $('#menu').show();
}
$('#lnk-menu').on('click', exibeMenu);

No código acima, o elemento com id #lnk-menu recebe uma associação no evento click para executar a função exibeMenu(). A associação ocorre de forma direta, ou seja, quando o on() é executado o evento passa a estar associado ao elemento, antes mesmo do clique ocorrer.

Essa opção equivale ao bind() e deve ser utilizada em casos de elementos únicos, ou com poucos elementos, para evitar problemas de performance.

Múltiplos eventos

Também é possível associar múltiplos eventos a um ou mais elementos. Para isso, basta passar um mapa onde cada chave representa um evento ao invés de um evento como string:

$('#lnk-menu').on({
  click: function(){
    $('#menu').show();
  },
  dblclick: function(){
    $('#submenu').show();
  },
  mouseenter: function(){
    $(this).addClass('ativo');
  }
});

Removendo associações de eventos diretos

Remover associações de eventos diretos é simples:

$('#lnk-menu').off();

Para remover eventos específicos, mantendo qualquer outra associação, basta informar o nome do evento:

$('#lnk-menu').off('click');

Eventos delegados

A delegação de eventos (antigos live() e delegate()) ocorre quando passamos um ou mais seletores nos parâmetros do on. O evento não será
associado diretamente quando o código for executado, tampouco será executado para o seletor que chama o on() e sim para os elementos descendentes que se encaixem no parâmetro passado.

A associação ocorre quando o evento é acionado. Esse tipo de associação funciona tanto para elementos já presentes no DOM como para elementos criados posteriormente.

function exibeConteudo(e){
  $(this).find('conteudo').fadeIn();
}

$('table').on('click', 'a', exibeConteudo);

Removendo a associação de eventos específicos

Em alguns momentos será preciso associar eventos diretos e, ao mesmo tempo, delegar eventos. Nesses casos, é possível remover apenas os eventos delegados utilizando o parâmetro especial “**”.

$('a').off('click', '**');

Outra opção é remover a associação com base na função utilizada:

$('#lnk-menu').off('click', 'a', exibeConteudo);

Namespaces

Uma importante implementação do on() é a possibilidade de utilizar namespaces nos eventos – uma grande novidade para desenvolvedores de plugins. Um evento pode, agora, ser associado a um namespace específico, facilitando o controle sobre associações específicas de um plugin ou uma funcionalidade.

$('#lnk-menu').on('click.menu', exibeMenu);
$('.menu-item').on('mouseleave.menu', escondeMenu);

$('#lnk-menu, .menu-item').off('.menu');

Enviando dados para o evento

O método on() também permite enviar dados específicos para um evento. O objeto de dados fica associado ao objeto do evento.

function exibeMenu(e) { 
  $('.ativo').text(e.data.descricao);
}

$('#lnk-home').on('click', { descricao: 'Página inicial' }, exibeMenu);
$('#lnk-sobre').on('click', { descricao: 'Sobre a empresa' }, exibeMenu);

No exemplo acima, cada link passa uma descrição diferente durante o evento. Essa descrição passa a ser o conteúdo dos elementos com a classe “.ativo”.

Este evento se autodestruirá…

O método .one() poderia ter entrado na lista dos métodos desconhecidos do meu último artigo, já que existe desde a versão 1.1 do jQuery. No entanto, junto com a implementação do .on() ele ganhou uma nova cara.

Sua implementação segue as mesmas regras do .on() com uma importante diferença: o evento associado é executado apenas uma vez. Após a execução a associação é automaticamente removida, seja ela uma associação direta ou delegada.

$('#lnk-menu').one('click', function() {
  alert('Este evento não será mais executado.');
});

Caso o seletor possua mais de um elemento, o evento será associado uma vez a cada um deles, ou seja, cada elemento possuirá uma execução do evento.


Essas são as novidades com relação a eventos utilizando jQuery. Os métodos .on() e .off() devem “matar” seus antecessores (.live() e .delegate()) e padronizar de uma vez por todas a associação de eventos em aplicações.

Por Davi Ferreira

Programador apaixonado pelo que faz. Responsável pelo desenvolvimento de sistemas e interfaces para Globo.com, Confederação Brasileira de Vôlei, Ricoh Brasil, Embratel entre outros.

http://www.daviferreira.com/blog

Mais posts do autor

Comentários (30)

  • Nandorossetto

    Eu gostava do live(), já salvou muitas vidas!

  • Mateus Ávila Isidoro

    Animal. Eu vou trocar os meus delegates por on. Parabéns por mais um fantástico artigo.

  • http://twitter.com/guiiipontes Guilherme Pontes

    Poxa, usava muito o live, até agora hehehe

  • Tomas Vasquez

    Classe A, como diria um amigo aqui do trabalho. :D

  • http://twitter.com/pedromagalhaes Pedro Magalhães

    Boa dica

  • http://www.udgwebdev.com/ Caio Ribeiro Pereira

    muito bizarro esse método off() 

  • http://www.sevenlabs.com.br/ Igor Prado

    Fantástico!

  • Deivid Marques

    Vlw pelo post!

  • http://twitter.com/_allanrodrigues Allan Rodrigues

    Isso vai acabar com códigos gigantescos, principalmente em partes de data e namespace, mão na roda

  • Pingback: jQuery: conheça os métodos on() e off() | Leonardo Cotta

  • Fernando

    Até hoje eu não sei pra que serve exatamente o bind().. Porque eu delegaria um evento para um elemento que já existe, se eu posso usar sem o bind()? Alguém me explica?

  • JonasAntonelli

    uma melhoria muito válida, o que mais de novo tem na versão 1.7 do jQuery?

  • http://twitter.com/kayo_leandro Kayo Leandro

    Excelente método, uma mão na roda…

  • Emerson Maia

    boa, parabéns !

  • Felipe Rodrigues

    O post foi de grande ajuda…

  • Eder Lima

    Confesso que é um pouco estranho trabalho com ‘on’ e ‘off’ quando se está acostumado com addEvent ou removeEvent de outras linguagens e framework.

  • Pingback: Novo método no jQuery 1.7 | WebPatterns - Seu site nos padrões WEB

  • Ofelquis

    Não sei o que você vê de bizarro.

  • Leandro Finger

     Gostei! Vai melhorar muito na hora de remover um evento.

  • http://twitter.com/JoaoVagner JoaoVagner

    Como fica a compatibilidade? Se eu vincular o 1.7, e tiver scripts com .live, to ferrado? 

  • Denis Polizzi

    Voce é o Davi Ferreira da punknet?

  • Giolvani de Matos

    Essa parada do namespace ficou show mesmo. Ótimo post!

  • http://labs.webdiastutoriais.com/ Hugo Dias

    utilizo e muito o metodo .on() . Principalmente se você tem uma aplicação muito grande e precisa fazer muitos binds …

  • Allan Oliveira

    Continua a mesma coisa. É só um método a mais.

  • http://twitter.com/caarlos0 Carlos Alexandro Becker

    Sempre faço $(document).on(evento, seletor, function), qual a REAL diferença de fazer isso ou o $(seletor).(event, function) ?

  • Vinícius Moraes de Araújo

    A diferença fica por conta do seguinte se você estiver utilizando $(seletor).(event, function) e o seu seletor ainda não existir no DOM ou tiver sido removido o evento não será executado. Porém se você utilizar $(document).on(evento, seletor, function) o document sempre irá existir na página independente se o seletor já está criado ou foi removido e adicionado posteriormente, fazendo com que o evento dispare.

    Isso acontece pois, quando a função on() delega o método, ela utiliza a árvore do DOM e caso “$(seletor)” não exista o método se perde. Espero que eu tenha conseguido te explicar claramente.

  • http://twitter.com/caarlos0 Carlos Alexandro Becker

    Foi o que pensei. Valeu =D

  • Vagner Lima

    Me salvou. Estava penando com o uso do .on(). Vlw!!

  • Natanael

    mto bom

  • Paulo Dias

    Nossa muito bom !! Não sabia do .one !! Acabou de me ajudar ! rs