Qual é a diferença entre `on` e` live` ou `bind`?

172

No jQuery v1.7, um novo método onfoi adicionado. A partir da documentação:

'O método .on () anexa manipuladores de eventos ao conjunto de elementos atualmente selecionado no objeto jQuery. A partir do jQuery 1.7, o método .on () fornece toda a funcionalidade necessária para anexar manipuladores de eventos. '

Qual a diferença com livee bind?

Diego
fonte
Tinha procurado algo assim antes de perguntar e não teve sucesso. Obrigado!
Diego

Respostas:

329

on()é uma tentativa de mesclar a maioria das funções de ligação de eventos do jQuery em uma. Isto tem a vantagem adicional de arrumar as ineficiências com livevs delegate. Nas versões futuras do jQuery, esses métodos serão removidos e somente one oneserão deixados.

Exemplos:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

Internamente, o jQuery mapeia todos esses métodos e configuradores de manipuladores de eventos abreviados para o on()método, indicando ainda que você deve ignorar esses métodos a partir de agora e apenas usar on:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

Consulte https://github.com/jquery/jquery/blob/1.7/src/event.js#L965 .

Andy E
fonte
Como @JamWaffles disse a resposta mais compreensível. Você poderia adicionar a comparação entre on e delegar para completar a resposta? Obrigado!
Diego
lols, você adicionou a fonte jquery 4 segundos antes de mim: D contexto equivalente btw ao vivo é documento, não document.body
Esailija
1
Você pode preferir consultar a tag 1.7, caso contrário, futuras alterações podem tornar seu link inválido (não apontar para o local certo): github.com/jquery/jquery/blob/1.7/src/event.js#L965
Felix Kling
3
$(document.body).delegate("click", ".mySelector", fn);deve ser$(document.body).delegate(".mySelector", "click", fn);
Sonny
2
@dsdsdsdsd, off serve como um substituto genérico para unbind, unlive e undelegate.
Andy E
12

onestá na natureza muito perto delegate. Então, por que não usar delegado? É porque onnão vem sozinho. existe off, para desassociar um evento e onecriar um evento para ser executado apenas uma vez. Este é o "pacote" de um novo evento.

O principal problema liveé que ele é anexado à "janela", forçando um evento de clique (ou outro evento) em um elemento dentro da estrutura da página (o dom), a "borbulhar" na parte superior da página para encontrar um evento manipulador disposto a lidar com isso. Em cada nível, todos os manipuladores de eventos precisam ser verificados, isso pode aumentar rapidamente, se você fizer uma imbricação profunda ( <body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

Assim, bindassim clickcomo outros ligadores de eventos de atalho se conectam diretamente ao destino do evento. Se você possui uma tabela de, digamos, 1000 linhas e 100 colunas, e cada uma das 100.000 células inclui uma caixa de seleção com o clique que você deseja manipular. Anexar 100'000 manipuladores de eventos levará muito tempo no carregamento da página. Criar um único evento no nível da tabela e usar a delegação de eventos é várias ordens de magnitude mais eficientes. O destino do evento será recuperado no momento da execução do evento. " this" será a tabela, mas " event.target" será o habitual " this" em uma clickfunção. Agora, o mais interessante oné que " this" sempre será o destino do evento, e não o contêiner ao qual está anexado.

roselan
fonte
O delegado não vem com desclassificado?
precisa saber é o seguinte
1
Sim. boa localização. Você aprende todos os dias;) (O doc tem melhorado muito desde 2011 thou)
roselan
5

com o .onmétodo é possível fazer .live, .delegatee .bindcom a mesma função, mas .live()apenas com .live()é possível (delegar eventos ao documento).

jQuery("#example").bind( "click", fn ) = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = jQuery( document ).on( "click", "#example", fn )

Posso confirmar isso diretamente da fonte jQuery:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery (this.context)? this.context=== documentna maioria dos casos

Esailija
fonte
3

(Minha frase de abertura fazia mais sentido antes de você mudar a pergunta. Originalmente você disse "Qual é a diferença live?")

oné mais delegatedo que é live, é basicamente uma forma unificada de ( binde delegate, de fato, a equipe disse que seu objetivo é "... unificar todas as formas de anexar eventos a um documento ..." ).

liveé basicamente on(ou delegate) anexado ao documento como um todo. Foi descontinuado a partir da v1.7 em favor do uso de onou delegate. No futuro, suspeito que veremos o código usando onapenas, e não usando bindou delegate(ou live) ...

Portanto, na prática, você pode:

  1. Use oncomo bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
    
  2. Use onlike delegate(delegação de evento enraizada em um determinado elemento):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
    
  3. Use onlike live(delegação de evento enraizada no documento):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);
    
TJ Crowder
fonte
1
Na página que vinculei, "Se um novo HTML estiver sendo injetado na página, selecione os elementos e anexe os manipuladores de eventos depois que o novo HTML for colocado na página. Ou use eventos delegados para anexar um manipulador de eventos, conforme descrito a seguir". . Então, é mais provável que vincule, não viva. Estou certo?
Diego
@ Diego: oné uma combinação de binde delegate, como eu disse, não muito parecido live. Você pode usar oncomo bind(anexar um manipulador diretamente a um elemento) ou oncomo delegate(anexar um manipulador a um elemento), mas acionar o evento apenas se o elemento real clicado corresponder a um seletor e como se esse elemento fosse o evento aconteceu em - por exemplo, delegação de eventos) ou você pode usá-lo como live( delegateusando o documento como raiz). É a delegação de eventos que a torna útil se você estiver adicionando elementos dinamicamente.
TJ Crowder
1
o live antigo também poderia ser usado como delegado: $("#id", ".class").live(fn)= $(".class").delegate("#id", fn );Na verdade, na fonte antiga do jQuery, eles usavam live como caso geral e delegado como caso especial, o que tornava isso ainda mais confuso quando você pensa sobre isso.
Esailija 9/11/11
@ Esailija: Justo. Eu não acho que esse seja o uso conhecido, porque eles foram adicionados delegaterapidamente, mas ainda assim. :-)
TJ Crowder
2

live é o atalho para .on () agora

//from source http://code.jquery.com/jquery-1.7.js
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

também este post pode ser útil para você http://blog.jquery.com/2011/11/03/jquery-1-7-released/

doochik
fonte
2

Não existe um para o caso de uso básico. Essas duas linhas são funcionalmente iguais

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on () também pode delegar eventos e é preferido.

.bind () é atualmente apenas um alias para .on () agora. Aqui está a definição da função de ligação na 1.7.1

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

A idéia para adicionar .on () era criar uma API de evento unificado, em vez de ter várias funções para evento de ligação; .on () substitui .bind (), .live () e .delegate ().

Dan
fonte
0

Algo que você deve estar ciente se desejar associar os manipuladores de eventos ao elemento - preste atenção a qual elemento o manipulador foi anexado!

Por exemplo, se você usar:

$('.mySelector').bind('click', fn);

você receberá os manipuladores de eventos usando:

$('.mySelector').data('events');

Mas se você usar:

$('body').on('click', '.mySelector', fn);

você receberá os manipuladores de eventos usando:

$('body').data('events');

(no último caso, o objeto de evento relevante terá selector = ". mySelector")

Alexander
fonte
eventsnão é documentado de qualquer maneira e eu acho que não funciona mais em 1.9
John Dvorak
Certo. Pode-se usar _data em vez de dados nas versões mais recentes. A resposta foi sobre a diferença no "proprietário do evento" e não a sintaxe exata para versões antigas ou novas. Existem outras postagens sobre a sintaxe exata para diferentes versões do JQuery. Por exemplo stackoverflow.com/questions/2518421/…
Alexander