twb: document.getElementsByTagName zeigt sich renitent

Liebe alle - einmal mehr bin ich als DOM-Dummie auf Euer versammeltes Fachwissen angewiesen. Das Problem ist folgendes: Mein Skript, das ein in DHTML gehaltenes Sudoku (URL s.o.) antreibt, ist unschön, weil es nach jeder Zifferneingabe oder Mausklick über
document.getElementById("Id").innerHTML=var;
das gesamte innerHTML neu aufbaut. Das funktioniert zwar, ist aber unelegant und ineffizient. Also möchte ich neu nur noch die Elemente neu aufbauen, die im Fall einer Zifferneingabe auch wirklich geändert werden. Die Eingabefunktion (die auch die Art der Eingabe - Ziffer, Buchstabe, "" - prüft) sieht so aus:

function enter(b)
{
a=document.forms[0].elements[b].value;
if (a>0&&a<10)
{
td[b]="<input type="text" autocomplete="off" id="form"+color[0]+"" size="1" maxLength="1" value=""+a+"" onkeyup="javascript:enter("+b+");">";
num[b]=a;
message="Number entered.";
}
else if (a=="")
{
td[b]="<input type="text" autocomplete="off" id="form"+color[0]+"" size="1" maxLength="1" value="" onkeyup="javascript:enter("+b+");">";
num[b]=a;
message="Number cleared.";
}
else
{
td[b]="<input type="text" autocomplete="off" id="form"+color[0]+"" size="1" maxLength="1" value="" onkeyup="javascript:enter("+b+");">";
num[b]="";
message="Only numbers 1-9 allowed!";
}
document.getElementsByTagName("td")[b].firstChild.data=td[b];
document.getElementById("msg").firstChild.data=message;
}

(Nur zum Verständnis - td ist der Array mit den Tabellenzelleninhalten, num der Array mit den Zahlenwerten.)

Alles funktioniert bestens,
document.getElementById("msg").firstChild.data=message;
erneuert mir auch zuverlässig die Statuszeile unterhalb des Spiels. Nur
document.getElementsByTagName("td")[b].firstChild.data=td[b];
tut nicht, was es sollte - die Tabellenzelle mit der Indexnummer b wird nicht neu aufgebaut, obwohl die Variable b sauber übergeben wird. Was mach' ich falsch?

Herzlich, Thomas

  1. hi,

    document.getElementsByTagName("td")[b].firstChild.data=td[b];
    tut nicht, was es sollte - die Tabellenzelle mit der Indexnummer b wird nicht neu aufgebaut, obwohl die Variable b sauber übergeben wird. Was mach' ich falsch?

    Sagt dir die Javascript-Konsole deines Browsers, dass du etwas falsch machst?
    Was ergibt eine Kontrollausgabe von
    document.getElementsByTagName("td")[b].firstChild.data und von
    document.getElementsByTagName("td")[b].firstChild
    ?

    Wie ist überhaupt dein HTML aufgebaut, liegt unter der TD direkt ein firstChild mit einer data-Eigenschaft, die sich derart ändern liesse (also ein Textknoten)?

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. hi,

      Hallo!

      Sagt dir die Javascript-Konsole deines Browsers, dass du etwas falsch machst?

      Nein. Der IE ist stumm wie ein Fisch, und der die JS-Konsole des FF bleibt jungfräulich weiss.

      Was ergibt eine Kontrollausgabe von
      document.getElementsByTagName("td")[b].firstChild.data und von

      <input type="text" autocomplete="off" id="form0" size="1" maxLength="1" value="3" onkeyup="javascript:enter(40);"> (bei Zifferneingabe 3 in td Index 40, also genau die HTML-Sequenz, die ich brauche)

      document.getElementsByTagName("td")[b].firstChild

      [object HTMLInputElement]

      Hilft das was?

      1. document.getElementsByTagName("td")[b].firstChild

        [object HTMLInputElement]

        Das hat keine data Eigenschaft.

        Struppi.

        --
        Javascript ist toll (Perl auch!)
      2. hi,

        Was ergibt eine Kontrollausgabe von
        document.getElementsByTagName("td")[b].firstChild.data

        SELFHTML zu .data:
        "Speichert Zeichendaten eines Knotens, sofern es sich um einen Textknoten handelt."

        <input type="text" autocomplete="off" id="form0" size="1" maxLength="1" value="3" onkeyup="javascript:enter(40);"> (bei Zifferneingabe 3 in td Index 40, also genau die HTML-Sequenz, die ich brauche)

        Das ist doch wohl kein Textknoten?

        [object HTMLInputElement]

        Nein, ganz offensichtlich ist es keiner.

        Du willst also nicht den Textinhalt eines Textknotens ändern - was _willst_ du ändern?
        Vielleicht den Inhalt der value-Eigenschaft dieses Inputfeldes?

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Das ist doch wohl kein Textknoten?

          Nein, unverkennbar nicht. Was ich bräuchte, ist eine vollständige HTML-Sequenz, die einen neuen Input erzeugt.

          value-Eigenschaft dieses Inputfeldes?
          Nein, der value ist bereits in den num-Array gewandert.

          Statt wie bis anhin mittels
          document.getElementById("Id").innerHTML=var;
          jedesmal die gesamte Anzeige neu darstellen zu lassen, suche ich nach einer eleganteren Möglichkeit, nur die betreffende Tabellenzelle bzw. den betreffenden Input zu erneuern. Bin ich vollkommen auf dem Holzweg?

          1. Hallo twb,

            ...nur die betreffende Tabellenzelle bzw. den betreffenden Input zu erneuern.

            wäre das ein Ansatz:

            <input type="text" value="x" onchange="alert(this.value)">

            statt alert kannst du auch eine Funktion aufrufen die den Wert Speichert, prüft oder einfärbt. Siehe z.B. Mein Sudoku.

            Gruß, Jürgen

            1. Hallo Jürgen

              statt alert kannst du auch eine Funktion aufrufen die den Wert Speichert, prüft oder einfärbt.

              Nun, Schweizer sind bekannt für ihre freundeidgenössischen Kompromisse. Ich sehe, dass Struppi natürlich recht hat, doch will ich mir das Leben nicht unnötig schwer machen. Daher werden nun in meinem Sudoku Änderungen nur eines Textinhalts via

              document.getElementById("Id").firstChild.data=var;

              angezeigt, was natürlich viel effizienter ist. Nur noch wenn ich die Eingabefarbe wechsle und alle noch nicht ausgefüllten Felder eine HTML-Frischzellenkur benötigen, dann wird die Tabelle ein zweites Mal neu aufgebaut, mittels

              document.getElementById("Id").innerHTML=var;

              Auf diese Weise wird nur noch HTML in die Seite geschaufelt, wenn es nötig ist. Trotzdem vielen Dank! Herzlich, Thomas

          2. document.getElementById("Id").innerHTML=var;
            jedesmal die gesamte Anzeige neu darstellen zu lassen, suche ich nach einer eleganteren Möglichkeit, nur die betreffende Tabellenzelle bzw. den betreffenden Input zu erneuern. Bin ich vollkommen auf dem Holzweg?

            Ja, wieso willst du unbedingt jedesmal den HTML Code ändern. Du kannst prima über DOM Funktionen sowohl den Inhalt, als auch z.b. die Sichtbarkeit usw. ändern. Soweit ich das sehe, musst du doch nicht dauernd HTML Code in die Seite neu einfügen, das reicht einmal am Anang und da schon solttest du document.createElement verwenden.

            Struppi.

            --
            Javascript ist toll (Perl auch!)
            1. Hallo Struppi

              Ja, richtig. In meinem Sudoku werden neu blosse Textänderungen (Statuszeile) nur noch via DOM geändert. innerHTML-Frischzellenkur erhalten die Tabellenzellen lediglich noch einmal bei Klick auf "Color" zwecks Wechsels der Eingabefarbe. Dein Posting hat mich drauf gebracht, dass ich wieder mal um die Ecke gedacht habe. Ein so recht schweizerisches Merciviumau. :-) Thomas