Javascript läßt sich nicht auslagern
Matthias
- html
- javascript
Hallo,
Ich habe einen Code geschrieben, der mir eine Anzeigt wenn eine Checkbox aktiviert wird. Das klapt auch soweit ganz gut, nur wenn ich das <script> in die Datei 'boxentest.js' auslagere funktioniert das ganze nicht mehr. (Ja die beiden Dateien liegen im selben Ordner!!) Was mache ich also falsch?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="boxentest.js"></script>
<meta name="viewport" content="width=device-width">
<title>Test</title>
</head>
<body>
<tr>
<td> Rand: <input type="checkbox" id="s1" value="Rand"> </td>
<td> Schatten: <input type="checkbox" id="s2" value="Schatten"> </td>
<td> Steg: <input type="checkbox" id="s3" value="Steg"> </td>
</tr>
<p id="box1"></p>
<p id="box2"></p>
<p id="box3"></p>
<script>
document.getElementById("s1").addEventListener("change", function() {
if(this.checked) {
document.getElementById("box1").innerHTML = "Rand ist aktiviert!";
} else {
document.getElementById("box1").innerHTML = "";
}
});
document.getElementById("s2").addEventListener("change", function() {
if(this.checked) {
document.getElementById("box2").innerHTML = "Schatten ist aktiviert!";
} else {
document.getElementById("box2").innerHTML = "";
}
});
document.getElementById("s3").addEventListener("change", function() {
if(this.checked) {
document.getElementById("box3").innerHTML = "Steg ist aktiviert!";
} else {
document.getElementById("box3").innerHTML = "";
}
});
</script>
</body>
</html>
@@Matthias
Was mache ich also falsch?
Da du nicht das zeigst, was nicht funktioniert, kann man dir auch nicht sagen, warum es nicht funktioniert.
Eine Vermutung habe ich aber: Wo setzt du das script
-Element denn hin? JavaScript wird (ohne weiteres Zutun) sofort dort ausgeführt, wo es steht – und blockiert solange das Parsen des nachfolgenden HTMLs und das Rendern der Seite, was nicht gut für die percieved performance ist. Wenn es ausgeführt wird und Elemente ansprechen will, die zu dem Zeitpunkt noch gar nicht im DOM vorhanden sind, dann kann das nur schiefgehen.
document.getElementById("box1").innerHTML = "Rand ist aktiviert!";
Was du außerdem falsch machst: Es gibt keinen Grund, die Strings, die kein Markup enthalten, nach Markup zu parsen. Verwende nicht innerHTML
, sondern textContent
.
Kwakoni Yiquan
@@Matthias
Was mache ich also falsch?
Und noch was:
<p id="box1"></p> <p id="box2"></p> <p id="box3"></p>
document.getElementById("box1").innerHTML = "Rand ist aktiviert!";
Du lässt Änderungen in den Boxen nicht von assistiven Technologien (wie bspw. Screenreadern) bekanntgeben. Die Boxen sollten das aria-live
-Attribut tragen:
<p id="box1" aria-live="polite"></p>
<p id="box2" aria-live="polite"></p>
<p id="box3" aria-live="polite"></p>
Kwakoni Yiquan
Lieber Matthias,
als Ergänzung zu den Hinweisen von Gunnar noch dieses:
DRY (don't repeat yourself) - vermeide identischen Code, wenn Du kannst.
In Deinem gezeigten JS-Code prüfst Du dreimal, ob eine Checkbox aktiviert ist, um dann einen Elementinhalt passend zu ändern. Da sollte es möglich sein, den Code genau nur einmal zu schreiben und dann entsprechend oft anzuwenden. Damit das sinnvoll gegliedert werden kann, hier ein Beispiel, wie ich das tun würde:
const tasks = [
{
"checkboxID": "s1",
"checked": "Rand ist aktiviert!",
"outputID": "box1",
"unchecked": ""
},
{
"checkboxID": "s2",
"checked": "Schatten ist aktiviert!",
"outputID": "box2",
"unchecked": ""
},
{
"checkboxID": "s3",
"checked": "Steg ist aktiviert!",
"outputID": "box3",
"unchecked": ""
}
];
document.body.addEventListener("input", event => {
tasks.forEach(data => {
const
checkbox = document.getElementById(data.checkboxID),
output = document.getElementById(data.outputID);
if (checkbox && output && event.target == checkbox) {
output.textContent = checkbox.checked ? data.checked : data.unchecked;
}
});
});
Zuerst wird eine Liste (Array) namens tasks
beschrieben, die Objekte enthält, die jeweils darstellen sollen, was wie zusammenhängt und welche Textausgaben hat. Ein solches Objekt (als Objekt-Literal notiert) hat vier Eigenschaften:
checkboxID
- die ID von <input type="checkbox">
checked
- der anzuzeigende Textinhalt, wenn die Checkbox aktiviert istoutputID
- die ID desjenigen Elements, dessen Textinhalt als Ausgabe dientunchecked
- der anzuzeigende Textinhalt, wenn die Checkbox nicht aktiviert istDer EventListener der Wahl lautet nicht change
, sondern input
. Die Funktion, die als zweiter Parameter für addEventListener()
angegeben ist, wurde hier als Pfeilfunktion notiert. Wichtig ist der Parameter event
, der das Event-Objekt enthalten wird, wenn ein Eingabefeld bedient wird. Mit event.target
lässt sich dann prüfen, ob eine unserer Checkboxen aktuell „angefasst“ wurde. Es ist sinnvoll, nur einen EventListener zu verwenden, anstatt an jedes Element einen eigenen zu pappen, weshalb er hier an document.body
geklebt wird. In Deinem Fall kannst Du ihn auch auf das passende <form>
aufkleben.
In der EventListener-Funktion wird nun jedes der Objekte in tasks
einzeln abgearbeitet. Die Array-Methode forEach
funktioniert im Grunde wie eine Schleife, nur dass man sich innerhalb einer (anonymen) Funktion befindet, die das jeweilige Array-Element als Parameter übergeben bekommt. Die anonyme Funktion hier (auch wieder als Pfeilfunktion notiert) nimmt das Element in der Variable data
entgegen.
Mit dem Objekt in data
können wir nun die Checkbox und das Anzeige-Element suchen. Wenn in den Variablen checkbox
und output
passende HTML-Element-Objekte stehen, dann ist das wie ein true
, und wenn das HTML-Element in checkbox
auch wirklich dasjenige ist, von dem das Ereignis ausgegangen ist, dann kann in das Ausgabe-Element ein entsprechender Inhalt geschrieben werden. Der ternäre Operator ist eine verkürzte Schreibweise, um sich ein if-else zu sparen.
Liebe Grüße
Felix Riesterer
Hey, Danke für die Hilfreichen Info's ich werde mal versuchen die Tips umzusetzen und mich dann zurück melden..... Da mache ich aber einen neuen Beitrag auf weil ich die Fragestellung noch um einen Colorinput und eine verknüpfte Ausgabe erweitern werde.... Ich war nämlich erst skeptisch wie komplex die Anfragen hier sein sollten, aber ich sehe - Ich habe hier mit 'den Guten' zu tun also werde ich mich wagen.....
Außerdem habe ich jetzt einen Account und würde meine Frage darüber stellen wollen.
Danke bis hierhin!