descan: Zweimal dieselbe ID, was passiert beim parsen des Browsers?

Hallo Leute,

meine Frage bezüglich ID's ist folgende:

Ich weis dass ich ID's nur einmal auf meiner Seite verwenden darf,
ich habe nur eine Verständnisfrage.

Angenommen ich habe in meinem html-Dokument eine ID zweimal verwendet.

Bsp.:

  
...  
<p id="grueneSchrift">testtext</p>  
  
<p id="grueneSchrift">testtext nummer 2</p>  
...  

und meine ID-Definition im CSS enthält nur die Farbinformation:

  
#grueneSchrift {  
 color: green;  
}  

Dann gibt mir mein Browser (obwohl ich die ID ja eigentlich nur einmal verwenden darf trotzdem beide Text in grün aus.

Greife ich nun aber per Javascript auf die ID zu und ändere den Text z.B. so:

  
function init() {  
	var textWechsel = document.getElementById("roteSchrift");  
	textWechsel.innerHTML = "Ich bin ein andere nichtssagender Satz";  
}  
  
window.onload = init;  

...so wird nur (so sollte es ja auch sein) der erste Text ersetzt und der zweite Text (testtext2) bleibt erhalten.

Nun würde mich interessieren was genau beim parsen mit den doppelt vorhandenn ID's passiert bzw. warum beide Texte grün sind und im Javascript nur der eine Text geändert wird.

Vielen Dank im Vorraus
Grüße Descan

  1. Nun würde mich interessieren was genau beim parsen mit den doppelt vorhandenn ID's passiert bzw. warum beide Texte grün sind und im Javascript nur der eine Text geändert wird.

    Das ist von Browser zu Browser verschieden.
    CSS kann es oft ja egal sein, wieviele Elemente ein Selektor matcht, da es ja keinen Rückgabewert an den CSS-Autor reichen muss.
    hier ist es nicht egal:
    selector:target{display:block;}

    Bei getElementById('#someid') oder querySelector('#someid') hast du aber einen definierten Rückgabewert, genau ein Element und keine Collection.

    Die Frage, was bei <a href="#someid"> geschieht, hast du noch gar nicht berührt.

    mfg Beat

    --
    ><o(((°>           ><o(((°>
       <°)))o><                     ><o(((°>o
    Der Valigator leibt diese Fische
  2. Hallo,

    Nun würde mich interessieren was genau beim parsen mit den doppelt vorhandenn ID's passiert bzw. warum beide Texte grün sind

    Das ist schlicht Fehlerkorrektur. #foo wird dabei als *[id="foo"] interpretiert. Und dieser Filter kann auf mehrere Elemente zutreffen.

    und im Javascript nur der eine Text geändert wird.

    Im JavaScript kann der Browser diesen Fehler nicht korrigieren – es kann nicht zweimal dasselbe DOM-Objekt existieren. getElementById muss eines von beiden zurückgeben. Operationen darauf betreffen somit nur dieses eine.

    Mathias

    1. @@molily:

      nuqneH

      #foo wird dabei als *[id="foo"] interpretiert.

      Kann man so nicht sagen. .bar und *[class="bar"] sind äquivalent; #foo und *[id="foo"] aber nicht, sie unterscheiden sich in der Spezifität.

      Qapla'

      --
      Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
      (Mark Twain)
      1. Om nah hoo pez nyeetz, Gunnar Bittersmann!

        #foo wird dabei als *[id="foo"] interpretiert.

        Faktenwissen? Vermutung?

        Kann man so nicht sagen. .bar und *[class="bar"] sind äquivalent; #foo und *[id="foo"] aber nicht, sie unterscheiden sich in der Spezifität.

        Dennoch bleibt der Fakt, dass im CSS-Kontext eine ID nicht eindeutig zu sein braucht.
        Fehlerfreies HTML ist trotzdem eine Grundvoraussetzung für wunschgemäße Darstellung.
        <behauptung>In solchen Fällen spielt die Spezifität keine Rolle und es ist fraglich, ob nicht die Spezifität erhalten bleibt.</behauptung>

        Matthias

        --
        1/z ist kein Blatt Papier.

        1. #foo wird dabei als *[id="foo"] interpretiert.

          Faktenwissen? Vermutung?

          Soll ich jetzt die Codestelle heraussuchen, oder was würdest du als Fakt gelten lassen?

          Mathias

          1. #foo wird dabei als *[id="foo"] interpretiert.

            Faktenwissen? Vermutung?

            Soll ich jetzt die Codestelle heraussuchen, oder was würdest du als Fakt gelten lassen?

            Mich würde es auch interessieren, der Teil des Browsers der die Selektorn verarbeitet und Elemente auswählt muss in irgend einer Form die ID-, Attribut- und Klassenselektoren verarbeiten.

            Ich glaube kaum, dass im Internet Explorer 6 #foo als [id='foo'] interpretiert wird oder .foo als [class~='foo'], weil der Browser ja gemeinhin bekannt gar keine Attribut-Selektoren unterstützt - und auch wenn der IE7 aufwärts bereits mit Attribut-Selektoren umgehen kann, ist es davon auszugehen, dass hier wohl noch genug Altlasten eingebaut sind und die die Attribut-Selektoren als "Eigenlösung" dazugebaut wurden.

            Natürlich: wenn man einen neuen Browser schreibt, wird man das wohl so machen (möglicherweise, denn die Spezifität ist ja auch ein Thema), aber ich bin mir nicht so sicher, ob man deine Aussage als Faustregel stehen lassen kann.

            1. Ich glaube kaum, dass im Internet Explorer 6 #foo als [id='foo'] interpretiert wird oder .foo als [class~='foo'], weil der Browser ja gemeinhin bekannt gar keine Attribut-Selektoren unterstützt

              Das hat auch niemand behauptet. Ich habe gesagt, dass ein ID-Selektor aus Gründen der Fehlertoleranz beim Matching wie ein Attributselektor umgesetzt wird. Dieser Vergleich sollte nur das illustrieren, was der OP ohnehin schon beobachtet hatte. Ich habe nicht gesagt, dass intern das Matching von #ID an die Implementierung von Attributselektoren delegiert wird. Das mag in manchen Browsern der Fall sein, wer weiß, ich habe es nicht geprüft und sehe auch keinen Grund dazu.

              aber ich bin mir nicht so sicher, ob man deine Aussage als Faustregel stehen lassen kann.

              Faustregel, häh?

              Noch einmal, ich habe keine Aussage gemacht, die sich verifizieren oder falsifizieren ließe. Das beobachtete Verhalten steht fest, ich habe es lediglich durch eine Analogie zu beschreiben versucht.

              Ich vermute, das hat der OP auch so verstanden, aber das scheint hier leider nebensächlich zu sein.

              Mathias

              1. Ich glaube kaum, dass im Internet Explorer 6 #foo als [id='foo'] interpretiert wird oder .foo als [class~='foo'], weil der Browser ja gemeinhin bekannt gar keine Attribut-Selektoren unterstützt

                Das hat auch niemand behauptet. Ich habe gesagt, dass ein ID-Selektor aus Gründen der Fehlertoleranz beim Matching wie ein Attributselektor umgesetzt wird. Dieser Vergleich sollte nur das illustrieren, was der OP ohnehin schon beobachtet hatte. Ich habe nicht gesagt, dass intern das Matching von #ID an die Implementierung von Attributselektoren delegiert wird. Das mag in manchen Browsern der Fall sein, wer weiß, ich habe es nicht geprüft und sehe auch keinen Grund dazu.

                Ich habe das so verstanden - und ich war hier scheinbar nicht der einzige :)

                aber ich bin mir nicht so sicher, ob man deine Aussage als Faustregel stehen lassen kann.

                Faustregel, häh?

                Nach der Klarstellung deinerseits ist das hinfällig.

                Noch einmal, ich habe keine Aussage gemacht, die sich verifizieren oder falsifizieren ließe. Das beobachtete Verhalten steht fest, ich habe es lediglich durch eine Analogie zu beschreiben versucht.

                Wir haben hier keinen Dialog geführt - ich hab's schon mir dem ersten absatz verstanden :)

              2. Hi,

                Ich glaube kaum, dass im Internet Explorer 6 #foo als [id='foo'] interpretiert wird oder .foo als [class~='foo'], weil der Browser ja gemeinhin bekannt gar keine Attribut-Selektoren unterstützt

                Das hat auch niemand behauptet. Ich habe gesagt, dass ein ID-Selektor aus Gründen der Fehlertoleranz beim Matching wie ein Attributselektor umgesetzt wird.

                Ich könnte mir vorstellen, daß die Ursache dafür, daß CSS bei mehreren identischen IDs die Regeln für die ID für alle diese Elemente anwendet, folgendes ist:

                Vermutung: der Browser geht für die Darstellung die Elemente durch, und guckt für jedes Element: gibt es CSS-Rulesets, deren Selektor auf dieses Element zutrifft? Wenn ja, wendet er sie an.
                Und dabei interessiert ihn in keiner Weise, ob die ID irgendwo schon mal verwendet wurde oder nicht.
                Bei Javascript per document.getElementById() dagegen sucht er im Elementbaum, bis er ein Element mit der gewünschten ID gefunden hat, und gibt dieses zurück. Weitersuchen braucht er ja nicht, darf ja kein weiteres geben - und da genau ein Element zurückgeliefert werden müßte, könnte das eh nicht zusätzlich zurückgegeben werden.

                M.a.W.: beim CSS geht der Browser vom Element aus und sucht darauf zutreffende Rulesets.

                cu,
                Andreas

                --
                Warum nennt sich Andreas hier MudGuard?
                O o ostern ...
                Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
      2. #foo wird dabei als *[id="foo"] interpretiert.

        Kann man so nicht sagen.

        Doch. Kann man schon. Wenn man die Aussage nicht dem Kontext entreißt und missversteht.

        .bar und *[class="bar"] sind äquivalent; #foo und *[id="foo"] aber nicht, sie unterscheiden sich in der Spezifität.

        Ich habe nicht behauptet, dass diese beiden Selektoren äquivalent seien. Ich habe diesen Vergleich lediglich gezogen, um das beobachtete Verhalten, das faktisch fehlertolerante Matching des ID-Selektors, zu erklären.

        Mathias

        1. @@molily:

          nuqneH

          #foo wird dabei als *[id="foo"] interpretiert.
          Kann man so nicht sagen.
          Doch. Kann man schon. Wenn man die Aussage nicht dem Kontext entreißt und missversteht.

          So, wie du die Aussage formuliert hattest, war sie missverständlich. „#foo wird dabei als *[id="foo"] interpretiert“ kann man verstehen als „#foo wird intern zu *[id="foo"] umgeschrieben und das dann weiter verarbeitet“, was eben nicht der Fall ist.

          Ich habe nicht behauptet, dass diese beiden Selektoren äquivalent seien.

          Wie gesagt, es war deine Formulierung, die ich so nicht unkommentiert stehenlassen wollte. Ich traue dir durchaus zu, den Unterschied zwischen beiden Selektoren zu kennen; aber nicht allen Mitlesern dieses Forums.

          Qapla'

          --
          Gut sein ist edel. Andere lehren, gut zu sein, ist noch edler. Und einfacher.
          (Mark Twain)