Estou iniciando um projeto com jQuery.
Que armadilhas / erros / equívocos / abusos / abusos você teve no seu projeto jQuery?
Estou iniciando um projeto com jQuery.
Que armadilhas / erros / equívocos / abusos / abusos você teve no seu projeto jQuery?
Respostas:
Desconhecer o desempenho atingido e usar em excesso os seletores em vez de atribuí-los a variáveis locais. Por exemplo:-
$('#button').click(function() {
$('#label').method();
$('#label').method2();
$('#label').css('background-color', 'red');
});
Ao invés de:-
$('#button').click(function() {
var $label = $('#label');
$label.method();
$label.method2();
$label.css('background-color', 'red');
});
Ou ainda melhor com encadeamento : -
$('#button').click(function() {
$("#label").method().method2().css("background-color", "red");
});
Eu achei isso o momento esclarecedor em que percebi como as pilhas de chamadas funcionam.
Editar: sugestões incorporadas nos comentários.
var $label = $('#label');
Entenda como usar o contexto. Normalmente, um seletor de jQuery pesquisará todo o documento:
// This will search whole doc for elements with class myClass
$('.myClass');
Mas você pode acelerar as coisas pesquisando dentro de um contexto:
var ct = $('#myContainer');
// This will search for elements with class myClass within the myContainer child elements
$('.myClass', ct);
[0]
. $('.myClass', ct);
ou se você sabe ct é uma instância de jQuery você pode usar encontrarct.find(".myClass")
Não use seletores de classe simples, como este:
$('.button').click(function() { /* do something */ });
Isso acabará analisando cada elemento para ver se ele possui uma classe de "botão".
Em vez disso, você pode ajudá-lo, como:
$('span.button').click(function() { /* do something */ });
$('#userform .button').click(function() { /* do something */ });
Eu aprendi isso no ano passado com no blog Rebecca Murphy
Atualização - Esta resposta foi dada há mais de 2 anos e não está correta para a versão atual do jQuery. Um dos comentários inclui um teste para provar isso. Há também uma versão atualizada do teste que inclui a versão do jQuery no momento desta resposta.
$('.b')
poderia usar document.getElementsByClassName('b')
se o navegador suportar, mas isso $('a.b')
fará com que ele obtenha todos os elementos correspondentes com a classe b
e confirme se são âncoras em uma operação de dois estágios. O último parece mais trabalho para mim. Para uma analogia da vida real, tente o seguinte: Encontre todas as meias no meu quarto. Agora, jogue fora os que não estão na minha cômoda.
Tente dividir funções anônimas para poder reutilizá-las.
//Avoid
$('#div').click( function(){
//do something
});
//Do do
function divClickFn (){
//do something
}
$('#div').click( divClickFn );
(anonymous)
. Leia mais sobre esta dica aqui: stackoverflow.com/questions/182630/jquery-tips-and-tricks/…
Eu já vi centenas de linhas de código dentro da instrução doc ready. Feio, ilegível e impossível de manter.
Ao usar a $.ajax
função para solicitações do Ajax para o servidor, evite usar o complete
evento para processar dados de resposta. Será acionado se a solicitação foi bem-sucedida ou não.
Em vez de complete
usar success
.
Consulte Eventos do Ajax nos documentos.
Suponha que você queira animar um parágrafo que desaparece ao clicar nele. Você também quis remover o elemento do DOM posteriormente. Você pode pensar que pode simplesmente encadear os métodos:
$("p").click(function(e) {
$(this).fadeOut("slow").remove();
});
Neste exemplo, .remove () será chamado antes que .fadeOut () seja concluído, destruindo seu efeito de desbotamento gradual e simplesmente fazendo o elemento desaparecer instantaneamente. Em vez disso, quando você deseja acionar um comando apenas após concluir o anterior, use os retornos de chamada:
$("p").click(function(e){
$(this).fadeOut("slow", function(){
$(this).remove();
});
});
O segundo parâmetro de .fadeOut () é uma função anônima que será executada quando a animação .fadeOut () for concluída. Isso cria um desbotamento gradual e uma remoção subsequente do elemento.
Se você ligar () o mesmo evento várias vezes, ele será acionado várias vezes. Eu costumo sempre ir unbind('click').bind('click')
apenas por segurança
Não abuse dos plug-ins.
Na maioria das vezes, você precisará apenas da biblioteca e talvez da interface do usuário. Se você simplificar, seu código poderá ser mantido a longo prazo. Nem todos os plug-ins são suportados e mantidos, na verdade a maioria não. Se você pode imitar a funcionalidade usando os elementos principais, recomendo fortemente.
Os plug-ins são fáceis de inserir no seu código, economizam um pouco de tempo, mas quando você precisar de algo extra, é uma má idéia modificá-los, pois você perde as atualizações possíveis. O tempo que você economiza no início, perde mais tarde alterando os plug-ins obsoletos.
Escolha os plug-ins que você usa com sabedoria. Além da biblioteca e da interface do usuário, uso constantemente $ .cookie , $ .form , $ .validate e thickbox . De resto, desenvolvo principalmente meus próprios plug-ins.
Armadilha: Usando loops em vez de seletores.
Se você encontrar o método jQuery '.each' para iterar sobre os elementos DOM, pergunte a si mesmo se pode usar um seletor para obter os elementos.
Mais informações sobre os seletores jQuery:
http://docs.jquery.com/Selectors
Armadilha: NÃO use uma ferramenta como o Firebug
O Firebug foi praticamente criado para esse tipo de depuração. Se você estiver mexendo no DOM com Javascript, precisará de uma boa ferramenta como o Firebug para lhe dar visibilidade.
Mais informações sobre o Firebug: http://getfirebug.com/
Outras grandes idéias estão neste episódio do Podcast Polimórfico: (Segredos do jQuery com Dave Ward) http://polymorphicpodcast.com/shows/jquery/
Incompreensão de usar esse identificador no contexto certo. Por exemplo:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
$(".listOfElements").each( function()
{
$(this).someMethod( ); // here 'this' is not referring first_element anymore.
})
});
E aqui uma das amostras como você pode resolvê-lo:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
var $that = this;
$(".listOfElements").each( function()
{
$that.someMethod( ); // here 'that' is referring to first_element still.
})
});
Evite pesquisar o DOM inteiro várias vezes. Isso é algo que realmente pode atrasar seu script.
Ruim:
$(".aclass").this();
$(".aclass").that();
...
Boa:
$(".aclass").this().that();
Ruim:
$("#form .text").this();
$("#form .int").that();
$("#form .choice").method();
Boa:
$("#form")
.find(".text").this().end()
.find(".int").that().end()
.find(".choice").method();
Sempre armazene em cache $ (this) em uma variável significativa, especialmente em um .each ()
Como isso
$(selector).each(function () {
var eachOf_X_loop = $(this);
})
$self
ou $this
se você estiver com preguiça de pensar em um bom nome de variável.
Evite a criação múltipla dos mesmos objetos jQuery
//Avoid
function someFunc(){
$(this).fadeIn();
$(this).fadeIn();
}
//Cache the obj
function someFunc(){
var $this = $(this).fadeIn();
$this.fadeIn();
}
$this = $(this);
em uma linha separada. Se você pode (sem fazer uma bagunça), esqueça $this
e encadeie tudo:$(this).fadeIn().fadeIn();
Fazendo muitas manipulações DOM. Embora os métodos .html (), .append (), .prepend () etc. sejam ótimos, devido à maneira como os navegadores renderizam e renderizam novamente as páginas, usá-los com muita freqüência causará lentidão. Geralmente, é melhor criar o html como uma string e incluí-lo no DOM uma vez, em vez de alterá-lo várias vezes.
Ao invés de:
var $parent = $('#parent');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$parent.append($div);
}
Tente o seguinte:
var $parent = $('#parent');
var iterations = 10;
var html = '';
for (var i = 0; i < iterations; i++){
html += '<div class="foo-' + i + '"></div>';
}
$parent.append(html);
Ou mesmo isso ($ wrapper é um elemento recém-criado que ainda não foi injetado no DOM. O acréscimo de nós a essa div do wrapper não causa lentidão e, no final, anexamos o $ wrapper ao $ parent, usando apenas uma manipulação do DOM ):
var $parent = $('#parent');
var $wrapper = $('<div class="wrapper" />');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$wrapper.append($div);
}
$parent.append($wrapper);
Usando ClientID para obter a identificação "real" do controle em projetos ASP.NET.
jQuery('#<%=myLabel.ClientID%>');
Além disso, se você estiver usando o jQuery no SharePoint, deverá chamar jQuery.noConflict ().
Passando IDs em vez de objetos jQuery para funções:
myFunc = function(id) { // wrong!
var selector = $("#" + id);
selector.doStuff();
}
myFunc("someId");
Passar um conjunto embrulhado é muito mais flexível:
myFunc = function(elements) {
elements.doStuff();
}
myFunc($("#someId")); // or myFunc($(".someClass")); etc.
Uso excessivo de encadeamento.
Veja isso:
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
Use cadeias no estilo acumulador
Usando o operador +, uma nova string é criada na memória e o valor concatenado é atribuído a ela. Somente depois disso, o resultado é atribuído a uma variável. Para evitar a variável intermediária para o resultado da concatenação, você pode atribuir diretamente o resultado usando o operador + =. Lento:
a += 'x' + 'y';
Mais rápido:
a += 'x';
a += 'y';
Operações primitivas podem ser mais rápidas que chamadas de função
Considere o uso de operação primitiva alternativa sobre chamadas de função em loops e funções críticas de desempenho. Lento:
var min = Math.min(a, b);
arr.push(val);
Mais rápido:
var min = a < b ? a : b;
arr[arr.length] = val;
Leia mais em JavaScript Performance Best Practices
Se você deseja que os usuários vejam entidades html no navegador, use 'html' em vez de 'text' para injetar uma string Unicode, como:
$('p').html("Your Unicode string")
meus dois centavos)
Geralmente, trabalhar com jquery significa que você não precisa se preocupar com elementos DOM reais o tempo todo. Você pode escrever algo como isto - $('div.mine').addClass('someClass').bind('click', function(){alert('lalala')})
- e esse código será executado sem gerar erros.
Em alguns casos, isso é útil, em alguns casos - nem um pouco, mas é um fato que o jquery tende a ser, bem, compatível com partidas vazias. Ainda,replaceWith
lançará um erro se alguém tentar usá-lo com um elemento que não pertence ao documento. Acho isso bastante contra-intuitivo.
Outra armadilha é, na minha opinião, a ordem dos nós retornados pelo método prevAll () - $('<div><span class="A"/><span class="B"/><span class="C"/><span class="D"/></div>').find('span:last-child').prevAll()
. Não é grande coisa, na verdade, mas devemos ter em mente esse fato.
Se você planeja usar o Ajax em muitos dados, como, digamos, 1500 linhas de uma tabela com 20 colunas, nem pense em usar o jQuery para inserir esses dados em seu HTML. Use JavaScript simples. O jQuery será muito lento em máquinas mais lentas.
Além disso, na metade do tempo o jQuery fará coisas que o tornarão mais lento, como tentar analisar as tags de script no HTML recebido e lidar com as peculiaridades do navegador. Se você deseja uma velocidade de inserção rápida, use JavaScript simples.
.innerHTML
fará. Mas se você estiver criando algo como o Gmail, em que o usuário mantém a aba aberta por horas, você terá que aceitar o problema e lidar com a lentidão extra. Para os curiosos, aqui está exatamente o que o jQuery .html()
faz: james.padolsey.com/jquery/#v=1.4&fn=jQuery.fn.html
Usando o jQuery em um projeto pequeno que pode ser concluído com apenas algumas linhas de JavaScript comum.
couple of lines of ordinary JavaScript
Claro que não há problema. Mas quando é que é só isso? Pessoas que dizem "por que não usar javascript vanilla ??" ainda não foi mordido o suficiente pelo IE ... e para não mencionar quanto código de cruft e clichê você precisa escrever para fazer coisas simples em JS simples e antigo.
Não entendendo a ligação de eventos. JavaScript e jQuery funcionam de maneira diferente.
Por demanda popular, um exemplo:
No jQuery:
$("#someLink").click(function(){//do something});
Sem jQuery:
<a id="someLink" href="page.html" onClick="SomeClickFunction(this)">Link</a>
<script type="text/javascript">
SomeClickFunction(item){
//do something
}
</script>
Basicamente, os ganchos necessários para JavaScript não são mais necessários. Ou seja, use a marcação embutida (onClick, etc), porque você pode simplesmente usar os IDs e classes que um desenvolvedor usaria normalmente para fins de CSS.