Spoon: Array wird automatisch verändert

Hi,

ich ermittle mittels JS alle Links (A-Tags) einer Seite und möchte vor jedem Link einen neu erstellten darstellen. So sieht das derzeit aus:

  
  var links = content.document.getElementsByTagName("a");  
  var linksNum = links.length;  
  
  for (var i=0; i<linksNum; i++) {  
   var newA = content.document.createElement("a");  
   newA.href = "http://domain.tld";  
   newA.target = "_blank";  
  
   newA.appendChild(newImg);  
  
   links[i].parentNode.insertBefore(newA, links[i]);  
  }

Dadurch, dass ich in jedem Schleifendurchgang einen neuen Link generiere, verändert sich merkwürdigerweise das Array "links", obwohl dieser Variable nie ein neuer Wert zugewiesen wird. Irgendwie aktualisiert es sich von selbst?! o0

Dadurch kann ich zB im Schleifenkopf nicht links.length verwenden, da dieser Wert variabel ist und eine Endlosschleife verursachen würde.

Auf jedenfall baut er jetzt alle neuen Links hintereinander, da der neu hinzugefügte Link sich komischerweise im links-Array befindet.

Wie bekomme ich ein Array der Links hin, welches nicht meine neu hinzugefügten beinhaltet?

Gruss
Spoons

  1. Hi,

    var links = content.document.getElementsByTagName("a");

    Dadurch, dass ich in jedem Schleifendurchgang einen neuen Link generiere, verändert sich merkwürdigerweise das Array "links", obwohl dieser Variable nie ein neuer Wert zugewiesen wird. Irgendwie aktualisiert es sich von selbst?! o0

    Natuerlich - dein links ist lediglich eine Referenz auf die NodeList, die getElementsByTagName liefert. Und eine grundlegende Eigenschaft von NodeLists, bzw. eine elementare Anforderung an diese, ist nun mal, dass sie den DOM-Zustand "live" wiedergeben.
    (Eine NodeList ist auch kein Array - sie hat lediglich einige gaengige Methoden mit diesem gemein.)

    Dadurch kann ich zB im Schleifenkopf nicht links.length verwenden, da dieser Wert variabel ist und eine Endlosschleife verursachen würde.

    Du koenntest ja bspw., wenn du gerade einen neuen Link erstellt und vor dem aktuellen eingefuegt hast, den Schleifenzaehler selber um eins hochzaehlen.

    Auf jedenfall baut er jetzt alle neuen Links hintereinander, da der neu hinzugefügte Link sich komischerweise im links-Array befindet.

    Nicht komischer-, sondern absolutermussgenausosein-weise.

    Wie bekomme ich ein Array der Links hin, welches nicht meine neu hinzugefügten beinhaltet?

    Das brauchst du eigentlich nicht, wenn du's halbwegs geschickt angehst.
    Sonst muesstest du dir wirklich erst die Referenzen auf die einzelnen Linkelemente selbst als Elemente eines eigenen, "richtigen" Arrays hinterlegen. Umstaendlich ...

    MfG ChrisB

    --
    "The Internet: Technological marvel of marvels - but if you don't know *what* you're lookin' for on the Internet, it is nothing but a time-sucking vortex from hell."
  2. Hallo Spoon,

    habe mir Deinen Quellcode nur kurz angeschaut.

    Meine Vermutung:
    content.document.getElementsByTagName("a")
    übergibt nur eine Referenz, und wird bei jedem Zugriff aktuell ausgewertet.

    Mögliche Lösung wäre, Deine alten und neuen Knoten so zu markieren, daß Du sie unterscheiden kannst. Zum Beispiel, indem Du keine A-Knoten einfügst, sondern irgendetwas anderes, was nicht in Deinem Dokument vorkommt, und nach Ende des Einfügens die irgendwas-anderes-Knoten umwandelst in A-Knoten.

    Viel Glück!
    RK

  3. Hi,

    ich ermittle mittels JS alle Links (A-Tags) einer Seite und möchte vor jedem Link einen neu erstellten darstellen. So sieht das derzeit aus:

    var links = content.document.getElementsByTagName("a");

    Gib dem Array einen anderen Namen.
    Im window-Objekt wird automatisch eine Collection mit allen Links des Dokuments angelegt, und die trägt den Namen "links".

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
  4. gruss Spoons,

    ich ermittle mittels JS alle Links (A-Tags) einer Seite und
    möchte vor jedem Link einen neu erstellten darstellen.
    So sieht das derzeit aus:

    ...[code/]

    Dadurch, dass ich in jedem Schleifendurchgang einen neuen
    Link generiere, verändert sich merkwürdigerweise das Array
    "links", obwohl dieser Variable nie ein neuer Wert zugewiesen
    wird. Irgendwie aktualisiert es sich von selbst?!

    Du verwendest eine getter-methode des DOM, die laut spezifikation
    eine sogenannte »live [NodeList]« zurueckliefern soll.

    geckos machen da, glaube ich, zweimal was falsch; sie geben vor,
    eine [HTMLCollection] zurueckzuliefern, die ja nicht *lebendig*
    sein soll, sich dort aber trotzdem so verhaelt.

    »molily« (Mathias Schaefer) wird Dir dazu bestimmt erschoepfender
    und korrekt auskunft geben, wenn er in diesm thread aufschlaegt.

    wenn Du wirklich nur an links interessiert bist, dann probier
    doch mal das verhalten der [HTMLCollection] »document.links« aus.

    falls diese sich in geckos ebenfalls nicht handhaben laesst, dann
    musst Du deine [HTMLCollection] bzw. [NodeList] explizit in ein
    array ueberfuehren ...

    Wie bekomme ich ein Array der Links hin, welches nicht meine
    neu hinzugefügten beinhaltet?

    ... ungefaehr so - code:

    var list;  
    list = Array.filter(document.links, (function () {return true;}));  
    list = Array.filter(document.getElementsByTagName("a", (function () {return true;}));
    

    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
    ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
    1. geckos machen da, glaube ich, zweimal was falsch; sie geben vor,
      eine [HTMLCollection] zurueckzuliefern, die ja nicht *lebendig*
      sein soll, sich dort aber trotzdem so verhaelt.

      Nein, nur einmal. Richtig ist, statt einer NodeList wird eine HTMLCollection zurückgegeben, Letztere ist aber ebenfalls laut Standard "lebendig".

      --
      Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
      Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
      1. n'abend Timo,

        Nein, nur einmal. Richtig ist, statt einer NodeList wird eine
        HTMLCollection zurückgegeben, Letztere ist aber ebenfalls laut
        Standard "lebendig".

        jo, stimmt, jetzt wo ich's gerade nochmal nachlese ...
        dann bleibt nur die schon beispielhaft aufgezeigte
        ueberfuehrung in ein [Array]-objekt.

        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
        ie:( fl:) br:> va:( ls:& fo:) rl:) n3;} n4:} ss:} de:µ js:} mo:? zu:]
        1. jo, stimmt, jetzt wo ich's gerade nochmal nachlese ...
          dann bleibt nur die schon beispielhaft aufgezeigte
          ueberfuehrung in ein [Array]-objekt.

          Nein, siehe Vorschlag von ChrisB. Nach Erstellen des Links den Zähler noch einmal erhöhen. i++ ist nicht in Stein gemeißelt und muss auch nicht der einzige Code sein, der i manipuliert.

          --
          Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
          Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|