]>
Commit | Line | Data |
---|---|---|
9e114b38 | 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-17"> | |
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>x²</button> | |
377 | <button>ln</button> | |
378 | <button> </button> | |
379 | <button> </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> |