]> permondes.de Git - PocketCalculator.git/blob - Taschenrechner.html
Signed-off-by: permondes <machen@permondes.de>
[PocketCalculator.git] / Taschenrechner.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
5 <meta name="author" content="Permondes (see permondes.de)">
6 <meta name="date" content="2019-12-17a">
7
8 <title>Permondes Pocket Calculator</title>
9
10 <!-- Taschenrechner, adopted from https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/Taschenrechner
11 Usage
12 = | <enter>: Ergebnis berechnen
13 √ | "r": Wurzel
14 x²| "S": Quadrat
15 ln| "l": natürlicher Logarithmus
16 ANS|"a": answer, letztes Resultat
17 STO|"s": store in memory
18 RCL|"m": recall memory
19 ENG|"n": notation (exponential / norm)
20 ESC|"c": zurücksetzen auf Null
21 -->
22
23 <!-- style ------------------------------------------------------------------------------------------------------------>
24 <style>
25 body {
26 background: #505050;
27 }
28
29 /* form of calculator */
30 #calc {
31 border: 1px solid dimgray;
32 border-radius: 0.2em;
33 box-shadow: inset 0 0 1px LightGray;
34 display: inline-block;
35 padding: 1em 0;
36 text-align: center;
37 width: 50em;
38 }
39
40 /* input and output area fieldset */
41 .cl_IO {
42 border: inset;
43 }
44
45 #f_Eingabe, #f_Ergebnis, #f_Formel {
46 display: block;
47 height: 1em;
48 background: #cee7ce;
49 font-size: 300%;
50 padding: 0.2em 1em; /* top, bottom: 0; left, right: 1 */
51 text-align: left;
52 }
53
54 #f_Ergebnis {
55 background: #aec7ae;
56 text-align: right;
57 }
58
59 /* buttens fieldset */
60 .cl_Buttons {
61 border: none;
62 margin: 0 auto;
63 padding-bottom: 0;
64 }
65
66 #calc button {
67 border: 2px #222222 outset;
68 background-image: linear-gradient(to bottom right, #222222, #585858);
69 font-weight: bold;
70 color: white;
71 cursor: pointer;
72 margin: 5px;
73 padding: 0px;
74 width: 4em;
75 height: 3em;
76 font-size: 200%;
77 }
78
79 </style>
80
81 <!-- script ------------------------------------------------------------------------------------------------------------>
82 <script>
83 "use strict";
84
85 var
86 v_Formel, v_Ergebnis, v_Eingabe,
87 ans = 0.0, mem = 0.0,
88 v_FormularOverwrite = true,
89 notation = "NORM";
90
91 // convert a number to text taking into account the notation
92 function convertNumToText(p_notation, p_number) {
93 var v_text;
94 if (p_notation == "ENG") {
95 v_text = p_number.toExponential();
96 } else {
97 v_text = p_number.toString();
98 }
99 return v_text;
100 }
101
102 function toggleNotation() {
103 switch (notation) {
104 case "NORM":
105 notation = "ENG";
106 break;
107 case "ENG":
108 notation = "NORM";
109 break;
110 }
111 v_Ergebnis.value = convertNumToText(notation, ans);
112 }
113
114 /* clear Formular field */
115 function clear_Formular () {
116 v_Formel.value = "";
117 }
118
119 /* clear fields */
120 function key_clear () {
121 v_Eingabe.value = "";
122 clear_Formular ();
123 v_Ergebnis.value = "";
124 }
125
126 /* delete last character */
127 function deletechar () {
128 v_Eingabe.value = v_Eingabe.value.substr(0, v_Eingabe.value.length-1);
129 }
130
131 /* input of number, decimal point, e or () */
132 function key_number (c) {
133 if (c == ",") {c="."}
134 v_Eingabe.value += c;
135 }
136
137 function getLastResult () {
138 v_Eingabe.value = convertNumToText(notation, ans);
139 }
140
141 // Memory handling
142 function memory_store () {
143 mem = ans;
144 }
145
146 function memory_recall () {
147 v_Eingabe.value = convertNumToText(notation, mem);
148 }
149
150
151 /* Basic arithmetics */
152 function operator_function (c) {
153 if (v_FormularOverwrite) {
154 clear_Formular();
155 v_FormularOverwrite = false; }
156 v_Formel.value += " " + v_Eingabe.value + " " + c; // Operatoren sind durch Leerzeichen von den Zahlen getrennt
157 v_Eingabe.value = "";
158 }
159
160 /* In der Funktion extra() werden Math Berechnungen durchgeführt */
161 function extra_function (type) {
162 switch (type) {
163 case "√":
164 v_Eingabe.value = Math.sqrt(v_Eingabe.value);
165 break;
166 case "x²":
167 v_Eingabe.value = Math.pow(v_Eingabe.value, 2);
168 break;
169 case "ln":
170 v_Eingabe.value = Math.log(v_Eingabe.value);
171 break;
172 }
173 }
174
175 // Bei einem Klick auf = (oder bei passender Benutzung der Tastatur) berechnet die Funktion result() das Ergebnis.
176 // Mit einem RegEx werden nur Ziffern, der Dezimalpunkt und die vier Operatoren als gültige Zeichen für die Berechnung zugelassen (inklusive möglicher Leerzeichen). Dabei werden die üblichen Tastenbeschriftungen für Multiplikation und Division durch ihre JavaScript-Entsprechungen ersetzt. Das eigentliche Rechenergebnis wird mit der window-Methode eval berechnet.
177 function result () {
178 operator_function("");
179 var
180 input = v_Formel.value,
181 r = 0
182 ;
183
184 // replace × with * and ÷ with / for eval()
185 input = input.replace(/×/g, "*").replace(/÷/g, "/");
186
187 // remove anything else that is not allowed here
188 input = input.replace(/[^0-9.e() +\-*\/]/g, "");
189
190 try {
191 r = eval(input);
192 } catch (e) {
193 r = 0;
194 }
195
196 // v_Ergebnis.textContent = convertNumToText(notation, r);
197 v_Formel.value = v_Formel.value + "=";
198 v_Ergebnis.value = convertNumToText(notation, r);
199 v_FormularOverwrite = true;
200 ans = r;
201 }
202
203 /* Der Eventhandler DOMContentLoaded wird ausgelöst, wenn das DOM vollständig aufgebaut,
204 aber noch nicht alle externen Ressourcen wie z.B. Bilder geladen sind.. */
205 document.addEventListener("DOMContentLoaded", function () {
206
207 v_Formel = document.getElementById("f_Formel");
208 v_Ergebnis = document.getElementById("f_Ergebnis");
209 v_Eingabe = document.getElementById("f_Eingabe");
210 key_clear();
211 var form = document.getElementById("calc");
212
213 /* click-handling für alle buttons in #calc erstellen */
214 document.querySelectorAll("#calc button").forEach(function (b) {
215 var c = b.textContent;
216
217 switch (c) {
218 case "9":
219 case "8":
220 case "7":
221 case "6":
222 case "5":
223 case "4":
224 case "3":
225 case "2":
226 case "1":
227 case "0":
228 case ".":
229 case "e":
230 case "(":
231 case ")":
232 b.addEventListener("click", function () { key_number(c); });
233 break;
234
235 case "ANS":
236 b.addEventListener("click", function () {getLastResult(); });
237 break;
238
239 case "STO":
240 b.addEventListener("click", function () { memory_store(); });
241 break;
242 case "RCL":
243 b.addEventListener("click", function () { memory_recall(); });
244 break;
245
246 case "+":
247 case "-":
248 case "×":
249 case "÷":
250 b.addEventListener("click", function () { operator_function(c); });
251 break;
252
253 case "√":
254 case "x²":
255 case "ln":
256 b.addEventListener("click", function () { extra_function(c); });
257 break;
258
259 case "DEL":
260 b.addEventListener("click", function () { deletechar() } );
261 break;
262
263 case "C":
264 b.addEventListener("click", function () {key_clear() });
265 break;
266
267 case "=":
268 b.addEventListener("click", function () {result() });
269 break;
270
271 case "ENG":
272 b.addEventListener("click", function () {toggleNotation();});
273 break;
274
275 }
276 });
277
278 /* reacting on keypress */
279 document.addEventListener("keyup", function (ev) {
280 var c = ev.key;
281
282 switch (c) {
283 case "9":
284 case "8":
285 case "7":
286 case "6":
287 case "5":
288 case "4":
289 case "3":
290 case "2":
291 case "1":
292 case "0":
293 case ".":
294 case ",":
295 case "e":
296 case "(":
297 case ")":
298 key_number(c);
299 break;
300 case "l":
301 extra_function("ln");
302 break;
303 case "r":
304 extra_function("√");
305 break;
306 case "S":
307 extra_function("x²");
308 break;
309 case "Escape": // <escape> to clear display
310 case "c":
311 key_clear();
312 break;
313 case "Backspace": // <backspace> to remove 1 char
314 deletechar();
315 break;
316 case "*":
317 case "/":
318 case "+":
319 case "-":
320 operator_function(c);
321 break;
322 case "Enter":
323 result();
324 break;
325 case "a":
326 getLastResult();
327 break;
328 case "m":
329 memory_recall();
330 break;
331 case "s":
332 memory_store();
333 break;
334 case "n":
335 toggleNotation();
336 break;
337 }
338 });
339
340 /* Da der Taschenrechner ein einzeiliges Formularfeld enthält,
341 kann dieses Formular jederzeit mit Betätigung der Eingabetaste abgesendet werden.
342 Ein Absenden ist im Zusammenhang mit dem Taschenrechner jedoch unerwünscht.
343 Deshalb wird mit addEventListener eine Funktion an das submit-Event des <form>-Elements gebunden, die verhindert,
344 dass der Browser das Standardverhalten beim Absenden eines Formulars ausführt: */
345 form.addEventListener("submit", function (ev) {
346 // prevent form submission and page reload
347 ev.preventDefault();
348 ev.stopPropagation();
349 return false;
350 });
351 form.addEventListener("dblclick", function (ev) {
352 ev.preventDefault();
353 ev.stopPropagation();
354 return false;
355 });
356
357
358 } )
359
360 </script>
361
362 </head>
363
364 <!-- body -------------------------------------------------------------------------------------------------------------->
365 <body>
366 <h1>Permondes <br/>Pocket Calculator</h1>
367 <main role="main">
368 <form id="calc">
369 <fieldset class="cl_IO">
370 <input id="f_Formel" readonly></input>
371 <input id="f_Ergebnis" readonly></input>
372 <input id="f_Eingabe" readonly></input>
373 </fieldset>
374 <fieldset class="cl_Buttons">
375 <button></button>
376 <button></button>
377 <button>ln</button>
378 <button>&nbsp;</button>
379 <button>&nbsp;</button>
380
381 <button>STO</button>
382 <button>RCL</button>
383 <button>ENG</button>
384 <button>DEL</button>
385 <button>C</button>
386
387 <button>7</button>
388 <button>8</button>
389 <button>9</button>
390 <button>(</button>
391 <button>)</button>
392
393 <button>4</button>
394 <button>5</button>
395 <button>6</button>
396 <button>×</button>
397 <button>÷</button>
398
399 <button>1</button>
400 <button>2</button>
401 <button>3</button>
402 <button>+</button>
403 <button>-</button>
404
405 <button>0</button>
406 <button>.</button>
407 <button>e</button>
408 <button>ANS</button>
409 <button>=</button>
410 </fieldset>
411 </form>
412 </main>
413 </body>
414
415 </html>