JQuery ile bir projeye başlıyorum.
JQuery projenizde hangi tuzaklar / hatalar / yanlış anlamalar / suistimaller / kötüye kullanımlarınız oldu?
JQuery ile bir projeye başlıyorum.
JQuery projenizde hangi tuzaklar / hatalar / yanlış anlamalar / suistimaller / kötüye kullanımlarınız oldu?
Yanıtlar:
Yerel değişkenlere atamak yerine, hit ve aşırı seçicilerin performansından habersiz olmak. Örneğin:-
$('#button').click(function() {
$('#label').method();
$('#label').method2();
$('#label').css('background-color', 'red');
});
Ziyade:-
$('#button').click(function() {
var $label = $('#label');
$label.method();
$label.method2();
$label.css('background-color', 'red');
});
Veya zincirleme ile daha da iyi : -
$('#button').click(function() {
$("#label").method().method2().css("background-color", "red");
});
Bulduğum bu nasıl aramalarının yığınlarının çalışmalarını fark edince aydınlatarak anı.
Düzenleme: yorumlara dahil edilen öneriler.
var $label = $('#label');
Bağlamın nasıl kullanılacağını anlayın. Normalde, bir jQuery seçici tüm dokümanı arar:
// This will search whole doc for elements with class myClass
$('.myClass');
Ancak bir bağlamda arama yaparak işleri hızlandırabilirsiniz:
var ct = $('#myContainer');
// This will search for elements with class myClass within the myContainer child elements
$('.myClass', ct);
[0]
. $('.myClass', ct);
veya ct.find(".myClass")
Çıplak sınıf seçicileri kullanmayın, şöyle:
$('.button').click(function() { /* do something */ });
Bu, bir "düğme" sınıfına sahip olup olmadığını görmek için her öğeye bakacaktır.
Bunun yerine, aşağıdaki gibi yardımcı olabilirsiniz:
$('span.button').click(function() { /* do something */ });
$('#userform .button').click(function() { /* do something */ });
Bunu geçen yıl Rebecca Murphy'nin blogundan öğrendim
Güncelleme - Bu yanıt 2 yıl önce verildi ve jQuery'nin mevcut sürümü için doğru değil . Yorumlardan biri bunu kanıtlamak için bir test içeriyor. Testin , bu yanıt sırasında jQuery sürümünü içeren güncellenmiş bir sürümü de vardır .
$('.b')
kullanabilir document.getElementsByClassName('b')
, ancak bunu yapmak $('a.b')
, sınıfla eşleşen tüm öğeleri almasına neden olur b
ve daha sonra iki aşamalı bir işlemde çapa olduklarını doğrular. İkincisi bana daha fazla iş gibi geliyor. Gerçek bir yaşam benzetmesi için şunu deneyin: Odamdaki tüm çorapları bulun. Şimdi, şifonuzda olmayanları atın.
Anonim işlevleri bölmeye çalışın, böylece onları yeniden kullanabilirsiniz.
//Avoid
$('#div').click( function(){
//do something
});
//Do do
function divClickFn (){
//do something
}
$('#div').click( divClickFn );
(anonymous)
. Bu ipucu hakkında daha fazla bilgiyi buradan edinebilirsiniz: stackoverflow.com/questions/182630/jquery-tips-and-tricks/…
Doc ready ifadesinin içinde yüzlerce kod satırı gördüm. Çirkin, okunamaz ve bakımı imkansız.
Kullanırken $.ajax
için işlevini Ajax sunucusuna istekleri, kullandığınız kaçınmalısınız complete
işlem tepki verilerine olayı. İsteğin başarılı olup olmadığı tetiklenir.
Bunun yerine complete
, kullanın success
.
Dokümanlardaki Ajax Etkinlikleri'ne bakın .
Bir paragrafı tıkladıktan sonra yok etmek istediğinizi varsayalım. Daha sonra öğeyi DOM'dan kaldırmak istediniz. Sadece yöntemleri zincirleyebileceğinizi düşünebilirsiniz:
$("p").click(function(e) {
$(this).fadeOut("slow").remove();
});
Bu örnekte .remove (), .fadeOut () tamamlanmadan çağrılır, aşamalı solma efektinizi yok eder ve öğeyi hemen yok eder. Bunun yerine, bir komutu yalnızca öncekini bitirdikten sonra başlatmak istediğinizde, geri aramayı kullanın:
$("p").click(function(e){
$(this).fadeOut("slow", function(){
$(this).remove();
});
});
.FadeOut () öğesinin ikinci parametresi, .fadeOut () animasyonu tamamlandıktan sonra çalışacak anonim bir işlevdir. Bu kademeli bir solma ve daha sonra elemanın çıkarılmasını sağlar.
Aynı olayı birden çok kez bağlarsanız () birden çok kez tetiklenir. Genellikle her zaman unbind('click').bind('click')
güvende olurum
Eklentileri kötüye kullanmayın.
Çoğu zaman sadece kütüphaneye ve belki de kullanıcı arayüzüne ihtiyacınız olacaktır. Basit tutarsanız, kodunuz uzun vadede korunabilir olacaktır. Tüm eklentiler desteklenmez ve korunmaz, aslında çoğu desteklenmez. Çekirdek öğeleri kullanarak işlevselliği taklit edebiliyorsanız kesinlikle tavsiye ederim.
Eklentilerin kodunuza eklenmesi kolaydır, size biraz zaman kazandırır, ancak ekstra bir şeye ihtiyacınız olduğunda, olası güncellemeleri kaybettiğiniz için bunları değiştirmek kötü bir fikirdir. Başlangıçta kaydettiğiniz zaman, kullanımdan kaldırılmış eklentileri değiştirdiğinizde daha sonra kaybedersiniz.
Akıllıca kullandığınız eklentileri seçin. Kütüphane ve kullanıcı arayüzü dışında, sürekli olarak .cookie , $ .form , $ .validate ve thickbox kullanıyorum . Geri kalanı için çoğunlukla kendi eklentilerimi geliştiriyorum.
Tuzak: Seçiciler yerine döngüler kullanma.
DOM öğelerini yinelemek için kendinizi jQuery '.each' yöntemine ulaşıyorsanız, kendinize bunun yerine öğeleri almak için bir seçici kullanıp kullanamayacağınızı sorun.
JQuery seçicileri hakkında daha fazla bilgi:
http://docs.jquery.com/Selectors
Pitfall: Firebug gibi bir araç kullanmıyorum
Firebug bu tür hata ayıklama için pratik olarak yapıldı. Javascript ile DOM'da mucking olacaksanız, size görünürlük sağlamak için Firebug gibi iyi bir araca ihtiyacınız var.
Firebug hakkında daha fazla bilgi: http://getfirebug.com/
Diğer harika fikirler Polimorfik Podcast'in bu bölümünde: (Dave Ward ile jQuery Sırları) http://polymorphicpodcast.com/shows/jquery/
Bu tanımlayıcıyı doğru bağlamda kullanmanın yanlış anlaşılması. Örneğin:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
$(".listOfElements").each( function()
{
$(this).someMethod( ); // here 'this' is not referring first_element anymore.
})
});
Ve burada nasıl çözebileceğiniz örneklerinden biri:
$( "#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.
})
});
Tüm DOM'da birkaç kez arama yapmaktan kaçının. Bu gerçekten senaryonuzu geciktirebilecek bir şey.
Kötü:
$(".aclass").this();
$(".aclass").that();
...
İyi:
$(".aclass").this().that();
Kötü:
$("#form .text").this();
$("#form .int").that();
$("#form .choice").method();
İyi:
$("#form")
.find(".text").this().end()
.find(".int").that().end()
.find(".choice").method();
$ (This) öğesini her zaman anlamlı bir değişkene önbellekleyin.
Bunun gibi
$(selector).each(function () {
var eachOf_X_loop = $(this);
})
$self
veya $this
iyi bir değişken adı düşünmek çok tembel iseniz.
Etkinlikler
$("selector").html($("another-selector").html());
hiçbir olayı klonlamıyor - hepsini yeniden hatırlamanız gerekiyor.
JP'nin commen t - clone () yöntemine göre, doğru geçerseniz olayları yeniden hatırlatır.
Aynı jQuery nesnelerini birden çok oluşturmaktan kaçının
//Avoid
function someFunc(){
$(this).fadeIn();
$(this).fadeIn();
}
//Cache the obj
function someFunc(){
var $this = $(this).fadeIn();
$this.fadeIn();
}
$this = $(this);
ayrı bir hatta olmak daha okunabilir . Yapabiliyorsanız (dağınıklık yapmadan), unutun $this
ve her şeyi zincirleyin:$(this).fadeIn().fadeIn();
Çok fazla DOM manipülasyonu yapmak. .Html (), .append (), .prepend (), vb. Yöntemler harika olsa da, tarayıcıların sayfaları oluşturma ve yeniden oluşturma biçimi nedeniyle, bunları çok sık kullanmak yavaşlamalara neden olur. HTML'yi bir dize olarak oluşturmak ve DOM'u birden çok kez değiştirmek yerine bir kez DOM'ye eklemek daha iyidir.
Onun yerine:
var $parent = $('#parent');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$parent.append($div);
}
Bunu dene:
var $parent = $('#parent');
var iterations = 10;
var html = '';
for (var i = 0; i < iterations; i++){
html += '<div class="foo-' + i + '"></div>';
}
$parent.append(html);
Ya da bu bile ($ wrapper, henüz DOM'a enjekte edilmemiş yeni oluşturulan bir öğedir. Bu wrapper div'a düğüm eklemek yavaşlamalara neden olmaz ve sonunda yalnızca bir DOM manipülasyonu kullanarak $ parent'e $ wrapper ekleriz ):
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);
ASP.NET projelerinde denetimin "gerçek" kimliğini almak için ClientID kullanma.
jQuery('#<%=myLabel.ClientID%>');
Ayrıca, SharePoint içinde jQuery kullanıyorsanız, jQuery.noConflict () öğesini çağırmalısınız.
JQuery nesneleri yerine kimliklerin işlevlere iletilmesi:
myFunc = function(id) { // wrong!
var selector = $("#" + id);
selector.doStuff();
}
myFunc("someId");
Sarılı bir seti geçmek çok daha esnektir:
myFunc = function(elements) {
elements.doStuff();
}
myFunc($("#someId")); // or myFunc($(".someClass")); etc.
Zincirin aşırı kullanımı.
Bunu gör:
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
Akümülatör tarzı dizeler kullanın
+ İşlecini kullanarak bellekte yeni bir dize oluşturulur ve birleştirilmiş değer ona atanır. Ancak bundan sonra sonuç bir değişkene atanır. Birleştirme sonucunun ara değişkeninden kaçınmak için, + = operatörünü kullanarak sonucu doğrudan atayabilirsiniz. Yavaş:
a += 'x' + 'y';
Daha hızlı:
a += 'x';
a += 'y';
İlkel işlemler işlev çağrılarından daha hızlı olabilir
Performans açısından kritik döngülerde ve fonksiyonlarda fonksiyon çağrıları üzerinde alternatif ilkel işlem kullanmayı düşünün. Yavaş:
var min = Math.min(a, b);
arr.push(val);
Daha hızlı:
var min = a < b ? a : b;
arr[arr.length] = val;
En Devamı JavaScript Performans En İyi Uygulamalar
Kullanıcıların tarayıcılarında html varlıklarını görmesini istiyorsanız, bir Unicode dizesi enjekte etmek için 'metin' yerine 'html' kullanın:
$('p').html("Your Unicode string")
benim görüşüm)
Genellikle jquery ile çalışmak, DOM öğeleri hakkında her zaman endişelenmenize gerek olmadığı anlamına gelir. Böyle bir şey yazabilirsiniz -$('div.mine').addClass('someClass').bind('click', function(){alert('lalala')})
- ve bu kod herhangi bir hata atmadan yürütülür.
Bazı durumlarda bu yararlıdır, bazı durumlarda - hiç de değil, ama jquery'nin boş maçlarla dost olma eğiliminde olduğu bir gerçektir. Hala,replaceWith
belgeye ait olmayan bir öğeyle kullanmaya çalışırsa hata atar. Bunu oldukça sezgisel buluyorum.
Başka bir tuzak, bence, prevAll () yöntemi - tarafından döndürülen düğümlerin sırasıdır $('<div><span class="A"/><span class="B"/><span class="C"/><span class="D"/></div>').find('span:last-child').prevAll()
. Aslında büyük bir mesele değil, ama bu gerçeği aklımızda tutmalıyız.
Ajax'a, örneğin 20 sütunlu bir tablo 1500 satır gibi çok sayıda veri planlıyorsanız, bu verileri HTML'nize eklemek için jQuery kullanmayı düşünmeyin. Düz JavaScript kullanın. jQuery yavaş makinelerde çok yavaş olacaktır.
Ayrıca, jQuery, gelen HTML'deki komut dosyası etiketlerini ayrıştırmaya çalışmak ve tarayıcı tuhaflıklarıyla uğraşmak gibi daha yavaş olmasına neden olacak şeyler yapacak. Hızlı ekleme hızı istiyorsanız, düz JavaScript ile devam edin.
.innerHTML
yapacaktır. Ancak, kullanıcının sekmeyi saatlerce açık tuttuğu Gmail gibi bir şey oluşturuyorsanız, mermiyi ısırmanız ve ekstra yavaşlıkla uğraşmanız gerekecek. Meraklı olmak için, jQuery's tam olarak ne .html()
yapıyor: james.padolsey.com/jquery/#v=1.4&fn=jQuery.fn.html
Sadece birkaç satır sıradan JavaScript ile tamamlanabilen küçük bir projede jQuery kullanmak.
couple of lines of ordinary JavaScript
Elbette, hiç sorun değil. Ama ne zaman sadece bu kadar? "Neden vanilya javascript kullanılmıyor ??" henüz IE tarafından yeterince sert ısırılmadı ... ve düz eski JS basit şeyler yapmak için yazmak zorunda ne kadar cruft ve boilerplate kod bahsetmiyorum.
Olay bağlama anlaşılmıyor. JavaScript ve jQuery farklı çalışır.
Yoğun talep üzerine bir örnek:
JQuery'de:
$("#someLink").click(function(){//do something});
JQuery olmadan:
<a id="someLink" href="page.html" onClick="SomeClickFunction(this)">Link</a>
<script type="text/javascript">
SomeClickFunction(item){
//do something
}
</script>
Temel olarak JavaScript için gereken kancalar artık gerekli değildir. Satır içi işaretleme (onClick, vb.) Kullanın, çünkü bir geliştiricinin normalde CSS amaçları için kaldıracağı kimlikleri ve sınıfları kullanabilirsiniz.