Po pierwsze, istnieją trzy wyniki czynność może : nie rób nic, zadzwoń pod numer this.close()
lub zadzwoń pod numer this.open()
. Idealnie więc wynikowa funkcja będzie miała jedną instrukcję if, która określa, który wynik jest używany.
Następnym krokiem jest wyodrębnienie całego kodu boolowskiego do zmiennych. Np. var leftPastCenter = this.content.getBoundingClientRect().left > viewport/2
.
Wreszcie, użyj logiki boolowskiej, aby uprościć ją krok po kroku.
Oto jak to zrobiłem:
Po pierwsze, należy wyodrębnić wszystkie zmienne logiczne:
function() {
var duration = +new Date() - start.time,
isPastHalf = Number(duration) < 250 && Math.abs(delta.x) > 20 || Math.abs(delta.x) > viewport/2,
direction = delta.x < 0,
leftPastCenter = this.content.getBoundingClientRect().left > viewport/2,
positiveDelta = this.isEmpty(delta) || delta.x > 0,
isPulled = pulled === true; // I'll assume the test is needed rather than just using pulled.
if (!isScrolling) {
if (isPastHalf) {
if (direction) {
this.close();
} else {
if (leftPastCenter && isPulled) {
this.close();
return;
}
this.open();
}
} else {
if (leftPastCenter) {
if (positiveDelta) {
this.close();
return;
}
this.open();
return;
}
this.close();
}
}
}
najłatwiejsza część wyciągnąć realizuje jeśli isScrolling
to prawda, nic się nie dzieje. Ten natychmiast pozbywa się jednego poziomu zagnieżdżenia:
// above same
if (isScrolling) { return; }
if (isPastHalf) {
if (direction) {
this.close();
} else {
if (leftPastCenter && isPulled) {
this.close();
return;
}
this.open();
}
} else {
if (leftPastCenter) {
if (positiveDelta) {
this.close();
return;
}
this.open();
return;
}
this.close();
}
}
Spójrzmy teraz na sprawach this.open()
są nazywane. Jeśli isPastHalf
jest prawdziwe, this.open()
jest wywoływane tylko wtedy, gdy !direction
i !(leftPastCenter && isPulled)
.Jeśli isPastHalf
jest fałszywe, a następnie this.open()
nazywa się tylko wtedy, gdy leftPastCenter
i !positiveDelta
:
// above same
if (isScrolling) { return; }
if (isPastHalf) {
if (!direction && !(leftPastCenter && isPulled)) {
this.open();
} else {
this.close();
}
} else {
if (leftPastCenter && !positiveDelta) {
this.open();
} else {
this.close();
}
}
Rzut IFS (tak this.close()
nastąpi wcześniej), sprawia, że kod nieco schludniej i daje moją ostateczną wersję:
function() {
var duration = +new Date() - start.time,
isPastHalf = Number(duration) < 250 && Math.abs(delta.x) > 20 || Math.abs(delta.x) > viewport/2,
direction = delta.x < 0,
leftPastCenter = this.content.getBoundingClientRect().left > viewport/2,
positiveDelta = this.isEmpty(delta) || delta.x > 0,
isPulled = pulled === true; // I'll assume the test is needed rather than just using pulled.
if (isScrolling) { return; }
if (isPastHalf) {
if (direction || (leftPastCenter && isPulled)) {
this.close();
} else {
this.open();
}
} else {
if (!leftPastCenter || positiveDelta) {
this.close();
} else {
this.open();
}
}
}
Trudno jest mi zrobić więcej, nie znając Twojego kodu. Warto zauważyć, że direction
i moja nowa zmienna positiveDelta
są prawie identyczne - można usunąć positiveDelta
i po prostu użyć direction
. Ponadto, direction
nie jest dobrą nazwą dla boolowskiej, coś jak movingLeft
byłoby lepsze.
Co daje ten błąd? – marekful
Poważnie? Nie używaj zagnieżdżonych 'jeśli's. Określ odpowiedzialność zgodnie z * zasadą odpowiedzialności pojedynczej *. Jeden fragment kodu (moduł) powinien wykonać jedną i tylko jedną rzecz i powinien to zrobić dobrze. Wystarczy pomyśleć o tym, jak wiele możliwych ścieżek wykonania wykonują te brzydkie krzaki if ... – Powerslave
Czy przeczytałeś kod @Powerslave? Jak to łamie SRP? – Joe