Ratlos: For Schleife zählt merkwürdig

Hallo Selfhtml community,

ich arbeite seit einigen Wochen als Programmierer und muss mich in die Welt von Html und Javascript einlesen. Bei einer meiner Aufgaben kam nun ein Problem, an welchem ich verzweifle.

Ich rufe in einem Javascript bereich eine Funktion auf, mit welcher eine Tabelle erzeugt wird. Unter der Tabelle befindet sich eine weitere Tabelle, welche aus einem Textfeld und einem Button besteht. Die Zahl die dort eingetragen wird soll nur die Zeile mit der gleichen Zahl stehen lassen und den Rest der restlichen Tabelle bis auf den Header löschen. Ich gehe dies mit meiner Funktion "Loeschen()" durch, innerhalb dieser Funktion verwende ich folgende "For"-Schleife.

  
  
function Loeschen()  
		{  
			var bestehen = document.Form1.Auswahl.value;  
			var h;  
			var zeilen = document.getElementById('Tabelle1').getElementsByTagName('tr');  
			//alert(zeilen.length);  
			//console.debug(zeilen.length);  
			var wert;  
			for (h = 1; h < zeilen.length; h=h+1)  
			{  
				//alert(zeilen[h].id);  
				wert = zeilen[h].id;	  
				//console.debug(zeilen[h]);  
				//alert("Wert: " + wert);		  
				//alert("Bestehen: " + bestehen);  
				//alert("Zähler: " + h);  
				//alert("Ergebnis: " + (wert != bestehen));  
				//if (wert != bestehen)  
				{  
					alert("Entfernen" + h);  
					document.getElementById(h).parentNode.removeChild(document.getElementById(h));  
					  
				}  
			}	  
		}  

Das merkwürdige an der Schleife ist jedoch, dass sie ungleichmäßig die Zeilen löscht, obwohl wenn man den "document.getElement" Bereich am Ende als Kommentar einfügt die Schleife richtig zählt. Hoffe ihr habt mein Problem verstanden.

MfG

  1. hi,

    mach dir zum testen eine einfache tabelle. teste nur das, was dir probleme bereitet. dann kann man auch nachvollziehen, wo die lücken in deinem löschvorgang sind. lass alle kommentare weg. guck mal, ob es nicht eine alternative zu removeChild gibt.

    ansonsten würde ich h += 1 schreiben, und mich vielleicht auch mal mit den good parts von javascript bei douglas crockford vertraut machen (ggfs. sogar jslint), wenn du das als beruf weiter machst ...;

    mfg

    tami

    1. hi,

      guck mal, ob es nicht eine alternative zu removeChild gibt.

      gibts nicht: http://stackoverflow.com/questions/3387427/javascript-remove-element-by-id

      kann man aber schöner schreiben (würde ich meinen):

        
      var element = document.getElementById("element-id");  
      element.parentNode.removeChild(element);  
      
      

      auch zu empfehlen: http://molily.de/js/

      mfg

      tami

    2. hi,

      mach dir zum testen eine einfache tabelle. teste nur das, was dir probleme bereitet. dann kann man auch nachvollziehen, wo die lücken in deinem löschvorgang sind. lass alle kommentare weg. guck mal, ob es nicht eine alternative zu removeChild gibt.

      ansonsten würde ich h += 1 schreiben, und mich vielleicht auch mal mit den good parts von javascript bei douglas crockford vertraut machen (ggfs. sogar jslint), wenn du das als beruf weiter machst ...;

      mfg

      tami

      Hey,

      danke für die schnelle Antwort, jedoch habe ich besagtes schon versucht und bin immer noch nicht weiter gekommen.. Das merkwürdige an der Sache ist, das die Schleife alles perfekt durchzählt, solange der "Löschvorgang" deaktiviert ist, so wird z.b. von 1-20 durchgezählt und solange kein Wert in dem Textfeld eingegeben wurde der Wert: Entfernen + h für jede Zeile wiedergegeben. Sobald ich einen Wert in besagtes Textfeld einfüge, wird dieser Wert mit dem alert(zeilen[h].id) zwar benannt wird jedoch nicht im nächsten alert zum löschen wiedergegeben. Das heißt bis dahin zählt meine Schleife ++h richtig. Nachdem ich jedoch removechild wieder aktiviere zählt meine Schleife teilweise in h+=2 schritten und hört teilweise bei unbestimmten Werten(je nach Größe der Ausgangstabelle) auf.

  2. Hi,

    löschen von Elementen auf einem Array, dass man gerade iteriert, sollte man immer rückwärts machen.

    Grüße

    • Steffen
    1. Hi,

      löschen von Elementen auf einem Array, dass man gerade iteriert, sollte man immer rückwärts machen.

      Ich finde es eigentlich intuitiver einfach solange das erste Element zu löschen, bis keins mehr drin ist. Was ist das pro/contra der beiden Lösungen?

      1. Hi,

        löschen von Elementen auf einem Array, dass man gerade iteriert, sollte man immer rückwärts machen.

        Ich finde es eigentlich intuitiver einfach solange das erste Element zu löschen, bis keins mehr drin ist. Was ist das pro/contra der beiden Lösungen?

        kommt darauf an, was Du willst.

        Du löscht alle Elemente; Ratlos/ich wollte nicht alle, sondern nur selektiv löschen.

        Grüße

        • Steffen
      2. Ich finde es eigentlich intuitiver einfach solange das erste Element zu löschen, bis keins mehr drin ist. Was ist das pro/contra der beiden Lösungen?

        Boah da hab ich jetzt ne Weile überlegt :-)
        Bei einem Array in Javascript stimmt das. Aber C, die Derivate davon und andere Sprachen kennen Arrays als ein festes Konstrukt aus dem man nichts löschen kann.
        Ich würds so formulieren, eine Liste die beim Löschen kürzer wird, sollte man von hinten löschen.

        Immer das erste Element löschen hätte bei einer Liste den Effekt dass die Liste bei jedem löschen alle verbleibenden Elemente eins nach vorne rücken muss.

  3. Hi,

    Das merkwürdige an der Schleife ist jedoch, dass sie ungleichmäßig die Zeilen löscht, obwohl wenn man den "document.getElement" Bereich am Ende als Kommentar einfügt die Schleife richtig zählt.

    Das liegt daran, dass NodeLists (das, was du von z.B. getElementsByTagName zurück bekommst) „live“ sind, d.h. immer den aktuellen Zustand des DOM wiederspiegeln.

    Wenn du also die erste Zeile löschst, „rücken“ die anderen nach – die zweite Zeile wird zur ersten, die dritte zur zweiten, etc.
    Im nächsten Durchlauf löschst du die zweite Zeile – und die ursprünglich dritte, die original zweite, bleibt also unberührt – etc. pp.

    Einfache Lösung: Die Elemente nicht vorwärts, sondern rückwärts durchlaufen – von length - 1 bis 0. Denn wenn am Ende der NodeList ein Element wegfällt, macht das für den nächsten Durchlauf, in dem der Schleifenzähler um eins verringert wurde, keinen Unterschied.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hi,

      Einfache Lösung: Die Elemente nicht vorwärts, sondern rückwärts durchlaufen – von length - 1 bis 0. Denn wenn am Ende der NodeList ein Element wegfällt, macht das für den nächsten Durchlauf, in dem der Schleifenzähler um eins verringert wurde, keinen Unterschied.

      MfG ChrisB

      Hey,

      Vielen Dank für deine hilfreiche Antwort. :) Habe soweit das Problem verstanden, jedoch bin ich bis jetzt Schleifen immer nur "vorwärts" durchgegangen, könntest du mir den Code der Schleife möglicherweise zeigen?

      MfG

      Ratlos

      1. Hey,

        Vielen Dank für deine hilfreiche Antwort. :) Habe soweit das Problem verstanden, jedoch bin ich bis jetzt Schleifen immer nur "vorwärts" durchgegangen, könntest du mir den Code der Schleife möglicherweise zeigen?

        MfG

        Ratlos

        Hat sich bereits erledigt. Danke trotzdem & schönen Tag.

        MfG

        Rat

        1. Om nah hoo pez nyeetz, Ratlos!

          Bitte zitiere nicht das komplette Vorposting, sondern nur den Teil, auf den du dich in deiner Antwort konkret beziehst.

          Dieses Forum lässt sich so konfigurieren, dass man den gesamten Thread in einem Rutsch lesen kann. Da stören solche Vollzitate nur.

          Matthias

          --
          Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Rat und Ratatouille.

      2. Hi,

        könntest du mir den Code der Schleife möglicherweise zeigen?

        while(array.length > 0)  
          removeElement
        

        Schöne Grüße
        Micha