Transformando live () em on () no jQuery

202

Meu aplicativo adicionou Dropdowns dinamicamente. O usuário pode adicionar quantos forem necessários.

Tradicionalmente, eu estava usando o live()método do jQuery para detectar quando um desses menus suspensos foi change()ed:

$('select[name^="income_type_"]').live('change', function() {
    alert($(this).val());
});

No jQuery 1.7, atualizei isso para:

$('select[name^="income_type_"]').on('change', function() {
    alert($(this).val());
});

Olhando para o Documentos, isso deve ser perfeitamente válido (certo?) - mas o manipulador de eventos nunca é acionado. Obviamente, confirmei que o jQuery 1.7 está carregado e em execução, etc. Não há erros no log de erros.

O que estou fazendo de errado? Obrigado!

Jack
fonte
2
Eu sei que isso é tarde, mas parece que o jQuery liveestá realmente sendo usado de onqualquer maneira, portanto, uma reescrita do código legado talvez ainda não seja necessária até liveque seja removida, o que acredito ser 1.9. Trecho da fonte 1.7.1: live: function( types, data, fn ) {jQuery( this.context ).on( types, this.selector, data, fn ); return this;}Portanto, se alguém não estiver atualizando para uma versão em que livese foi, uma atualização pode não ser necessária imediatamente para o código legado. Para um novo código fora do curso, use o on()recomendado. Eu apenas pensei que esta informação poderia ajudar alguém em algum momento.
Nope
1
Consulte Exemplos de migração sobre como mudar livepara on.
Samuel Liew

Respostas:

246

A ondocumentação declara (em negrito;)):

Os manipuladores de eventos são vinculados apenas aos elementos selecionados no momento; eles devem existir na página no momento em que seu código faz a chamada .on().

Equivalente a .live()seria algo como

$(document.body).on('change', 'select[name^="income_type_"]', function() {
    alert($(this).val());
});

Embora seja melhor se você vincular o manipulador de eventos o mais próximo possível dos elementos, isto é, de um elemento mais próximo na hierarquia.

Atualização: Ao responder a outra pergunta, descobri que isso também é mencionado na .livedocumentação :

Reescrever o .live()método em termos de seus sucessores é direto; estes são modelos para chamadas equivalentes para todos os três métodos de anexo de evento:

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+
Felix Kling
fonte
5
@ Jack: Não se preocupe, IMO é uma boa pergunta. Presumo outros vão tropeçar isso também quando eles tentam converter todo o bind, livee delegatechamadas para on.
Felix Kling
4
Ah, sim, e é claro que só vemos essa resposta depois de executar um cobertor, encontrar e substituir de .live>.on
ajbeaven 7/11/11
3
Na IMO, a .onsintaxe é mais lógica, pois o ouvinte está realmente conectado ao seletor que você fornece. Quando o evento é acionado, o jQuery percorre o DOM e executa manipuladores onde especificado (delegação de evento simples). .livesugeriu que havia algo "mágico" que aconteceu, e foi dito que anexar manipuladores de eventos para "elementos futuros" que não eram inteiramente verdadeiros.
David Hellsing
1
@FelixKling que está correto - eu também me deparei com isso! Obrigado
willdanceforfun
2
Para o mecanismo de pesquisa: O método jQuery ".live ()" está obsoleto desde a v1.7 e removido na v1.9. Corrija seus scripts usando o método ".on ()". Surpreendentemente, isso também afeta o atual Microsoft jquery.unobtrusive-ajax.js v2.0.20710.0 (a Microsoft também não atualizou seus scripts e agora está corrompido).
Tony Wall
25

Além da resposta selecionada,

Porta jQuery.livepara o jQuery 1.9+ enquanto você espera a migração do aplicativo. Adicione isso ao seu arquivo JavaScript.

// Borrowed from jQuery 1.8.3's source code
jQuery.fn.extend({
  live: function( types, data, fn ) {
          if( window.console && console.warn ) {
           console.warn( "jQuery.live is deprecated. Use jQuery.on instead." );
          }

          jQuery( this.context ).on( types, this.selector, data, fn );
          return this;
        }
});

Nota: A função acima não funcionará no jQuery v3 conforme this.selectorfor removida.

Ou você pode usar https://github.com/jquery/jquery-migrate

Vikrant Chaudhary
fonte
7

Acabei de encontrar uma solução melhor que não envolve a edição de código de terceiros:

https://github.com/jquery/jquery-migrate/#readme

Instale o pacote NuQuet do jQuery Migrate no Visual Studio para eliminar todos os problemas de versão. Da próxima vez que a Microsoft atualizar seus módulos discretos de AJAX e validação, talvez tente novamente sem o script de migração para verificar se eles resolveram o problema.

Como o jQuery Migrate é mantido pela jQuery Foundation, acho que essa não é apenas a melhor abordagem para bibliotecas de terceiros e também para receber mensagens de aviso para suas próprias bibliotecas, detalhando como atualizá-las.

Tony Wall
fonte
3

Além das respostas selecionadas,

Se você usa o Visual Studio , pode usar o Regex Replace .
Em Editar> Localizar e substituir> Substituir em arquivos
ou Ctrl + Shift + H

No pop-up Localizar e substituir, defina esses campos

Encontre o que: \$\((.*)\)\.live\((.*),
Substitua por: $(document.body).on($2,$1,
Nas opções de localização, marque "Usar expressões regulares"

Maykol Rypka
fonte
-1

editor aberto jquery verision xxxjs, encontre jQuery.fn.extend

adicionar código

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

Exemplo: jquery-2.1.1.js -> linha 7469 (jQuery.fn.extend)

Exemplo de visualização de imagens

Uğur Tosun
fonte