In primo luogo, ci sono tre risultati vostra funzione possono avere: non fare nulla, chiamare this.close()
o chiamare this.open()
. Quindi idealmente la funzione risultante avrà una sola istruzione if che determina quale risultato viene utilizzato.
Il passaggio successivo consiste nell'estrarre tutto il codice booleano in variabili. Ad esempio var leftPastCenter = this.content.getBoundingClientRect().left > viewport/2
.
Infine, utilizzare la logica booleana per semplificare passo dopo passo.
Ecco come ho fatto:
In primo luogo, l'estratto di tutte le variabili booleane:
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();
}
}
}
La parte più facile da tirare fuori se sta realizzando isScrolling
è vero, non succede mai niente. Questo immediatamente si libera di un livello di nidificazione:
// 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();
}
}
Ora guardiamo i casi this.open()
sono chiamati. Se isPastHalf
è vero, this.open()
viene chiamato solo quando !direction
e !(leftPastCenter && isPulled)
.Se isPastHalf
è falso, quindi this.open()
viene chiamato solo quando leftPastCenter
e !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();
}
}
Sfogliando l'IFS (così this.close()
viene prima), rende il codice un po 'più ordinato, e dà la mia versione finale:
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();
}
}
}
È difficile per me fare di più, senza conoscere il codice base. Una cosa da notare è direction
e la mia nuova variabile positiveDelta
è quasi identica - è possibile rimuovere positiveDelta
e utilizzare semplicemente direction
. Inoltre, direction
non è un buon nome per un booleano, qualcosa come movingLeft
sarebbe meglio.
Che cosa sta dando questo errore? – marekful
Seriamente? Non usare nested 'if's. Determinare le responsabilità in base al * principio di responsabilità singola *. Un pezzo di codice (un modulo) dovrebbe fare una sola cosa e dovrebbe farlo bene. Pensa a quanti possibili percorsi di esecuzione generano questi brutti if-bush ... – Powerslave
Hai letto il codice @ PowerDirector? Come si rompe questo SRP? – Joe