globalaaray ;-/?
bleicher
- javascript
Шалом друзі!
mal eine kurze Frage - elemente eines Documents zählt man mit y=document.getelementsbytagname('ding').lenght;
und dann kann man doch per schleife for()
mit i<y alle Elemnte dieser Art ansprechen.
leider habe ich vergessen welches array ich damit ansprechen soll :(
(an formularelemte errinere ich mich noch..aber wie ging das mit <p>s zB?)
MFG
DiV
bleicher
Hallo bleicher,
elemente eines Documents zählt man mit y=document.getelementsbytagname('ding').lenght;
nein, die Funktion heisst getElementsByTagName(), die Eigenschaft heisst length
leider habe ich vergessen welches array ich damit ansprechen soll
y
Gruß,
Dieter
Danke.
Liebe(r) Dieter,
leider habe ich vergessen welches array ich damit ansprechen soll
y
nur der Vollständigkeit halber: Ich habe erst kürzlich gelernt, dass es sich bei y nicht um ein Array, sondern um eine HTMLCollection handelt (ein anscheinend besonderes Objekt)...
Liebe Grüße aus Ellwangen,
Felix Riesterer.
Hallo ihr beiden,
nur der Vollständigkeit halber: Ich habe erst kürzlich gelernt, dass es sich bei y nicht um ein Array, sondern um eine HTMLCollection handelt (ein anscheinend besonderes Objekt)...
nein, eine Collection ist eigentlich bloß die Javascript-Entsprechung von Array oder Objekt. Die JS-Strukturen sind gewissermaßen eine Kreuzung aus dem, was andere, streng typorientierte Programmiersprachen als Array einerseits und als Objekt andererseits kennen.
Aber bei diesem Beispiel (Schreibweise korrigiert)
y=document.getElementsByTagName('ding').length;
ist y nur eine Zahl, ein 'Number', nämlich die Anzahl der Elemente in der Collection/im Array. Um effizient mit dem Zeugs umzugehen, sollte man es etwas umstellen, etwa so:
dings = document.getElementsByTagName('ding');
for (i=0; i<dings.length; i++)
{ // Operation mit dings[i]
}
Schönen Abend noch,
Martin
Hallo,
Ihr immer mit den »Collections«! ;)
nur der Vollständigkeit halber: Ich habe erst kürzlich gelernt, dass es sich bei y nicht um ein Array, sondern um eine HTMLCollection handelt (ein anscheinend besonderes Objekt)...
getElementsByTagName gibt eine Knotenliste (NodeList) zurück.
HTMLCollections sind wieder was anderes, das sind besondere Knotenlisten, bei denen die Methode namedItem() bzw. die Schreibweise collection["name"] existiert. HTMLCollections werden bei document.images, document.links, document.forms usw. verwendet.
NodeLists und HTMLCollections sollte man nicht verwechseln.
eine Collection ist eigentlich bloß die Javascript-Entsprechung von Array oder Objekt.
Äh...? Nein! Eine NodeList ist ein spezielles JavaScript-Objekt.
Die JS-Strukturen sind gewissermaßen eine Kreuzung aus dem, was andere, streng typorientierte Programmiersprachen als Array einerseits und als Objekt andererseits kennen.
Äh. Es gibt ganz normale Arrays in JavaScript. Und Arrays sind Objekte. Was hat das mit HTMLCollections zu tun?
NodeLists oder HTMLCollections sind keine normalen Arrays. Die Elemente einer NodeList/HTMLCollection lassen sich aber genauso wie die Elemente eines Arrays über ihren Index mit der []-Schreibweise ansprechen. Das ist die einzige Gemeinsamkeit. Alle drei sind listenartige Datenstrukturen.
Eigentlich gibts kein Grund zur Konfusion. ;)
Mathias
n'Abend!
Ihr immer mit den »Collections«! ;)
Ja, das ist ein guter Begriff, um das Ganze von den "richtigen" Arrays oder Objekten, wie sie in "richtigen" Programmiersprachen üblich sind, abzugrenzen.
eine Collection ist eigentlich bloß die Javascript-Entsprechung von Array oder Objekt.
Äh...? Nein! Eine NodeList ist ein spezielles JavaScript-Objekt.
Ja, eben. Nämlich eines, das weder ein reinrassiges Array ist (Komponenten gleichen Typs durch numerische Indexe adressierbar), noch ein reinrassiges Objekt (Komponenten unterschiedlichen Typs durch Namen adressierbar). Es ist eben eine Kreuzung aus beiden: Ich kann mit new Array() ein Array anlegen und ihm Felder unterschiedlichen Typs hinzufügen, ebenso kann ich ein Objekt mit new Object() erzeugen, ihm dann aber eine Reihe von Strings über einen rein numerischen Index anhängen. Die Grenzen verwischen also, es ist weder das eine, noch das andere, sondern scheint je nach Kontext zu mutieren, vereint also die Eigenschaften beider Strukturen.
Die JS-Strukturen sind gewissermaßen eine Kreuzung aus dem, was andere, streng typorientierte Programmiersprachen als Array einerseits und als Objekt andererseits kennen.
Äh. Es gibt ganz normale Arrays in JavaScript. Und Arrays sind Objekte.
Eben. Und genau das unterscheidet JS von anderen Programmiersprachen wie z.B. C oder C++.
Was hat das mit HTMLCollections zu tun?
Keine Ahnung. Den Begriff "HTMLCollections" hast du ins Spiel gebracht. Ich sprach nur von Collections und meinte damit eine heterogene Datenstruktur.
Eigentlich gibts kein Grund zur Konfusion. ;)
Genau. Vielleicht meinen wir sogar dasselbe, gehen es aber von verschiedenen Richtungen an.
Ciao,
Martin
Hallo,
Es ist eben eine Kreuzung aus beiden: Ich kann mit new Array() ein Array anlegen und ihm Felder unterschiedlichen Typs hinzufügen, ebenso kann ich ein Objekt mit new Object() erzeugen, ihm dann aber eine Reihe von Strings über einen rein numerischen Index anhängen.
Auch gewöhnliche Arrays sind Objekte. Insofern ist ein gewöhnlicher Array auch eine »Kreuzung«, weil sich ein Array wie jedes beliebige Object verhält. Dasselbe gilt für NodeList, HTMLCollection und NamedNodeMap. Das ist keine Eigenheit von den letzten drei.
Mathias
Moin,
Es ist eben eine Kreuzung aus beiden: Ich kann mit new Array() ein Array anlegen und ihm Felder unterschiedlichen Typs hinzufügen, ebenso kann ich ein Objekt mit new Object() erzeugen, ihm dann aber eine Reihe von Strings über einen rein numerischen Index anhängen.
Auch gewöhnliche Arrays sind Objekte.
ja eben, das sag' ich doch die ganze Zeit. ;-)
Aber halt nur in Javascript, während das in klassischen, etablierten Programmiersprachen meist sehr genau unterschieden wird. Sieh mal, ich bin mit Pascal, C/C++ und Assembler "groß geworden", das sind alles Sprachen mit einer sehr eindeutigen Abbildung von logischen Datenstrukturen (Namen von Datentypen) auf die physikalische Repräsentation der Daten (Anordnung im Arbeitsspeicher, Adressierung). Das ist in Javascript (IMHO leider) nicht so eindeutig, die Grenze zwischen Array und Object ist nicht klar erkennbar.
Insofern ist ein gewöhnlicher Array auch eine »Kreuzung«, weil sich ein Array wie jedes beliebige Object verhält.
Ja, so sehe ich das auch. Anscheinend ist ein Array in JS ein Object, dessen Feldnamen "zufällig" rein numerisch und fortlaufend numeriert sind.
Schönen Tag noch,
Martin
Hallo,
Ich muss nochmal Erbsen zählen. ;)
Anscheinend ist ein Array in JS ein Object, dessen Feldnamen "zufällig" rein numerisch und fortlaufend numeriert sind.
Ein Object ist eine Art ungeordneter Hash mit Name-Werte-Paaren, soweit klar.
Ein Array ist ein solches Object und stellt *zudem* eine nummerierte, geordnete Liste mit Elementen dar. Da scheint mir dein Satz missverständlich.
Ein Array hat also beide Fähigkeiten voneinander *unabhängig*. Und die eine Fähigkeit ist auch nicht über die andere umgesetzt.
Ein Array ist in zweifacher Hinsicht eine Listenstruktur, er besitzt als Object eine ungeordnete Liste mit Membern identifiziert durch Strings und als Array eine geordnete Liste mit Elementen identifiziert durch Numbers.
Array-Elemente sind keine Member (Unterobjekte) des Array-Objekts. Ändert man die Member, bleiben die Elemente unangetastet; ändert man die Elemente, bleiben die Member unangetastet.
Das heißt konkret, arr[1] = "wert" bewirkt etwas völlig anderes als arr["1"] = "wert".
Das erste erzeugt ein Array-Element mit dem Index 1, welches kein Member (Unterobjekt) von arr ist.
Das zweite erzeugt einen Member namens »1«, kein Array-Element.
Ein Array ist nicht einfach ein Object, dessen Member numerisch identifiziert werden und fortlaufend nummeriert sind. Sonst wäre das hier schon ein halber Array:
var obj = {
1 : "a",
2 : "b",
3 : "c"
};
Hier könnte ich auch auch obj[1] schreiben. »1« wäre hier aber kein numerischer Index, sondern würde in einen String umgewandelt und würde als Membername behandelt. Außerdem kann man diese Object-Struktur nicht geordnet nach Membernamen durchlaufen. Mit einer for-in-Schleife bekommt man die Member in willkürlicher Reihenfolge.
Das nur als allgemeine Ergänzung, wahrscheinlich sage ich dir nichts neues. ;)
Mathias
gruss molily,
Hallo,
Ich muss nochmal Erbsen zählen. ;)
und mir bleibt mal wieder die nachlese ((:-(
Anscheinend ist ein Array in JS ein Object, dessen Feldnamen
"zufällig" rein numerisch und fortlaufend numeriert sind.Ein Object ist eine Art ungeordneter Hash mit Name-Werte-Paaren,
soweit klar.
drueck Dich doch nicht so drum:
»Jedes JavaScript-[[Object]]-Objekt ist ein Hash. Jedes andere
von [[Object]] verschiedene JavaScript-Objekt behält diese Hash-
Funktionalität über den jeweils implementierten Datentyp hinaus.«
Ein Array ist ein solches Object und stellt *zudem* eine nummerierte,
geordnete Liste mit Elementen dar. ...
richtig.
Ein Array hat also beide Fähigkeiten voneinander *unabhängig*.
Und die eine Fähigkeit ist auch nicht über die andere umgesetzt.
korrekt.
Ein Array ist in zweifacher Hinsicht eine Listenstruktur, er besitzt
als Object eine ungeordnete Liste mit Membern identifiziert durch
Strings und als Array eine geordnete Liste mit Elementen identifiziert
durch Numbers.
... wobei die ECMAScript-spezifikation hier auf alle faelle
gesunden menschenverstand widerspiegelt, denn genau das von
Dir vermutete verhalten ...
Das heißt konkret, arr[1] = "wert" bewirkt etwas völlig anderes als
arr["1"] = "wert". Das erste erzeugt ein Array-Element mit dem Index 1,
welches kein Member (Unterobjekt) von arr ist. Das zweite erzeugt einen
Member namens »1«, kein Array-Element.
... wird ausdruecklich ausgeschlossen.
die browserhersteller haben "15.4.5.1 [[Put]] (P, V)" meinem verständnis
nach »4. If P is "length", go to step 12.« und »12. Compute ToUint32(V).«
richtig gedeutet und identisch implementiert.
bsp.:
~~~javascript (function () {
var arr = [];
arr[2] = "zwei";
alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));
arr["1"] = "eins";
arr["2"] = "doppeltgemoppelt";
alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));
alert(arr[1]===arr["1"]);
arr.length = "2"; // this is [[PUT]] as well!
alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));
arr["length"] = 4;
arr["laenge"] = arr.length;
alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));
alert(arr.laenge)
})();/*
(function () {var arr = [];arr[2] = "zwei";alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));arr["1"] = "eins";arr["2"] = "doppeltgemoppelt";alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));alert(arr[1]===arr["1"]);arr.length = "2";alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));arr["length"] = 4;arr["laenge"] = arr.length;alert((typeof arr.toSource == "function") ? (arr.toSource()) : (arr));alert(arr.laenge);})();
*/
jedes ([[String]])-member wird intern sanft zur konvertierung gedraengt.
faellt es um, wird es den numerisch indizierten elementen zugeschlagen,
bleibt es standhaft, darf es sich weiterhin im kreis der anderen objekt-
eigenschaften tummeln.
> Array-Elemente sind keine Member (Unterobjekte) des Array-Objekts. Ändert
> man die Member, bleiben die Elemente unangetastet; ändert man die Elemente,
> bleiben die Member unangetastet.
jo.
> Ein Array ist nicht einfach ein Object, dessen Member numerisch
> identifiziert werden und fortlaufend nummeriert sind. Sonst wäre
> das hier schon ein halber Array:
>
> var obj = {
> 1 : "a",
> 2 : "b",
> 3 : "c"
> };
>
> Hier könnte ich auch auch obj[1] schreiben. »1« wäre hier aber kein
> numerischer Index, sondern würde in einen String umgewandelt und würde
> als Membername behandelt. Außerdem kann man diese Object-Struktur nicht
> geordnet nach Membernamen durchlaufen. Mit einer for-in-Schleife bekommt
> man die Member in willkürlicher Reihenfolge.
>
> Das nur als allgemeine Ergänzung, wahrscheinlich sage ich dir nichts neues. ;)
man kann es nicht oft genug wiederholen.
> Mathias
so long - peterS. - pseliger@gmx.net
--
»Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - [Douglas Crockford](http://javascript.crockford.com/)
ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
Hallo,
Ich habe erst kürzlich gelernt, dass es sich bei [dem Rückgabewert von getElementsByTagName] nicht um ein Array, sondern um eine HTMLCollection handelt (ein anscheinend besonderes Objekt)...
Weder noch. ;)
Aber man fasst echte Arrays, NodeLists, HTMLCollections und NamedNodeMaps gerne vereinfachend unter dem Begriff »Array« zusammen, weil all diese Listenstrukturen ermöglichen, dass man auf deren Elemente über liste[indexnummer] zugreifen kann. Und alle kann man ähnlich durchlaufen, weil sie eine length-Eigenschaft haben.
In den restlichen Eigenschaften und Methoden bestehen allerdings keine Gemeinsamkeiten, insbesondere fehlen den unechten Arrays die typischen Array-Methoden. In den Fällen, in denen diese Unterschiede unwichtig sind, nimmt man halt den verallgemeinernden Begriff »Array« (zieht sich z.B. durch SELFHTML).
Mathias
Hallo,
... insbesondere fehlen den unechten Arrays die typischen Array-Methoden. ...
leider. Denn einigen Seiten würde ein document.getElementsByTagName("*").sort();
nicht schaden.
Gruß, Jürgen
Hallo,
Denn einigen Seiten würde ein
document.getElementsByTagName("*").sort();
nicht schaden.
Nach was würde da sortiert werden? Prototype z.B. wandelt über $A() alle NodeLists in Arrays um (und gibt ihnen damit auch alle Enumerable-Methoden). Mit einer eigenen Vergleichsfunktion kann man dann sortieren.
Mathias
Hallo molily,
wie Du dem geänderten Thema entnehmen kannst, war mein Vorschlag nicht ganz ernst gemeint. Ich habe eigentlich nur daran gedacht, dass es einigen Seiten, die aus ziemlich "krausem" HTML bestehen, nicht mehr schaden kann, wenn einfach alle Tags (direkt im Dokument, evtl. über Bookmarklet) (um)sortiert werden. Das man so etwas implementieren kann, ist mit schon klar. Mein erster Tabellensortierer hat direkt im DOM-Baum sortiert, allerdings mit eigenem Quicksort. Mit einem "alert" an der richtigen Stelle konnte ich dann dem Quicksort bei der Arbeit zusehen.
Gruß, Jürgen
Hallo,
nur der Vollständigkeit halber: Ich habe erst kürzlich gelernt, dass es sich bei y nicht um ein Array, sondern um eine HTMLCollection handelt (ein anscheinend besonderes Objekt)...
Übrigens, was Firefox angeht, hast du Recht (so bist du wahrscheinlich darauf gekommen). Dieses Verhalten ist aber strenggenommen nicht DOM-konform. Eine normale NodeList hat keine namedItem()-Methode und eigentlich weiß ich auch nicht, welchen Vorteil es hat, dass getElementsByTagName eine HTMLCollection anstatt einer NodeList zurückgibt. Man könnte so etwas machen:
document.getElementsByTagName("input").namedItem("feldname")
Aber dafür gibt es document.getElementsByName(). Ferner sucht namedItem() auch nach Elementen mit der übergebenen ID, aber dafür gibt es document.getElementById()...
Mathias
hi,
Man könnte so etwas machen:
document.getElementsByTagName("input").namedItem("feldname")
Aber dafür gibt es document.getElementsByName().
getElementsByName würde mir alles liefern, was ein name-Attribut haben kann - also bspw. auch Bilder oder (Anker-)Links.
Mit obiger Syntax könnte man (so sie denn allgemein und nicht nur browserspezifisch wäre) die Auswahl nur auf input-Elemente mit einem bestimmten Namen beschränken.
(Die Frage, ob und wann es überhaupt sinnvoll sein könnte, für Formularelemente und Bilder oder Links identische Namen zu vergeben, mal außen vor gelassen.)
Ferner sucht namedItem() auch nach Elementen mit der übergebenen ID, aber dafür gibt es document.getElementById()...
Auch hier sucht getElementById wieder "global", während namedItem() auf eine bereits "begrenzte Auswahl" angewendet werden könnte.
gruß,
wahsaga
Hallo,
document.getElementsByTagName("input").namedItem("feldname")
Mit obiger Syntax könnte man (so sie denn allgemein und nicht nur browserspezifisch wäre) die Auswahl nur auf input-Elemente mit einem bestimmten Namen beschränken.
Ja, das dachte ich mir auch - allerdings wüsste ich ebensowenig, wieso man einem Formularfeld und einem anderen Element dasselbe name-Attribut geben sollte. Will man ein Feld zuverlässig adressieren, gibt man ihm eine ID, die man z.B. für Label sowieso braucht.
Ferner sucht namedItem() auch nach Elementen mit der übergebenen ID, aber dafür gibt es document.getElementById()...
Auch hier sucht getElementById wieder "global", während namedItem() auf eine bereits "begrenzte Auswahl" angewendet werden könnte.
Naja, da es dokumentweit nur ein Element mit einer ID geben kann, sollte getElementsByTagName("tagname").namedItem("ID") immer denselben Effekt haben wie ein bloßes getElementById(), daher sehe ich in dem Fall keinen Vorteil.
Man könnte so höchstens prüfen, ob das Element mit einer bestimmten ID ein bestimmtes Element ist (wenn nicht, ergibt namedItem null). Aber das geht auch mit getElementById("ID").tagName == "gesuchterTagName".
Ich vermute, es hat irgendwelche internen Gründe, warum Firefox an dem Punkt mit einer HTMLCollection arbeitet.
Mathias
hi,
Auch hier sucht getElementById wieder "global", während namedItem() auf eine bereits "begrenzte Auswahl" angewendet werden könnte.
Naja, da es dokumentweit nur ein Element mit einer ID geben kann, sollte getElementsByTagName("tagname").namedItem("ID") immer denselben Effekt haben wie ein bloßes getElementById(), daher sehe ich in dem Fall keinen Vorteil.
Man könnte sich beispielsweise für das Element mit der ID "xy" nur dann interessieren, wenn es ein Nachfahre von einem bestimmten anderen Element ist.
gruß,
wahsaga