Skip to content

HTML, CSS and first steps

Der Taschenrechner besteht aus zwei Teilen:

  • dem Display und
  • den Tasten
<div class="calculator">
<div class="calculator-display">0</div>
<div class="calculator-keys">...</div>
</div>

Die Tasten müssen auf einen Klick reagieren, daher verwenden wir dafür Buttons:

<div class="calculator-keys">
<button class="calculator-key">+</button>
<button class="calculator-key">-</button>
<button class="calculator-key">&times;</button>
<button class="calculator-key">/</button>
<button class="calculator-key">1</button>
<button class="calculator-key">2</button>
<button class="calculator-key">3</button>
<button class="calculator-key">4</button>
<button class="calculator-key">5</button>
<button class="calculator-key">6</button>
<button class="calculator-key">7</button>
<button class="calculator-key">8</button>
<button class="calculator-key">9</button>
<button class="calculator-key">0</button>
<button class="calculator-key">.</button>
<button class="calculator-key">AC</button>
<button class="calculator-key">=</button>
</div>

Diese Buttons ordnen wir in einem Grid an:

.calculator {
display: grid;
// ...
}

Um die Art der Taste und deren Wert zu identifizieren, verwenden wir zwei custom attributes:

  • data-button-type - sagt uns die Art der Taste
  • data-key - sagt uns den Wert der Taste

Wir können die Tasten in fünf verschiedene Gruppen einteilen:

  1. Operatoren (+, -, × /)
  2. Ziffern (0 - 9)
  3. Dezimalpunkt (.)
  4. Gleichheitszeichen (=)
  5. Löschen (AC)

Diese data-attributes fügen wir nun den Tasten hinzu:

<div class="calculator-keys">
<button class="calculator-key" data-key="plus" data-button-type="operator">+</button>
<button class="calculator-key" data-key="minus" data-button-type="operator">-</button>
<button class="calculator-key" data-key="times" data-button-type="operator">&times;</button>
<button class="calculator-key" data-key="divide" data-button-type="operator">/</button>
<button class="calculator-key" data-key="1" data-button-type="number">1</button>
<button class="calculator-key" data-key="2" data-button-type="number">2</button>
<button class="calculator-key" data-key="3" data-button-type="number">3</button>
<button class="calculator-key" data-key="4" data-button-type="number">4</button>
<button class="calculator-key" data-key="5" data-button-type="number">5</button>
<button class="calculator-key" data-key="6" data-button-type="number">6</button>
<button class="calculator-key" data-key="7" data-button-type="number">7</button>
<button class="calculator-key" data-key="8" data-button-type="number">8</button>
<button class="calculator-key" data-key="9" data-button-type="number">9</button>
<button class="calculator-key" data-key="0" data-button-type="number">0</button>
<button class="calculator-key" data-key="decimal" data-button-type="decimal">.</button>
<button class="calculator-key" data-key="clear" data-button-type="clear">AC</button>
<button class="calculator-key" data-key="equal" data-button-type="equal">=</button>
</div>

Wenn wir einen Taschenrechner benutzen, können fünf verschiedene Dinge passieren:

  • Wir klicken auf eine Zahl
  • Wir klicken auf einen Operator
  • Wir klicken auf den Dezimalpunkt
  • Wir klicken auf Istgleich
  • Wir klicken auf Löschen

Wir müssen also überlegen, was passiert, wenn diese Tasten gedrückt werden. Dass es dabei viele Permutationen gibt, macht die Sache einigermaßen kompliziert.

Gehen wir also Schritt für Schritt vor.

Als erstes selektieren wir den Rechner selbst. Für die Tasten verwenden wir das event delegation pattern: wir prüfen zuerst, ob der Klick auf einen Button gegangen ist, wenn nicht, verlassen wir den EventListener gleich wieder.

const calculator = document.querySelector('.calculator');
const calculatorButtonsDiv = calculator.querySelector('.calculator-keys');
calculatorButtonsDiv.addEventListener = ('click', e => {
if(!e.target.closest('button')) return;
});

Die fünf verschiedenen Arten von Tasten können wir mit dem data-button-type Attribut identifizieren:

calculatorButtonsDiv.addEventListener('click', e => {
// ...
const button = e.target;
const { buttonType } = button.dataset;
if (buttonType === 'number') {
console.log('Pressed number');
}
if (buttonType === 'decimal') {
console.log('Pressed decimal');
}
if (buttonType === 'operator') {
console.log('Pressed operator');
}
if (buttonType === 'equal') {
console.log('Pressed equal');
}
if (buttonType === 'clear') {
console.log('Pressed clear');
}
})

Also nochmal: wenn wir einen Taschenrechner in die Hand nehmen, dann drücken wir üblicherweise eine dieser fünf Arten von Tasten:

  • eine Zahl
  • einen Operator
  • den Dezimalpunkt
  • das Istgleich-Zeichen
  • die Löschtaste

Alle fünf Typen auf einmal zu berücksichtigen verursacht einen mental overload. Deshalb überlegen wir uns, was ein “normaler Mensch” eintippen würde. Dieses was würde ein normaler Mensch tun nennt man den happy path.

Nennen wir unsere “normale Person” Mary: Wenn Mary den Taschenrechner in die Hand nimmt, wird sie vermutlich als erstes eine Ziffer eintippen.

Wenn der Taschenrechner aufgerufen wird, zeigt er im Display vermutlich die Ziffer 0 an. Diese Ziffer wollen wir mit der eingegebenen Ziffer ersetzen. Dazu müssen wir zuerst herausfinden, welchen Wert die angeklickte Ziffer hat. Diesen Wert finden wir im key data attribute.

calculatorButtonsDiv.addEventListener('click', e => {
const button = e.target;
const { buttonType, key } = button.dataset;
// ...
});

Als nächstes müssen wir das aktuell angezeigte Resultat finden. Wir bekommen es mit .calculator-display.

const display = calculator.querySelector('.calculator-display');
calculatorButtonsDiv.addEventListener('click', e => {
const button = e.target;
const { buttonType, key } = button.dataset;
const result = display.textContent;
// ...
});

Wenn also aktuell im Display 0 angezeigt wird, wollen wir das durch die eingegebene Ziffer ersetzen:

calculatorButtonsDiv.addEventListener('click', e => {
// ...
if (result === '0') {
display.textContent = key;
}
});

Für denn Fall, dass die Ziffer im Display nicht 0 beträgt (die Wahrscheinlichkeit ist groß, dass bereits eine Ziffer eingegeben wurde), wollen wir die neu eingegebene Ziffer an die bestehende anhängen:

calculatorButtonsDiv.addEventListener('click', e => {
// ...
if (result === '0') {
display.textContent = key;
} else {
display.textContent = result + key;
}
// ...
});

Damit können jetzt beliebig lange Ziffernketten eingegeben werden. Der nächste happy path Fall wäre entweder ein Klick auf den Dezimalpunkt oder auf einen Operator. Da es nur einen Dezimalpunkt gibt, aber vier Operatoren, schauen wir uns zuerst den Dezimalpunkt an.

Wenn der Dezimalpunkt geklickt wird, wollen wir einen . an das Ergebnis anhängen:

calculatorButtonsDiv.addEventListener('click', e => {
// ...
if (buttonType === 'decimal') {
display.textContent = result + '.';
}
// ...
});

If Mary clicks another number after the decimal key

Section titled “If Mary clicks another number after the decimal key”

Für den Fall, dass Mary nach dem Dezimalpunkt wieder eine Ziffer klickt, brauchen wir nichts tun, das wird nämlich schon in der ersten if Abfrage erledigt.