Omówię kilka prostych rzeczy, które mogą ci pomóc lub nie. Niektóre mogą być oczywiste, inne mogą być niezwykle tajemnicze.
Krok 1: Rozmieść swój kod
Rozdzielenie kodu na wiele modułowych jednostek to bardzo dobry pierwszy krok. Zbierz to, co działa „razem” i umieść je w ich małych, zamkniętych jednostkach. nie martw się na razie o format, zachowaj go w tekście. Struktura jest późniejszym punktem.
Załóżmy więc, że masz taką stronę:
Miałoby sens, aby podzielić na przedziały, tak aby wszystkie związane z nagłówkami programy obsługi zdarzeń / segregatory były tam, dla ułatwienia konserwacji (i bez konieczności przesiewania przez 1000 wierszy).
Następnie możesz użyć narzędzia takiego jak Grunt, aby przebudować JS z powrotem do pojedynczej jednostki.
Krok 1a: Zarządzanie zależnościami
Użyj biblioteki, takiej jak RequireJS lub CommonJS, aby zaimplementować coś, co nazywa się AMD . Asynchroniczne ładowanie modułu umożliwia jawne określenie, od czego zależy Twój kod, co następnie umożliwia odciążenie wywołania biblioteki do kodu. Możesz po prostu powiedzieć „To potrzebuje jQuery”, a AMD załaduje je i wykona kod, gdy jQuery będzie dostępne .
Ma to również ukryty klejnot: ładowanie biblioteki nastąpi w momencie, gdy DOM będzie gotowy, a nie wcześniej. To już nie zatrzymuje ładowania Twojej strony!
Krok 2: Modularyzacja
Widzisz szkielet? Mam dwie jednostki reklamowe. Najprawdopodobniej będą mieć wspólne słuchacze wydarzeń.
Twoim zadaniem na tym etapie jest zidentyfikowanie punktów powtórzeń w kodzie i próba zsyntetyzowania tego wszystkiego w moduły . Moduły będą teraz obejmować wszystko. Będziemy dzielić rzeczy w trakcie.
Cała idea tego kroku polega na przejściu od kroku 1 i usunięciu wszystkich kopiowanych makaronów, aby zastąpić je jednostkami, które są luźno powiązane. Więc zamiast mieć:
ad_unit1.js
$("#au1").click(function() { ... });
ad_unit2.js
$("#au2").click(function() { ... });
Będę miał:
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();
Co pozwala ci na oddzielenie wydarzeń od twoich znaczników, a także pozbycie się powtórzeń. To całkiem przyzwoity krok, który później rozszerzymy.
Krok 3: Wybierz ramy!
Jeśli chcesz jeszcze bardziej zmodularyzować i zmniejszyć liczbę powtórzeń, istnieje kilka niesamowitych frameworków, które implementują podejścia MVC (Model - Widok - Kontroler). Moim ulubionym jest Backbone / Spine, ale jest też Angular, Yii, ... Lista jest długa.
Model przedstawia swoje dane.
Zobacz reprezentuje Mark-up i wszystkie zdarzenia związane z nim
Controller reprezentuje logikę biznesową - innymi słowy, regulator mówi strony co do obciążenia i poglądy, co do korzystania z modeli.
Będzie to znaczący krok do nauki, ale nagroda jest tego warta: preferuje czysty, modułowy kod zamiast spaghetti.
Jest wiele innych rzeczy, które możesz zrobić, to tylko wskazówki i pomysły.
Zmiany specyficzne dla kodu
Oto kilka konkretnych ulepszeń kodu:
$('.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);
}
}
});
});
Jest to lepiej napisane jako:
$("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);
}
});
});
Wcześniej w kodzie:
window.Layer = function() {
this.instance = $("<div>");
// Markup generated here
};
window.Layer.prototype = {
setName: function(newName) {
},
bindToGroup: function(parentNode) {
}
}
Nagle masz sposób na utworzenie standardowej warstwy z dowolnego miejsca w kodzie bez wklejania kopii. Robisz to w pięciu różnych miejscach. Właśnie uratowałem ci pięć pasty do kopiowania.
Jeszcze jeden:
// Opakowanie zestawu reguł dla akcji
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);
Jest to bardzo skuteczny sposób rejestrowania reguł, jeśli masz zdarzenia, które nie są standardowe lub zdarzenia tworzenia. Jest to również naprawdę niesamowite w połączeniu z systemem powiadomień pub / sub oraz w przypadku powiązania z wydarzeniem, które uruchamiasz za każdym razem, gdy tworzysz elementy. Fire'n'forget modułowe wiązanie wydarzeń!