Size yardımcı olabilecek veya olmayabilecek bazı basit şeyleri gözden geçireceğim. Bazıları apaçık olabilir, bazıları aşırı derecede gizemli olabilir.
1. Adım: Kodunuzu bölümlere ayırın
Kodunuzu birden çok modüler birime ayırmak çok iyi bir ilk adımdır. Neyin "birlikte" işe yaradığını toparlayın ve onları kendi küçük kapalı birimlerine koyun. şimdilik format hakkında endişelenmeyin, onu satır içinde tutun. Yapı daha sonraki bir noktadır.
Diyelim ki böyle bir sayfanız var:
Bakım kolaylığı için (ve 1000 satırı elemek zorunda kalmadan) başlıkla ilgili tüm olay işleyicileri / bağlayıcıları orada olacak şekilde bölümlere ayırmak mantıklı olacaktır.
Ardından, JS'nizi tek bir birime yeniden oluşturmak için Grunt gibi bir araç kullanabilirsiniz.
Adım 1a: Bağımlılık yönetimi
AMD adlı bir şeyi uygulamak için RequireJS veya CommonJS gibi bir kitaplık kullanın . Eşzamansız Modül Yükleme, kodunuzun neye bağlı olduğunu açıkça belirtmenize olanak tanır, bu da kitaplık çağrısını koda aktarmanıza olanak tanır. Kelimenin tam anlamıyla "Bunun jQuery'ye ihtiyacı var" diyebilirsiniz ve AMD onu yükleyecek ve jQuery mevcut olduğunda kodunuzu çalıştıracaktır .
Bunda da gizli bir cevher var: Kütüphane yüklemesi, DOM hazır olduğu anda yapılacaktır, daha önce değil. Bu artık sayfanızın yüklenmesini durdurmuyor!
2. Adım: Modülerleştirin
Tel çerçeveyi görüyor musun? İki reklam birimim var. Büyük ihtimalle olay dinleyicileri paylaşacaklar.
Bu adımdaki göreviniz, kodunuzdaki tekrarlama noktalarını belirlemek ve tüm bunları modüller halinde sentezlemeye çalışmaktır . Modüller, şu anda her şeyi kapsayacak. İlerledikçe eşyaları ayıracağız.
Bu adımın tüm fikri, 1. adımdan başlamak ve tüm kopya-pastaları silmek, bunları gevşek bağlı birimlerle değiştirmek. Yani, sahip olmak yerine:
ad_unit1.js
$("#au1").click(function() { ... });
ad_unit2.js
$("#au2").click(function() { ... });
Sahip olacağım:
ad_unit.js
:
var AdUnit = function(elem) {
this.element = elem || new jQuery();
}
AdUnit.prototype.bindEvents = function() {
... Events go here
}
page.js
:
var AUs = new AdUnit($("#au1,#au2"));
AUs.bindEvents();
Bu , tekrardan kurtulmanın yanı sıra etkinlikleriniz ve işaretlemeniz arasında bölmelere ayırmanıza olanak tanır . Bu oldukça iyi bir adım ve bunu daha sonra daha da genişleteceğiz.
3. Adım: Bir çerçeve seçin!
Tekrarları daha da modülerleştirmek ve azaltmak istiyorsanız, MVC (Model - Görünüm - Denetleyici) yaklaşımlarını uygulayan bir sürü harika çerçeve vardır. Benim favorim Backbone / Spine, ancak bir de Angular, Yii var ... Liste uzayıp gidiyor.
Bir Modeli verilerinizi temsil eder.
Bir Görünüm İz-up temsil eden ve tüm olaylar buna bağlı
Bir Denetleyici , iş mantığınızı temsil eder - başka bir deyişle, denetleyici sayfaya hangi görünümlerin yükleneceğini ve hangi modellerin kullanılacağını söyler.
Bu, önemli bir öğrenme adımı olacak, ancak ödül buna değer: spagetti yerine temiz, modüler kodu tercih ediyor.
Yapabileceğiniz daha pek çok şey var, bunlar sadece kılavuzlar ve fikirlerdir.
Koda özgü değişiklikler
Kodunuzda bazı özel iyileştirmeler şunlardır:
$('.new_layer').click(function(){
dialog("Create new layer","Enter your layer name","_input", {
'OK' : function(){
var reply = $('.dialog_input').val();
if( reply != null && reply != "" ){
var name = "ln_"+reply.split(' ').join('_');
var parent = "";
if(selected_folder != "" ){
parent = selected_folder+" .content";
}
$R.find(".layer").clone()
.addClass(name).html(reply)
.appendTo("#layer_groups "+parent);
$R.find(".layers_group").clone()
.addClass(name).appendTo('#canvas '+selected_folder);
}
}
});
});
Bu daha iyi şöyle yazılır:
$("body").on("click",".new_layer", function() {
dialog("Create new layer", "Enter your layer name", "_input", {
OK: function() {
// There must be a way to get the input from here using this, if it is a standard library. If you wrote your own, make the value retrievable using something other than a class selector (horrible performance + scoping +multiple instance issues)
// This is where the view comes into play. Instead of cloning, bind the rendering into a JS prototype, and instantiate it. It means that you only have to modify stuff in one place, you don't risk cloning events with it, and you can test your Layer stand-alone
var newLayer = new Layer();
newLayer
.setName(name)
.bindToGroup(parent);
}
});
});
Kodunuzda daha önce:
window.Layer = function() {
this.instance = $("<div>");
// Markup generated here
};
window.Layer.prototype = {
setName: function(newName) {
},
bindToGroup: function(parentNode) {
}
}
Birdenbire, kopyalayıp yapıştırmadan kodunuzun herhangi bir yerinden standart bir katman oluşturmanın bir yoluna sahip olursunuz. Bunu beş farklı yerde yapıyorsun. Sana beş kopya-yapıştır bıraktım.
Bir tane daha:
// Eylemler için kural kümesi sarmalayıcı
var PageElements = function(ruleSet) {
ruleSet = ruleSet || [];
this.rules = [];
for (var i = 0; i < ruleSet.length; i++) {
if (ruleSet[i].target && ruleSet[i].action) {
this.rules.push(ruleSet[i]);
}
}
}
PageElements.prototype.run = function(elem) {
for (var i = 0; i < this.rules.length; i++) {
this.rules[i].action.apply(elem.find(this.rules.target));
}
}
var GlobalRules = new PageElements([
{
"target": ".draggable",
"action": function() { this.draggable({
cancel: "div#scrolling, .content",
containment: "document"
});
}
},
{
"target" :".resizable",
"action": function() {
this.resizable({
handles: "all",
zIndex: 0,
containment: "document"
});
}
}
]);
GlobalRules.run($("body"));
// If you need to add elements later on, you can just call GlobalRules.run(yourNewElement);
Bu, standart olmayan etkinlikleriniz veya yaratma etkinlikleriniz varsa kuralları kaydetmenin çok etkili bir yoludur. Bu aynı zamanda, bir pub / sub bildirim sistemi ile birleştirildiğinde ve bir element oluşturduğunuzda ateşlediğiniz bir olaya bağlandığında ciddi anlamda şaşırtıcıdır. Fire'n'forget modüler olay bağlamayı!