/ (BROWSER) name- und id-Werte-Konflikt im IE
Felix Riesterer
- javascript
Liebe Spezialisten,
bei der Arbeit an meinem Artikel bin ich auf diese Seite gestoßen, die folgenden Bug im IE beschreibt:
Hat man zwei verschiedene HTML-Elemente, von denen das eine ein name-Attribut (z.B. name="wert") und ein anderes ein ID-Attribut mit jeweils demselben Inhalt hat (also id="wert"), dann liefert document.getElementById("wert")
nicht unbedingt wie gewünscht das Element mit der passenden ID, sondern fälschlicherweise das HTML-Element mit einem passenden Wert im name-Attribut, das im Dokument an vorausgehender Stelle notiert ist.
Gibt es dazu sichere Workarounds? Bleibt nur der Hinweis darauf, dass man tunlichst sowohl name-, als auch ID-Attribute mit dokumentweit einmaligen Werten versieht, ja am besten auf das name-Attribut zugunsten des id-Attributes komplett verzichtet?
Liebe Grüße,
Felix Riesterer.
Mahlzeit Felix Riesterer,
Bleibt nur der Hinweis darauf, dass man tunlichst sowohl name-, als auch ID-Attribute mit dokumentweit einmaligen Werten versieht, ja am besten auf das name-Attribut zugunsten des id-Attributes komplett verzichtet?
Ersteres ja. Letzteres würde ich nicht tun - AFAIK funktionieren Formular dann nicht mehr ... oder wird dann etwas alternativ der Wert aus dem "id"-Attribut genommen? Ich denke nicht ...
MfG,
EKKi
Lieber EKKi,
Bleibt nur der Hinweis darauf, dass man tunlichst sowohl name-, als auch ID-Attribute mit dokumentweit einmaligen Werten versieht
|
Ersteres ja.
OK. Dann formuliere ich um:
, ja am besten
Am besten ist es, man vergibt immer name- und ID-Attribut zusammen an ein HTML-Element, wobei bei Formularfeldern mit der ID sorgsamer umgegangen werden muss, da manche Formularfelder (Radio-Buttons oder Checkboxen) manchmal gemeinsam ein identisches name-Attribut brauchen, die aber dann keinesfalls alle auch ein identisches ID-Attribut gemeinsam haben dürfen.
Kommt das jetzt so hin?
Liebe Grüße,
Felix Riesterer.
Mahlzeit Felix Riesterer,
Kommt das jetzt so hin?
Perfekt ... genauso mache ich es auch. ;-)
MfG,
EKKi
Liebe Spezialisten,
Hat man zwei verschiedene HTML-Elemente, von denen das eine ein name-Attribut (z.B. name="wert") und ein anderes ein ID-Attribut mit jeweils demselben Inhalt hat (also id="wert"), dann liefertdocument.getElementById("wert")
nicht unbedingt wie gewünscht das Element mit der passenden ID, sondern fälschlicherweise das HTML-Element mit einem passenden Wert im name-Attribut, das im Dokument an vorausgehender Stelle notiert ist.
Tatsache. Hatte wohl noch nie den Fall, ist ja interessant konnte es gerade mal reproduzieren.
Anscheinend nimmt er aber immer das erste im Dokument auftauchende. Sprich, hat man z.B.
<input type="text" id="Wert" value="Wertrichtig">
<input type="text" name="Wert" value="Wertfalsch">
macht er es richtig, aber bei
<input type="text" name="Wert" value="Wertfalsch">
<input type="text" id="Wert" value="Wertrichtig">
schnappt er sich den falschen.
Bestimmt nur ein Feature vom IE ;) damit die alten Hasen die immer nur name verwenden auch mit dem getElementById arbeiten können.
Hahaha
gruss Felix,
Hat man zwei verschiedene HTML - Elemente, von denen das eine ein
name-Attribut (z.B. name="wert") und ein anderes ein ID-Attribut
mit jeweils demselben Inhalt hat (also id="wert"), dann liefert
document.getElementById("wert")
nicht unbedingt wie gewünscht das
Element mit der passenden ID, sondern fälschlicherweise das HTML-
Element mit einem passenden Wert im name-Attribut, das im Dokument
an vorausgehender Stelle notiert ist.
Gibt es dazu sichere Workarounds? ...
keine ahnung, man koennte sich aber einen ebensolchen bauen.
wie ueblich der hinweis auf die [http://jconsole.com], in die
der folgende code zur machbarkeitdemonstration hineinkopiert
und ausgefuehrt werden sollte:
// [Array.generics.iterators.accessors] - [http://www.pseliger.de/jsExtendedApi/jsApi.Array.mozGenerics.dev.js] september 23-2006:
Array.filter = function (obj, fct) {var arr=[];if(typeof fct=="function"){var i,l=(((obj instanceof Array)||((typeof obj.length=="number")&&((typeof obj.item=="function")||(typeof obj.item=="object")||(typeof obj.item=="string")||(obj instanceof window.NodeList)||(obj instanceof window.HTMLCollection))))?(obj.length):(obj.length||0));for(i=0;i<l;++i){if(fct.call(null,(obj[i]||obj.item(i)),i,obj)){arr.push(obj[i]||obj.item(i));}}}return arr;};
(function () {
var sh = (window || this); // sh : scripting host.
var dc = sh.document; // dc : document.
//var LNL = dc.getElementsByTagName("*"); // create a *live node list*.
//print("LNL.length : " + LNL.length);
//sh.HTMLCollection = (((typeof sh.HTMLCollection != "function") && ((typeof sh.HTMLCollection != "object") || !sh.HTMLCollection))?( { } ):(sh.HTMLCollection));
sh.NodeList = (((typeof sh.NodeList!="function")&&((typeof sh.NodeList!="object")||!sh.NodeList))?({}):(sh.NodeList));
sh.Node = (((typeof sh.Node!="function")&&((typeof sh.Node!="object")||!sh.Node))?({}):(sh.Node));
dc.getElementById = (function (coreFctById) {
return (function (str) {
str = String(str);
//return coreFctById(str);
//print("LNL.length : " + LNL.length);
//return Array.filter((LNL || document.getElementsByTagName("*")), (function (elm) {
return Array.filter(document.getElementsByTagName("*"), (function (elm) {
return (elm && (typeof elm.id == "string") && (elm.id == str));
}))[0];
});
})(dc.getElementById);
delete sh;
delete dc;
delete arguments.callee;
})();
print("document.getElementById : " + document.getElementById);
var myElm = document.getElementById("output");
print("myElm.id : " + myElm.id);
viel erfolg - peterS. - pseliger@gmx.net
hallo again in die runde, ...
... wobei mir gerade einfaellt, dass wenn alle browser mit der referenzierung
und der lebenserhaltung der LNL(live node list) zurechtkommen, im naechst-
folgenden schritt ueberprueft werden muss, ob sich das ergebnis dann nicht
auch direkt mit LNL[str] abgreifen laesst - wenn dem so waere, sparte man
sich auch gleich noch den ganzen filterprozess und koennte einfach so im
vorbeigehen vielleicht sogar ein im vergleich zum im DOM implementierten
schnelleres [getElementById] geschrieben haben. dafuer muesste man aber
noch 'nen performance-test hinterherschieben.
so long - peterS. - pseliger@gmx.net
hallo ich schon wieder ...
das nun viel schlanker daherkommende aber eben noch
zu testende baby sieht dann folgendermassen aus:
(function () {
var LNL = document.getElementsByTagName("*");
document.getElementById = (function (coreFctById) {
return (function (str) {
return LNL[String(str)];
});
})(document.getElementById);
})();
print("document.getElementById : " + document.getElementById);
var myElm = document.getElementById("output");
print("myElm.id : " + myElm.id);
so ... bitte uebernehmen .. ich bin erstmal weg.
so long - peterS. - pseliger@gmx.net
Hallo,
return LNL[String(str)];
Das läuft m.W. auf namedItem hinaus. Aber macht namedItem nicht genau das, was man nicht will, nämlich nach name- und id-Attribut suchen? Oder habe ich hier die Intention missverstanden?
Mathias
hallo Mathias,
return LNL[String(str)];
Das läuft m.W. auf namedItem hinaus. Aber macht namedItem nicht genau das,
was man nicht will, nämlich nach name- und id-Attribut suchen? Oder habe
ich hier die Intention missverstanden?
nein, Du hast die dahintersteckende Absicht voll erkannt. aber weil ich die
spezifikationen nun mal nicht auswendig dahersagen kann und auch nicht die
lust hatte, die zeit zum nachlesen aufzubringen, wollte ich das testing dem
OP oder anderen ueberlassen und schrieb daher auch zwei postings zuvor:
... wobei mir gerade einfaellt, dass wenn alle browser mit der
referenzierung und der lebenserhaltung der LNL(live node list)
zurechtkommen, im naechstfolgenden schritt ueberprueft werden
muss, ob sich das ergebnis dann nicht auch direkt mit LNL[str]
abgreifen laesst ...
so long - peterS. - pseliger@gmx.net
gruss Mathias,
> > return LNL[String(str)];
Das läuft m.W. auf namedItem hinaus. Aber macht namedItem nicht genau das,
was man nicht will, nämlich nach name- und id-Attribut suchen? Oder habe
ich hier die Intention missverstanden?
ich hab's jetzt mal getestet - die bequem gedachte abkuerzung ueber
»return LNL[String(str)];
« entspricht tatsaechlich »namedItem
« und
entfaellt damit als loesung. es bleibt aber immer noch der zuerst
vorgestellte patch ueber »Array.filter
«.
so long - peterS. - pseliger@gmx.net