Harlequin: getElementsByAttribute()

Hi,

ich stehe gerade vor einem Problem...

ich muss auf meiner Seite mehrere Inputfelder bearbeiten. Das problem ist, wie greife ich am besten darauf zu? getElementsByTagName liefert mir alle Inputfelder, das sind aber zuviele (ich brauche nur bestimmte), getElementsById lässt keine Wildcards zu und ein getElementsByAttribute existiert (leider) nicht, dabei wäre das class-Attribut ideal geeignet.

Bsp:

<input name="Bem_DR_29_ZR_4_" id="Bem_DR_29_ZR_4_" type="text" class="Bemerkungsfeld_einzeilig" onBlur="checkChanged('Bem_DR_29_ZR_4_');" />

Der Anfang von ID "Bem_" ist immer gleich und wäre eine Möglichkeit der Identifizierung. Auch class identifiziert die gesuchten Felder eindeutig. Leider gibt es kein umschließendes Tag das nur die gesuchten Felder enthält, womit sich getElementsByTagname nicht entsrechend einschränken lässt.

Gibt es noch eine andere Möglichkeit, als sich entweder alle IDs (oder zumindest die grenzen der Zähler) in einem Array zu merken und das ganze über eine Schleife und getElementById zu lösen? Bei mehreren hundert Feldern ist das nicht gerade schnell (zumindest im IE).

Gruß,

Harlequin

  1. Hallo Harlequin.

    Gibt es noch eine andere Möglichkeit, als sich entweder alle IDs (oder zumindest die grenzen der Zähler) in einem Array zu merken und das ganze über eine Schleife und getElementById zu lösen?

    Suchst du so etwas?

    Einen schönen Donnerstag noch.

    Gruß, Ashura

    --
    sh:( fo:} ch:? rl:( br: n4:~ ie:{ mo:| va:) de:> zu:} fl:( ss:) ls:[ js:|
    „It is required that HTML be a common language between all platforms. This implies no device-specific markup, or anything which requires control over fonts or colors, for example. This is in keeping with the SGML ideal.“
    [HTML Design Constraints: Logical Markup]
    1. Hallo Harlequin.

      Gibt es noch eine andere Möglichkeit, als sich entweder alle IDs (oder zumindest die grenzen der Zähler) in einem Array zu merken und das ganze über eine Schleife und getElementById zu lösen?

      Suchst du so etwas?

      Hm... statt nur über die gesuchten Elemente zu laufen und diese dabei einzeln zu holen lieber alle Elemente holen und dann die einzelnen raussuchen... ob das wirklich schneller ist? Obwohl, kombiniert mit einem GetElementsByTagName("input") um zumindest etwas einzuschränken könnte es vieleicht sogar besser sein, bleibt auszuprobieren. Ich werds mal versuchen und Morgen bescheid geben.

      Gruß,

      Harlequin

      1. Hi,

        Hm... statt nur über die gesuchten Elemente zu laufen und diese dabei einzeln zu holen lieber alle Elemente holen und dann die einzelnen raussuchen... ob das wirklich schneller ist? Obwohl, kombiniert mit einem GetElementsByTagName("input") um zumindest etwas einzuschränken könnte es vieleicht sogar besser sein, bleibt auszuprobieren. Ich werds mal versuchen und Morgen bescheid geben.

        Erster Test mit getElementsByTag name und Filter über den ID Anfang:

        Firefox: 741ms

        IE6: 26207ms

        ich werd Morgen mal meine erste Idee (array mit IDs) ausprobieren...

        Gruß,

        Harlequin

  2. Hi,

    nach verschiedenen Versuchen hat sich jetzt die Ausnutzung der Dokument-Struktur als schnellste Lösung erwiesen. Da das ganze in eine Tabelle verpackt ist kann ich über table.rows[x].cells[y].childNodes[z] auf die Inputfelder zugreifen.

    IE und Firefox: etwas über 300ms.

    Dies nur als Hinweis für Andere die auf ein ähnliches Problem stoßen.

    Gruß,

    Harlequin

    1. nach verschiedenen Versuchen hat sich jetzt die Ausnutzung der Dokument-Struktur als schnellste Lösung erwiesen. Da das ganze in eine Tabelle verpackt ist kann ich über table.rows[x].cells[y].childNodes[z] auf die Inputfelder zugreifen.

      Wenn es dir nur um Inputfelder geht, hast du auch mal document.forms[..].elements[...] probiert?
      sollte noch schneller gehen.

      Struppi.

      --
      Javascript ist toll (Perl auch!)
      1. Hi,

        Wenn es dir nur um Inputfelder geht, hast du auch mal document.forms[..].elements[...] probiert?
        sollte noch schneller gehen.

        Das Problem ist, dass es auch in den anderen Tabellenzellen Inputfelder gibt, die aber in dem Moment nicht interessieren. Ich müsste dann meine Schleife mit einem Offset starten und um die Anzahl der Felder in einer Zeile erhöhen. Der Zugriff müsste dann pro Durchlauf mittels Zähler und Zähler+2 stattfinden. Klar, wäre so machbar aber die Lösung wäre extrem schlecht durchschaubar und sehr empfindlich auf Änderungen im Dokumentaufbau. Der Geschwindigkeitsgewinn dürfte auch nciht all zu groß ausfallen, da ich mir keine Schleifendurchläufe spare sondern nur Zugriffe auf Elementarrays wie z.B. colls[x].

        Gruß,

        Harlequin

        1. Wenn es dir nur um Inputfelder geht, hast du auch mal document.forms[..].elements[...] probiert?
          sollte noch schneller gehen.

          Das Problem ist, dass es auch in den anderen Tabellenzellen Inputfelder gibt, die aber in dem Moment nicht interessieren. Ich müsste dann meine Schleife mit einem Offset starten und um die Anzahl der Felder in einer Zeile erhöhen. Der Zugriff müsste dann pro Durchlauf mittels Zähler und Zähler+2 stattfinden. Klar, wäre so machbar aber die Lösung wäre extrem schlecht durchschaubar und sehr empfindlich auf Änderungen im Dokumentaufbau. Der Geschwindigkeitsgewinn dürfte auch nciht all zu groß ausfallen, da ich mir keine Schleifendurchläufe spare sondern nur Zugriffe auf Elementarrays wie z.B. colls[x].

          gut das du's probiert hast.

          Da ich deinen Aufbau der Seite nicht kenne, kann ich dir auch kein Beispiel bauen.

          Struppi.

          --
          Javascript ist toll (Perl auch!)
          1. Hi,

            gut das du's probiert hast.

            Hm, ich habs nicht ausprobiert, weil meine jetzige Lösung schon ausreichend schnell ist und ich für das Letzte bischen Speed nicht die Lesbarkeit des Codes opfern will.

            Da ich deinen Aufbau der Seite nicht kenne, kann ich dir auch kein Beispiel bauen.

            Ich habe eine Tabelle mit mehreren hundert Zeilen, die pro Zeile 10 Inputfelder enthält. Davon muss ich das 7. und das 9. bearbeiten. Außerdem befinden sich vor und nach der Tabelle weiter Inputfelder.

            Gruß,

            Harlequin

            1. gut das du's probiert hast.

              Hm, ich habs nicht ausprobiert, weil meine jetzige Lösung schon ausreichend schnell ist und ich für das Letzte bischen Speed nicht die Lesbarkeit des Codes opfern will.

              Naja, der Unterschied in der Lesbarkeit zwischen getElementsBy.... und document.formular.elements dürfte minimal sein.

              Da ich deinen Aufbau der Seite nicht kenne, kann ich dir auch kein Beispiel bauen.

              Ich habe eine Tabelle mit mehreren hundert Zeilen, die pro Zeile 10 Inputfelder enthält. Davon muss ich das 7. und das 9. bearbeiten. Außerdem befinden sich vor und nach der Tabelle weiter Inputfelder.

              Wenn das mit den Spalten immer so ist, dann könnte deine Lösung besser sein, da du mit elements durch das komlette Formular suchen musst. Du hättest halt keine Probleme falls du jemals die Tabelle ändern willst, da, wenn ich dich richtig verstanden habe, die Eigenschaften des Formularfeldes entscheidend sind.

              Struppi.

              --
              Javascript ist toll (Perl auch!)
              1. Hi,

                Naja, der Unterschied in der Lesbarkeit zwischen getElementsBy.... und document.formular.elements dürfte minimal sein.

                Hier reden wir scheinbar irgendwie aneinander vorbei. Die Zuletzt vorgestellte Lösung benutzt kein getElementsBy mehr. Ich benutze stattdessen tabelle.rows[x].cells[y].childNodes[z] wobei die Variablen einfach zu beschreiben sind:

                x läuft über alle Zeilen
                y = 8, die Spalte mit den betreffenden Feldern
                z = 0 oder 2, die 2 gesuchten Inputs
                (das meinte ich mit dem lesbaren Code)

                Die Werte ändern sich nur wenn Spalten vor der 8. eingefügt werden oder in der 8. Spalte neue Felder vor den gesuchten hinzukommen.

                Gruß,

                Harlequin

                1. Naja, der Unterschied in der Lesbarkeit zwischen getElementsBy.... und document.formular.elements dürfte minimal sein.

                  Hier reden wir scheinbar irgendwie aneinander vorbei. Die Zuletzt vorgestellte Lösung benutzt kein getElementsBy mehr. Ich benutze stattdessen tabelle.rows[x].cells[y].childNodes[z] wobei die Variablen einfach zu beschreiben sind:

                  Woher kommen die Arrays rows und cells? Woher kommt tabelle?

                  x läuft über alle Zeilen
                  y = 8, die Spalte mit den betreffenden Feldern
                  z = 0 oder 2, die 2 gesuchten Inputs
                  (das meinte ich mit dem lesbaren Code)

                  Die Werte ändern sich nur wenn Spalten vor der 8. eingefügt werden oder in der 8. Spalte neue Felder vor den gesuchten hinzukommen.

                  Schon klar, du hattest aber in deinem Ausgangsposting einen anderen Ansatz, der mit flexibler erscheint, da es mit diesem Ansatz unwichtig wäre, an welchem Ort im DOM Baum die Felder sind. so musst du immer sicher sein, dass da nichts dazwischen kommt und childNodes bezieht sich nicht ausschliesslich auf inputs.

                  Struppi.

                  --
                  Javascript ist toll (Perl auch!)
                  1. Hi,

                    Woher kommen die Arrays rows und cells? Woher kommt tabelle?

                    Die Tabelle bekomm ich mit einem einmaligen getElementById. Rows ist ein Attribut der Tabelle und Cells ein Attribut der Tabellenzeil, diese existieren also automatisch.

                    Schon klar, du hattest aber in deinem Ausgangsposting einen anderen Ansatz, der mit flexibler erscheint, da es mit diesem Ansatz unwichtig wäre, an welchem Ort im DOM Baum die Felder sind. so musst du immer sicher sein, dass da nichts dazwischen kommt und childNodes bezieht sich nicht ausschliesslich auf inputs.

                    Flexibler: ja, aber auch extrem langsam im IE. Ob ich jetzt über forms.elements... oder getElementsByTagName("input") das Array erstelle ist egal, das langsame ist das durchsuchen nach den IDs oder Klassen (der getElements Aufruf beötigt im IE 10ms). Die einzige schnelle Lösung wäre wieder die Position im DOM auszunutzen und feste Sprünge im Array zu machen, aber dann verliere ich noch mehr Flexibilität als mit der Rows/Cells Lösung.

                    Und ja, mir ist klar, dass ChildNodes sich nicht nur auf die Inputs bezieht. Am Index 1 steht z.B. ein <Span>.

                    Gruß,

                    Harleqin

                    1. Woher kommen die Arrays rows und cells? Woher kommt tabelle?

                      Die Tabelle bekomm ich mit einem einmaligen getElementById. Rows ist ein Attribut der Tabelle und Cells ein Attribut der Tabellenzeil, diese existieren also automatisch.

                      Als Arrays? In jedem Browser?
                      Ich dachte es wären Funktionen?
                      Ich werd mal in der Dokumentation schauen, mein alter Browser hier schmiert auf der Mozillaseite ab.

                      Und ja, mir ist klar, dass ChildNodes sich nicht nur auf die Inputs bezieht. Am Index 1 steht z.B. ein <Span>.

                      Auch Leerzeichen und Zeilenumbrüche erzeugen im Firefox einen Knoten

                      Struppi.

                      --
                      Javascript ist toll (Perl auch!)
                      1. Hi,

                        Als Arrays? In jedem Browser?
                        Ich dachte es wären Funktionen?
                        Ich werd mal in der Dokumentation schauen, mein alter Browser hier schmiert auf der Mozillaseite ab.

                        Für table.Rows siehe SELFHTML.

                        Das gleiche natürlich für die <tr> mit Cells.

                        Und ja, mir ist klar, dass ChildNodes sich nicht nur auf die Inputs bezieht. Am Index 1 steht z.B. ein <Span>.

                        Auch Leerzeichen und Zeilenumbrüche erzeugen im Firefox einen Knoten

                        Hier hab ich das Glück, dass mir .NET keine Whitespaces zwischen den Elementen erzeugt.

                        Gruß,

                        Harlequin