JavaScript on-the-fly berechnen mit Button

Crys

Lt. Commander
Registriert
Apr. 2009
Beiträge
1.651
HTML:
<!DOCTYPE html>
<html>
<head>
    <title>JS-Rechner</title>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
    <script type='text/javascript'>
        function verstecken() {
            var link = document.getElementById('b1');
            link.style.display = 'none';
        }
        document.addEventListener("load", verstecken, false);
    </script>
</head><body>

<form>
    <input type='number' id='i1' placeholder='Erste Zahl'>
    <label for='i1'>Ausgangswert</label><br />
    
    <input type='number' id='i2' placeholder='Zweite Zahl'>    
    <button type='button' id='b1'>Zahl</button>
    <label for='i2'>Button gibt mögliche Zahl für 'Zweite Zahl' aus</label>
</form> 

</body>
</html>

Ich möchte nur, das der Button beim laden versteckt wird.
Dann möchte ich in "Erste Zahl" eine Zahl eintragen, dann soll der Button erscheinen (soll nur da sein, wenn was in "Erste Zahl" eingetragen ist).
Die Beschriftung vom Button soll ein Rechenergebis sein z.B. "Erste Zahl" mal 2.
Wenn man auf den Button klickt, dann soll das Rechenergebis in "Zweite Zahl" eingetragen werden und ein eventueller Inhalt überschrieben werden.

Wie stelle ich das am besten an?
 
Mit CSS: display: none / display: block ( / inline ... was auch immer da die derzeitige Eisntellung ist). Das kannst du ja mit JS toggeln.
 
Häng an das input-Feld i1 einen onChange-Handler, der bei jedem change-Event prüft, ob das Feld leer ist oder nicht, und dementsprechend den Button zeigt oder versteckt.

Und an den Button einen onClick-Handler, der das Ergebnis berechnet und einträgt.
 
Danke NullPointer!

HTML:
<!DOCTYPE html>
<html>
<head>
    <title>JS-Rechner</title>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
    <script type='text/css'>
        #b1 {
            display: none;
        }
    </script>
    <script type='text/javascript'>
        function KnopfAendern(){
            var knopf = document.getElementById('b1');
            var ersteZahl = document.getElementById('i1');
            var zweiteZahl = document.getElementById('i2');
            
            if (ersteZahl.value=='' || isNaN(ersteZahl.value)){
                knopf.style.display = 'none';
            }else{
                var inhalt = ersteZahl.value * 5;
                    
                knopf.style.display = 'inline';
                knopf.innerHTML = inhalt;
            }
        }
        
        function InputAendern(){
            var zweiteZahl = document.getElementById('i2');
            var knopf = document.getElementById('b1');
            
            zweiteZahl.value = knopf.innerHTML;
        }
    </script>
</head><body>

<form>
    <input type='number' id='i1' placeholder='Erste Zahl' onchange='KnopfAendern();'>
    <label for='i1'>Ausgangswert</label><br />
    
    <input type='number' id='i2' placeholder='Zweite Zahl'>    
    <button type='button' id='b1' onclick='InputAendern();'>Zahl</button>
    <label for='i2'>Button gibt mögliche Zahl für 'Zweite Zahl' aus</label>
</form> 

</body>
</html>
Was kann ich an diesen Skript-Schnipsel noch vereinfachen?
Sind Fehler drin?
 
Zuletzt bearbeitet:
<script type='text/css'> so such thing :D Sonst ist der Ansatz schon richtig.

Ich würde dir 2 Dinge vorschlagen: Entweder Packst du den ganzen <script> Tag vor den </body> oder startest alles erst mit dem "DOMContentLoaded" Event. Dann hast du nämlich vollen Zugriff auf den DOM und kannst sowas machen:

Code:
var ersteZahl = document.getElementById('i1');
var zweiteZahl = document.getElementById('i2');
var knopf = document.getElementById('b1');

function InputAendern(){
    zweiteZahl.value = knopf.innerHTML;
}

knopf.addEventListener("click", InputAendern);
ersteZahl.addEventListener("input", KnopfAendern); //...

Das geht ohne Probleme und du musst nicht jedes mal die Elemente neu aus dem DOM fischen. So kannst du auch Variablen (mit DOM Elementen drin) über mehrere Funktionen hinweg nutzen.

Statt dem "change" Event kannste das "input" Event nehmen. Dann wird bei jeder Änderung die Zahl neu berechnet und nicht nur wenn das Input-Feld den Fokus verliert.
 
T0a5tbr0t schrieb:
<script type='text/css'> so such thing :D Sonst ist der Ansatz schon richtig.
Oha, habe ich gar nicht gesehen :D

T0a5tbr0t schrieb:
Statt dem "change" Event kannste das "input" Event nehmen. Dann wird bei jeder Änderung die Zahl neu berechnet und nicht nur wenn das Input-Feld den Fokus verliert.
Danke, so ist das noch viel besser!

T0a5tbr0t schrieb:
Ich würde dir 2 Dinge vorschlagen: Entweder Packst du den ganzen <script> Tag vor den </body> oder startest alles erst mit dem "DOMContentLoaded" Event. Dann hast du nämlich vollen Zugriff auf den DOM [...]
Sorry, das verstehe ich nicht. Das script ist ja schon vor dem </body>, halt im head ... meinst du im body?

T0a5tbr0t schrieb:
Das geht ohne Probleme und du musst nicht jedes mal die Elemente neu aus dem DOM fischen. So kannst du auch Variablen (mit DOM Elementen drin) über mehrere Funktionen hinweg nutzen.
Das Skript geht ja so nicht. Die Funktionen können dann ja nicht auf die Variablen zugreifen!?
 
Ich meinte direkt vor das </body> Ende. Der Browser arbeitet die Seite immer vom Oben nach Unten ab. Und am unteren Ende hat man dann schon den gasammten DOM zur Verfügung.

Crys schrieb:
Das Skript geht ja so nicht. Die Funktionen können dann ja nicht auf die Variablen zugreifen!?
Klar geht das in JavaScript ;)
Du kannst in Funktionen immer auf Variablen außerhalb des "Funktions-Scope" zugreifen. Nur darf "getElementById" eben erst nach laden des DOM's ausgeführt werden, denn sonst findet der nix.

Code:
function init() {
    var el = document.getElementById("foo");
    
    document.getElementById("bar").addEventListener("click", function() {
        // Hier kannst du el nutzen, denn JavaScript findet die Variable im Scope von "init"
        el.style.color = "#BADA55";
    });

    var nope = function() {
        var el = "megastring";
        // Hier ist el jetzt ein String
    }
    nope();

    document.getElementById("foo").addEventListener("click", function() {
        // Hier kannst du el auch nutzen und es ist immer noch ein Element
        el.style.color = "#F00000";
    });
    
}
document.addEventListener("DOMContentLoaded", init);
// Hier draußen kannst du nicht auf el zugreifen!
Diese "Magie" nennt man Closure. JavaScript "merkt" sich die Variablen und behält sie im Closure der Funktion.
 
Danke Toastbrot!

Ich habe noch etwas weiter gesucht, da ich die Ordnung liebe und des Skript gerne im Head habe.
HTML:
<script type='text/javascript' src='script.js' defer='defer'></script>
Das "defer"-Attribute war die Lösung. Dadurch wird das Skript erst nach dem vollständigen Parsen ausgeführt.
 
Ah clever ;) Ich verwende das Attribut selten, denn bei mehreren <script> Tags kann man sich leider nicht mehr auf die Reihenfolge verlassen. Vllt. solltest du auch isNaN mit parseInt tauschen. Macht in deinem Fall wohl nicht so viel aus, aber isNaN ist SHER buggy.
Code:
isNaN(null) // => false, WHAT?
typeof null // => "object", Jap das ist ein Bug in JavaScript, müsste "null" sein...
isNaN(true) // => false, JavaScript halt... :D
 
Auf defer sollte man sich, so oder so, nie verlassen. Browser, die defer nicht beherrschen, parsen das Script dann direkt beim Auftauchen des <script>-Tags.
Ich verwende auch gern defer, aber nur in Kombination mit async (also: erst async versuchen, dann defer versuchen, dann direkt durchlaufen lassen), aber ausschließlich bei Scripts, bei denen eine DOM-Manipulation nicht nötig ist.

Für alles, was garantiert erst nach dem kompletten DOM zünden darf, verwende ich die DOM-Ready - Events von jQuery oder Mootools. Eines der Frameworks verwende ich eh immer für irgend was (z.B. Slider), ist also kein Overhead.
 
Für Typunterscheidung immer Object.prototype.toString.call(null); --> [object Null]
 
T0a5tbr0t schrieb:
Macht in deinem Fall wohl nicht so viel aus, aber isNaN ist SHER buggy.
ne es ist nicht buggy. Das ist einer dieser Punkte in JavaScript der komplett jeglicher Logik widerspricht.
Wat - Destroy All Software Talks nimm dir die 2 Minuten, warte das erste Ruby-Beispiel ab und kringel dich dann vor lachen ;)

Am besten nie das Typsystem von JavaScript in so einem kranken Edge-Case brauchen.
Wobei isNaN(null) und isNaN(true) mit false noch logisch ist, denn "NaN" beschreibt den Wert einer illegalen artihm. Operation. Also 1/0 ist beispielsweise NaN, also ein ganz spezieller Wert, der angibt, dass es keine korrekte Zahl ist. Und sowohl null als auch true sind eben nicht dieser ganz spezielle Wert.
 
Jo "buggy" ist wohl der falsche Begriff, aber isNaN verhält sich komisch, da der angegebene Werte zuerst konvertiert wird bzw. "Not a Number" auch eine Zahl ist und der Name verwirrt.
Und 1/0 ist übrigens nicht NaN ;)
0/0 ist NaN :freak:
Das Problem haben auch andere Programmiersprachen welche IEEE 754 für Zahlen nutzen. Da gibt es eben diese "nicht-zahlen-zahl" und deshalb ist auch 0.1 + 0.2 !== 0.3...
Man muss diese kleinen Fehler eben kennen und umgehen.
 
Zuletzt bearbeitet:
Zurück
Oben