createElement, checkbox und der IE
Sebo
- javascript
4 Gunnar Bittersmann1 Micha1 bonzo400
Hallo!
Ich hab eine Frage zum erstellen einer Checkbox mit JavaScript. Vielleicht kann mir ja jemand helfen.
Im FF und Opera funktioniert es auch ohne Fehlermeldungen. Nur der IE macht mal wieder Sorgen.
Hier das Stück JS:
var formular = document.getElementById('form');
var checkbox = document.createElement('input');
formular.appendChild(checkbox);
checkbox.setAttribute('type', 'checkbox');
Jetzt habe ich gelesen, dass der IE "checkbox" nicht als "type" kennt, sondern dass ich das setAttribute weglassen und createElement('<input type="checkbox">') notieren muss.
Das funktioniert mit dem IE auch so wie beschrieben.
Jetzt würde ich beide Varianten gern für die jeweiligen Browser anbieten,
ich komm mit den Conditional Compilations des IE nicht klar.
Wie schreib ich eine Browserweiche in JS damit ich dem IE seine extra-Wurst braten kann?
Sebo
@@Sebo:
nuqneH
Jetzt habe ich gelesen, dass der IE "checkbox" nicht als "type" kennt
?? Doch, tut er.
sondern dass ich das setAttribute weglassen
Guter Plan. setAttribute()
bereitet im IE immer wieder Probleme. Du notierst Attribute besser als Eigenschaft des Elementobjekts:
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
und createElement('<input type="checkbox">') notieren muss.
?? Was soll das denn?
Jetzt würde ich beide Varianten gern für die jeweiligen Browser anbieten,
Nö, du würdest gen eine Variante für alle Browser anbieten. Das Problem ist hier die Reihenfolge: Erst checkbox.type = 'checkbox'
setzen, dann ins DOM hängen:
checkbox.type = 'checkbox';
formular.appendChild(checkbox);
Wobei auch das funktioniert:
checkbox.setAttribute('type', 'checkbox');
formular.appendChild(checkbox);
Qapla'
und createElement('<input type="checkbox">') notieren muss.
?? Was soll das denn?
Das habe ich hier gefunden.
Nö, du würdest gen eine Variante für alle Browser anbieten. Das Problem ist hier die Reihenfolge: Erst
checkbox.type = 'checkbox'
setzen, dann ins DOM hängen:
Es lag also nur an der Reihenfolge. Gut, dann muss ich für den IE nichts extra schreiben. Danke!
@@Sebo:
nuqneH
Das habe ich hier gefunden.
Soso, der gute alte wahsaga. ;-) Bei solchen Postings im Archiv hätte ich mich auch umbenannt. >;-> SCNR.
Da hat Micha das also her. Nun, wir können auch anders.
Qapla'
Hallo Gunnar Bittersmann,
Da hat Micha das also her. Nun, wir können auch anders.
Ja, da habe ich es her und seitdem setzte ich diesen Schnipsel immer ein, wenn Input-Elemente erzeugt werden sollen. ;-)
Im IE8 kann ich nach einem kurzen Test bestätigen, dass es unnötig zu sein scheint. Gilt das auch für ältere IEs?
Mit freundlichem Gruß
Micha
Im IE8 kann ich nach einem kurzen Test bestätigen, dass es unnötig zu sein scheint. Gilt das auch für ältere IEs?
Ja (getestet bis IE 6).
Das type-Attribut kann ganz normal gesetzt werden, bevor das input-Element eingehängt ist. Danach ist es nur lesbar.
Problematisch ist das name-Attribut. Aber auch nur insofern, dass input.name = "..." nicht dazu führt, dass das Element über die http://de.selfhtml.org/javascript/objekte/elements.htm@title=elements-Collection über dessen Namen oder ID erreichbar ist.
Will man das unbedingt, so ist die proprietäre Aufrufweise von createElement nötig:
<!DOCTYPE html>
<html><body>
<form><p id="target"></p></form>
<script>
[code lang=javascript](function () {
var input = document.createElement('input');
input.type = 'checkbox';
input.name = 'eins';
document.getElementById('target').appendChild(input);
input = document.createElement('<input type="checkbox" name="zwei">');
document.getElementById('target').appendChild(input);
alert(document.forms[0].elements.eins);
alert(document.forms[0].elements.zwei);
})();
</script>
</body></html>[/code]
Das ist seit IE 8 gefixt, betrifft also zumindest IE 6 und 7.
Credits: Struppi und JürgenB, SELFHTML Forum.
Mathias
Hallo Sebo,
Im FF und Opera funktioniert es auch ohne Fehlermeldungen. Nur der IE macht mal wieder Sorgen.
Wenn ich mich recht entsinne, besitzt das type-Attribut einen read-only Status und kann eigentlich nicht überschrieben werden. Wir haben das wie folgt gelöst:
try {
el = document.createElement(tagName);
el.type = type;
}
catch(err) {
el = document.createElement('<'+tagName+' type="'+type+'">');
}
Mit freundlichem Gruß
Micha
Hallo,
jetzt habe ich es gefunden: http://de.selfhtml.org/javascript/objekte/htmlelemente.htm#input
Mit freundlichem Gruß
Micha
try {
el = document.createElement(tagName);
el.type = type;
}
catch(err) {
el = document.createElement('<'+tagName+' type="'+type+'">');
}
Wie gesagt ist das unnötig. Für welche tagName und type ist es deiner Meinung nach nötig?
Für die Eingabewerte "input" und "checkbox" springen IE 6, 7, 8 und 9 \*nicht\* in den Catch-Block.
Mathias
Hallo molily,
Wie gesagt ist das unnötig.
Okay, dann werde ich das mal anpassen. Warum ich das Problem damals hatte, kann ich so nicht mehr nachvollziehen. Wenn ich mir diesen Beitrag so ansehe, würde ich meinen, dass ich den selben /Fehler/ gemacht habe wie Sebo. Also das Input-Element erstellt, dem Dokument hinzugefügt und *dann* erst die Attribute gesetzt. Genau sagen kann ichs Dir aber nicht mehr - dennoch Danke für Deinen Hinweis.
Mit freundlichem Gruß
Micha
[latex]Mae govannen![/latex]
try {
el = document.createElement(tagName); el.type = type;
}
catch(err) {
el = document.createElement('<'+tagName+' type="'+type+'">');
}
>
> Wie gesagt ist das unnötig. Für welche tagName und type ist es deiner Meinung nach nötig?
input / button.
Bei irgendeinem IE (ich glaube es war 6, aber frag mich nicht nach der genauen Version, bin nicht am entsprechenden Computer) ist hier letztens ein Script abgebrochen worden, weil ich ein Button-Element auf die herkömmliche Weise (wie im try-Block) erzeugt habe. Mit der „alternativen“ createElement-Schreibweise funktioniert es.
Stur lächeln und winken, Männer!
Kai
--
Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken
in Richtung "Mess up the Web".([suit](https://forum.selfhtml.org/?t=197497&m=1324775))
[SelfHTML-Forum-Stylesheet](http://selfhtml.knrs.de/#h_stylesheet)
[latex]Mae govannen![/latex]
input / button
Oder war es das button-Element? Habe gerade Zweifel.
Stur lächeln und winken, Männer!
Kai
[latex]Mae govannen![/latex]
Wie gesagt ist das unnötig. Für welche tagName und type ist es deiner Meinung nach nötig?
input / button.
Es war das button-Element.
var pfd = document.createElement('button');
pfd.type = 'button';
versagt mindestens noch im IE7, auf diesem Computer hab ich keinen IE8, kann daher nicht testetn.
Stur lächeln und winken, Männer!
Kai
@@Kai345:
nuqneH
var pfd = document.createElement('button');
pfd.type = 'button';
>
> versagt mindestens noch im IE7, auf diesem Computer hab ich keinen IE8, kann daher nicht testetn.
Versagt auch, aber
~~~javascript
var pfd = document.createElement('button');
pfd.setAttribute('type', 'button');
tut im 8er seinen Dienst (nicht im 7er).
Die Empfehlung, auf setAttribute()
zu verzichten, kann man also so allgemein doch nicht stehen lassen; manchmal ist setAttribute()
geradezu vonnöten.
BTW, auch in anderen Browsern, die 'dataset' noch nicht beherrschen:
if (foo.dataset) foo.dataset.barBaz = quz;
else foo.setAttribute('data-bar-baz', 'quz');
Qapla'
[latex]Mae govannen![/latex]
Versagt auch, aber
var pfd = document.createElement('button');
pfd.setAttribute('type', 'button');
>
> tut im 8er seinen Dienst (nicht im 7er).
>
> Die Empfehlung, auf `setAttribute()`{:.language-javascript} zu verzichten, kann man also so allgemein doch nicht stehen lassen; manchmal ist `setAttribute()`{:.language-javascript} geradezu vonnöten.
Man tauscht also die potentiellen Probleme der einen Technik gegen die der anderen Technik... da ist mir ein kleiner try-catch-Fallschirm irgendwie lieber. Ich denke mal, Clients, die \*das\* nicht verstehen, dürften inzwischen in freier Wildbahn nicht mehr anzutreffen sein.
Stur lächeln und winken, Männer!
Kai
--
Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken
in Richtung "Mess up the Web".([suit](https://forum.selfhtml.org/?t=197497&m=1324775))
[SelfHTML-Forum-Stylesheet](http://selfhtml.knrs.de/#h_stylesheet)
var pfd = document.createElement('button');
pfd.type = 'button';
>
> ~~~javascript
var pfd = document.createElement('button');
> pfd.setAttribute('type', 'button');
Danke für diese Ergänzungen. Das kann ich bestätigen.
Die Empfehlung, auf
setAttribute()
zu verzichten, kann man also so allgemein doch nicht stehen lassen; manchmal istsetAttribute()
geradezu vonnöten.BTW, auch in anderen Browsern, die 'dataset' noch nicht beherrschen:
if (foo.dataset) foo.dataset.barBaz = quz;
else foo.setAttribute('data-bar-baz', 'quz');
Wieso braucht man da notwendig setAttribute?
foo['data-bar-baz'] = 'quz'; ginge theoretisch auch, müssten die Browser auch schlucken.
Wobei eigentlich nichts dagegen spricht, in Browsern, die ohnehin nicht dataset unterstützen, die Camel-Case-Schreibweise zu verwenden. Also einfach als Alternative
foo.dataBarBaz = 'quz';
Kommt ja letztlich auf dasselbe heraus; beim Element werden Daten gespeichert. Wobei ich in diesen Browsern eher ein System einsetzen würde, wie es jQuery verwendet. Dabei wird nur ein Key am Element gespeichert und die Nutzdaten in einem von jQuery verwalteten zentralen Objekt. Das erleichtert das Aufräumen und das Verhindern von Memory-Leaks.
Mathias
Hallo molily,
Für welche tagName und type ist es deiner Meinung nach nötig?
Die Umsetzung im ganzen sieht so aus bei mlf. Besagter Code reagiert also auf INPUT und BUTTON Elemente in einer Helfer-Funktion (createInputElementWithAttributes):
document.createInputElementWithAttributes = function(tagName, att, par) {
if (tagName.toLowerCase() != "input" && tagName.toLowerCase() != "button")
return;
var type = false;
var el = false;
for (var i=0; i<att.length; i++) {
if (att[i][0].toLowerCase() == "type") {
type = att[i][1];
break;
}
}
if (type) {
try {
el = document.createElement(tagName);
el.type = type;
}
catch(err) {
el = document.createElement('<'+tagName+' type="'+type+'">');
}
}
el = el || document.createElement(tagName);
for (var i=0; i<att.length; i++) {
if (att[i][0].toLowerCase() != "type")
el[att[i][0]] = att[i][1];
}
if (par)
par.appendChild(el);
return el;
};
document.createElementWithAttributes = function(tagName, att, par) {
if (tagName.toLowerCase() == "input" || tagName.toLowerCase() == "button")
return document.createInputElementWithAttributes(tagName, att, par);
var el = document.createElement(tagName);
for (var i=0; i<att.length; i++)
el[att[i][0]] = att[i][1];
if (par) {
par.appendChild(el);
}
return el;
};
Mit freundlichem Gruß
Micha
Hallo,
Die Umsetzung im ganzen sieht so aus bei mlf. Besagter Code reagiert also auf INPUT und BUTTON Elemente in einer Helfer-Funktion (createInputElementWithAttributes)
Ok, aber was ist jetzt mit molilys Einwand, dass der catch-Block u.U. nicht zum Zug kommt?
Und wäre es statt try-catch mit
el = document.createElement(tagName);
el.type = type;
el.type === type || (el = document.createElement('<'+tagName+' type="'+type+'">');
nicht auch getan? Wahrscheinlich nicht, denn das sieht nach normaler Objekt-Erweiterung aus, so dass vielleicht der IE trotz (el.type === type) === true
die type-Eigenschaft nicht als Attribut ansieht.
Tipp: Wenn man die Attribute nicht als zweidimensionales Array sondern als Objekt übergibt, entfällt die Frickelei mit att[0][1].
Gruß, Don P
[latex]Mae govannen![/latex]
Und wäre es statt try-catch mit
el = document.createElement(tagName);
el.type = type;
el.type === type || (el = document.createElement('<'+tagName+' type="'+type+'">');
>
> nicht auch getan? Wahrscheinlich nicht, denn
... das Script bricht schon bei el.type = type; ab.
> Tipp: Wenn man die Attribute nicht als zweidimensionales Array sondern als Objekt übergibt, entfällt die Frickelei mit att[0][1].
Ack.
Stur lächeln und winken, Männer!
Kai
--
Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken
in Richtung "Mess up the Web".([suit](https://forum.selfhtml.org/?t=197497&m=1324775))
[SelfHTML-Forum-Stylesheet](http://selfhtml.knrs.de/#h_stylesheet)
Hallo,
Und wäre es statt try-catch mit
[...]
nicht auch getan? Wahrscheinlich nicht, denn... das Script bricht schon bei el.type = type; ab.
Ok, aber wenn halt trotzdem kein catch zum Zug kommen sollte, ist das suboptimal.
Umgekehrt müsste es jedenfalls klappen, z.B. geht folgendes im IE8 und auch im FF problemlos:
try { /* IE-Extrawurst */
var el = document.createElement( '<input type="checkbox">' );
}
catch(err){
el = document.createElement('input'); el.type = 'checkbox';
}
Der FF springt nämlich in den catch-block :).
Gruß, Don P
Hallo Don P,
Tipp: Wenn man die Attribute nicht als zweidimensionales Array sondern als Objekt übergibt, entfällt die Frickelei mit att[0][1].
Ich wollte kurze Aufrufe haben und finde es hier nicht *so* unübersichtlich:
document.createElementWithAttributes("a", [["class", "foo"], ["href", "#"]], null);
Trotzdem Danke für den Hinweis.
Mit freundlichem Gruß
Micha
[latex]Mae govannen![/latex]
Tipp: Wenn man die Attribute nicht als zweidimensionales Array sondern als Objekt übergibt, entfällt die Frickelei mit att[0][1].
Ich wollte kurze Aufrufe haben und finde es hier nicht *so* unübersichtlich:
document.createElementWithAttributes("a", [["class", "foo"], ["href", "#"]], null);
document.createElementWithAttributes("a", {"class": "foo", "href": "#"}, null);
ist meiner meinung nach viel übersichtlicher und in der Funktion auch leichter zu verarbeiten.
Stur lächeln und winken, Männer!
Kai
document.createElementWithAttributes("a", [["class", "foo"], ["href", "#"]], null);
document.createElementWithAttributes("a", {"class": "foo", "href": "#"}, null);
ist meiner meinung nach viel übersichtlicher und in der Funktion auch leichter zu verarbeiten.
Ja, Bibliotheken sind schon nicht dumm. Man kann von ihnen lernen, was API-Design angeht.
Mathias
Hallo Kai345,
document.createElementWithAttributes("a", {"class": "foo", "href": "#"}, null);
ist meiner meinung nach viel übersichtlicher und in der Funktion auch leichter zu verarbeiten.
Stimmt! Sieht überzeugend gut aus, muss ich sagen. Ich werde es mal im Hinterkopf behalten und bei Gelegenheit abändern. Vielen Dank.
Mit freundlichem Gruß
Micha
<snip>
Hier das Stück JS:
var formular = document.getElementById('form');
var checkbox = document.createElement('input');
formular.appendChild(checkbox);
checkbox.setAttribute('type', 'checkbox');
Erst type ändern, dann ins Dokument einfügen.
@@bonzo400:
nuqneH
Erst type ändern, dann ins Dokument einfügen.
Erst Thread lesen, dann antworten. ;-)
Qapla'