Struppi: Gültigkeit von Name/Bezeichnungen

Mich würde die Erklärung für folgendes Phänomen interessieren:

Ich hab folgendes HTML Konstrukt:

<a href="#"
onmouseover="test.src='f1.jpg';"
onmouseout="test.src='test.jpg';">Link</a>

<br>

<img src="bild1.jpg" name="test">

Das tauscht tatsächlich in allen mir zu Verfügung stehenden Browsern das Bild aus.
Ich dachte das wäre nur eine IE Eigenheit. aber na gut.
Was mich dann aber noch mehr verwunderte:

<script type="text/javascript">
test = new Object();
austausch1.src = 'xxx';
</script>

<a href="#"
onmouseover="test.src='f1.jpg';"
onmouseout="test.src='test.jpg';">
<img src="bild1.jpg" name="test">
</a>

Auch das tauscht das Bild aus.

Die Browser ersetzen also ungefragt die Variabel test durch document.images['test']

Noch merkwürdiger (bzw. es ist dann so wie ich es erwartet hätte) finde ich dann das Verhalten in diesem Fall:

<script type="text/javascript">
test = 'xxx';
</script>

<a href="bla" name="test"
onmouseover="alert(test)">link</a>

(es wird 'xxx' ausgegeben)

wie gesagt das der IE so reagiert nichts verwunderliches, aber alle anderen auch? Ist das eine Spezifikation? In welcher Reihenfolge werden die Elemente gesucht?
Ich bin immer davon ausgegangen das 'self' bzw. 'window' das erste Objekt ist.

Struppi.

  1. Lieber Struppi,

    mir scheint, dass beim Rendern der Seite die von Dir definierte Variablen "test" später durch das "name" Attribut Deines Bildes "umdefiniert" wird. Es steht ja zuerst Dein <script>-Bereich, in dem "test" als Variablen definiert wird, _danach_ aber das <img>, mit noch einem "test". Persönlich versuche ich soetwas zu vermeiden, da für mich das eine etwas unsaubere Programmierung wäre. Aber ich will Dir da weder etwas vorschreiben, noch Dich kritisieren.

    Anders kann ich mir das nicht erklären. Bin da auch kein Experte...

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

    1. mir scheint, dass beim Rendern der Seite die von Dir definierte Variablen "test" später durch das "name" Attribut Deines Bildes "umdefiniert" wird. Es steht ja zuerst Dein <script>-Bereich, in dem "test" als Variablen definiert wird, _danach_ aber das <img>, mit noch einem "test". Persönlich versuche ich soetwas zu vermeiden, da für mich das eine etwas unsaubere Programmierung wäre. Aber ich will Dir da weder etwas vorschreiben, noch Dich kritisieren.

      Ich will das gar nicht verwenden, eben weil ich es auch unsauber finde.

      Mich würde halt interessieren, wo dieses Verhalten spezifiziert ist und warum das so ist.

      Ich hab noch ein bisschen rumprobiert, das ganze passiert nur bei from und img Tags nicht bei anderen (soweit ich das probiert habe).

      Ich finde das ein sehr unspezifisches Verhalten, da es nicht so ist wie du sagst, die Variabel ist nach wie vor vorhanden (window.test) und sie wird auch verwendent, wenn kein img und form Element mit dem gleichen Namen im HTML Dokument vorkommt.

      Mhhhh???

      Struppi.

      1. Hi Struppi,

        also für mich ergibt das einen Sinn: Innerhalb eines Elements kann deine Variable einen anderen Wert haben, als ausserhalb. Bei dem <img> ist der onMouseOver innerhalb eines Ankers, ebenso wie das Bild. Damit ist für den onMouseOver "test" das, was es im Anker eben ist: Das Bild.
        Bei Formularen kann ich mir das auch vorstellen, denn da ist man innerhalb eines großen Elements, innerhalb dessen "test" anscheinend anders interpretiert wird, als außerhalb.

        Du könntest höchstens versuchen, ob eine "komplette" Referenz auf deine Variable mit getElementsByName (also angefangen bei document oder window) hier eine unterscheidung bringt...

        Diese Fragen dürften vor allem für Leute interessant sein, die fertige Scripte in ihre Seite einsetzen wollen, aber nicht besonders auf die verwendeten Variablennamen achten! Warum muss in einem Script die Variable auch immer gleich global definiert werden?? Ich habe mir angewöhnt Funktionen zu definieren, innerhalb derer Variablen mir "var xxx = ...; " definiert werden, damit sie außerhalb der Funktion nicht existieren.

        Liebe Grüße aus Ellwangen,

        Felix Riesterer.

        1. also für mich ergibt das einen Sinn: Innerhalb eines Elements kann deine Variable einen anderen Wert haben, als ausserhalb. Bei dem <img> ist der onMouseOver innerhalb eines Ankers, ebenso wie das Bild. Damit ist für den onMouseOver "test" das, was es im Anker eben ist: Das Bild.

          Das stimmt ja so nicht, das Bild kann auch ausserhalb stehen, irgendwo im Dokument.

          Du könntest höchstens versuchen, ob eine "komplette" Referenz auf deine Variable mit getElementsByName (also angefangen bei document oder window) hier eine unterscheidung bringt...

          Jaja, das geht, wie gesagt, es gibt window.test und document.images.test.
          Nur das mnchmal das eine genommen wird und wenn ein image oder form vorhanden ist das andere.

          Diese Fragen dürften vor allem für Leute interessant sein, die fertige Scripte in ihre Seite einsetzen wollen, aber nicht besonders auf die verwendeten Variablennamen achten! Warum muss in einem Script die Variable auch immer gleich global definiert werden?? Ich habe mir angewöhnt Funktionen zu definieren, innerhalb derer Variablen mir "var xxx = ...; " definiert werden, damit sie außerhalb der Funktion nicht existieren.

          Nicht das ich sehr darauf achte Variabeln lokal zu definieren.

          Aber in größeren Skripten verwendest du durchaus z.b. globale Objekte um eben z.b. in einem Event eine Ereignis auszulösen. Insofern ist der Fall nicht unwahrscheinlich, das du ein HTML Element benennst und ein JS Objekt und wenn diese zufällig den gleichen Namen haben bekommst du plötzlich ein Problem, da die übliche Schreibweise onclick="meinObj.tu_was();" nicht funktioniert (wenn z.b. ein Bild 'meinObj' heißt). Das läßt sich natürlich vermeiden, wenn man den Event per JS einfügt, da innerhalb des Skriptblocks das nicht passiert.

          Struppi.

  2. Hi,

    Ich bin immer davon ausgegangen das 'self' bzw. 'window' das erste Objekt ist.

    Ist das Unterobjekt eindeutig zu bestimmen, kann das Elternobjekt auch weggelassen werden.

    Beispiel: Üblich ist es, statt eigentlich korrekterweise window.document.location.href nur document.location.href zu schreiben. Auch location.href funktioniert. Und IIRC sogar nur href.

    Gruß, Cybaer

    --
    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
    1. Ich bin immer davon ausgegangen das 'self' bzw. 'window' das erste Objekt ist.

      Ist das Unterobjekt eindeutig zu bestimmen, kann das Elternobjekt auch weggelassen werden.

      Schon klar, aber warum ist hier auf einmal document.images oder auch document.forms das Elternobjekt aber normalerweise window?

      Struppi.

      1. Hi,

        Schon klar, aber warum ist hier auf einmal document.images oder auch document.forms das Elternobjekt aber normalerweise window?

        "Normalerweise" ist halt nur "wenn eindeutig", oder? ;-)

        Ich meine, wenn ich z.B. mehrere Images gleichen Namens habe, ersetzt der Browser dann "normalerweise" bei einem Rollover für diesen Namen die erste Grafik mit diesem Namen, die letzte, alle oder keine?

        Gruß, Cybaer

        PS: Anwort: Je nach Browser die erste oder die letzte Grafik.

        --
        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
        1. Schon klar, aber warum ist hier auf einmal document.images oder auch document.forms das Elternobjekt aber normalerweise window?

          "Normalerweise" ist halt nur "wenn eindeutig", oder? ;-)

          Normalerweise wird in JS Eventhandler automatisch das window Objekt als Eleternobjekt eingesetzt. Sobald im HTML Dokument aber ein Formular oder ein Bild mit dem Namen exsitiert wird statt window document.images oder document.forms als Elternobjekt ersetzt. Bzw eine Liste erzeugt.

          Ich meine, wenn ich z.B. mehrere Images gleichen Namens habe, ersetzt der Browser dann "normalerweise" bei einem Rollover für diesen Namen die erste Grafik mit diesem Namen, die letzte, alle oder keine?

          das ist ja eine ganz andere Frage. Im window. Objekt werden alle anderen Obnjekte überschrieben, es existiert nur das letzte.

          Aber es ist nicht so wie du schreibst:
          <form name="test"><input type="checkbox" onclick="checkBox(this);"></form>
          <img  name="test" src="test.jpg">
          <img  name="test" src="test.jpg">

          <br>
          <a href="#" onmouseover="alert(test)" >link</a>

          test ist eine Liste in diesem Falle mit der Länge drei und die Eigenschaft src ist undefiniert.

          Nach wie vor ist das Verhalten für mich nicht erklärlich und widerspricht dem was ich bisher gedacht habe.

          Struppi.

          1. Hi,

            test ist eine Liste in diesem Falle mit der Länge drei und die Eigenschaft src ist undefiniert.

            Na ja logisch. Daß du dann eine collection bekommst, muß wohl nicht extra erwähnt werden - oder doch?

            Laß die beiden Images, dann hast Du eine Liste von 2. Ersetze hiervon den ersten Eintrag, dann ändern die meisten Browser das erste Bild, manche aber das letzte.

            Jedenfalls war mir das vor grauer Urzeit mal aufgefallen ... :-)

            Gruß, Cybaer

            --
            Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
            1. test ist eine Liste in diesem Falle mit der Länge drei und die Eigenschaft src ist undefiniert.

              Na ja logisch. Daß du dann eine collection bekommst, muß wohl nicht extra erwähnt werden - oder doch?

              Also nochmal:

              Fall 1:
              --------------------------------
              <script>
              test = 'xxx';
              </script>

              <img onmouseover="alert(test);">

              Ausgabe: 'xxx'

              Fall 2:
              --------------------------------
              <script>
              test = 'xxx';
              </script>

              <img name="test">
              <img onmouseover="alert(test);">

              Ausgabe: HTML ImageElement

              Fall 3:
              --------------------------------
              <script>
              test = 'xxx';
              </script>

              <div name="test"><Div>

              <img onmouseover="alert(test);">

              Ausgabe: xxx

              Gibt es dafür eine Erklärung oder Spezifikation?

              Laß die beiden Images, dann hast Du eine Liste von 2. Ersetze hiervon den ersten Eintrag, dann ändern die meisten Browser das erste Bild, manche aber das letzte.

              Wie schon erwähnt, ich will das nicht so machen, sondern ich will nur eine Erklärung haben.

              Das Problem ist nicht, das ich nicht weiß wie ich die Elemente ansprechen kann, sondern, dass es a.) unerklärlich ist und b.) u.U. laufenden Skripte massiv stören kann, wenn plötzlich der Wert, den man vermeindlich im eventhandler anspricht nicht mehr der ist den man erwartet.

              Struppi.

              1. Hi,

                <script>
                test = 'xxx';
                </script>
                <div name="test"><Div>

                div hat kein name-Attribut.
                Es gibt auch keine collection document.divs.
                Beides zusammen dürfte dafür sorgen, daß das div nicht dazwischenfunkt.
                Je nach Browser würde mit getElementsByName auch das div nicht gefunden.

                cu,
                Andreas

                --
                Warum nennt sich Andreas hier MudGuard?
                Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
                1. Hi,

                  Full ACK.

                  Mindestens Opera (IIRC sogar als einziger der üblichen Browser) verhält sich hier korrekt. Die anderen hingegen ... ;-}

                  Gruß, Cybaer

                  --
                  Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                2. <script>
                  test = 'xxx';
                  </script>
                  <div name="test"><Div>

                  div hat kein name-Attribut.
                  Es gibt auch keine collection document.divs.
                  Beides zusammen dürfte dafür sorgen, daß das div nicht dazwischenfunkt.
                  Je nach Browser würde mit getElementsByName auch das div nicht gefunden.

                  OK, schlechtes Beispiel, aber:

                  script>
                  test = 'xxx';
                  </script>
                  <a href="#" name="test">test</A>

                  <a href="#" onclick="alert(test);">test</A>

                  Gibt wieder 'xxx' und eine Linkcollection gibt es.

                  Also, keine Erklärung und keine Spezifikation?
                  Sondern purer Zufall?

                  Struppi.

                  1. Hi,

                    Gibt wieder 'xxx'

                    Ja und? Das ist doch korrekt.

                    window.test hat halt Vorrang vor beispielsweise window.document.test.

                    Also nochmal: JavaScript erlaubt daß Weglassen der Hierarchie, wenn das Objekt eindeutig ist (auch wenn das per se als unsaubere Programmierung gilt). Daß es bei mehreren "test" zu für den Programmierer unerwünschten Effekten kommt, wenn man die Hierarchie dann einfach wegläßt, ist doch selbstverständlich. Welches "test" im Zweifel "gewinnt", dürfte *mindestens bei Objekten die parallel angesiedelt sind*, eine Sache des Browserprogrammierers sein.

                    Gruß, Cybaer

                    --
                    Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                    1. Gibt wieder 'xxx'

                      Ja und? Das ist doch korrekt.

                      window.test hat halt Vorrang vor beispielsweise window.document.test.

                      Dann erklär mir bitte, warum hat document.images oder document.forms Vorrang vor window. Warum hat document.links nicht vorrang vor window? Warum werden aber document.forms und document.images gleich behandelt (es wird ja eine Liste erzeugt, wo beide Elemente vorkommen)?

                      Also nochmal: JavaScript erlaubt daß Weglassen der Hierarchie, wenn das Objekt eindeutig ist (auch wenn das per se als unsaubere Programmierung gilt). Daß es bei mehreren "test" zu für den Programmierer unerwünschten Effekten kommt, wenn man die Hierarchie dann einfach wegläßt, ist doch selbstverständlich. Welches "test" im Zweifel "gewinnt", dürfte *mindestens bei Objekten die parallel angesiedelt sind*, eine Sache des Browserprogrammierers sein.

                      Nochmal es existieren:

                      window.test
                      window.document.images.test
                      window.document.forms.test
                      window.document.links.test

                      Welches hat im Eventhandler Vorrang?

                      Nach den erkenntnissen die ich durch ausprobieren gefunden habe:
                      window.document.images.test | window.document.forms.test
                      window.test
                      window.document.links.test

                      Das hat keine Logik und ich finde keine Spezifikation wo das erklärt ist. Es hat auch nichts mit "parallel" zu tun. Im Falle von window gibt es das sowieso nicht, da dort das letzte alle vorherigen überschreibt.

                      Im Prinzip geht es darum, in welcher Reihenfolge durchsucht die JS Engine die Objekte innerhalb HTML Eventhandler? Und wieso erzeugt sie aus verschiedenen Collections eine einzige Liste? Und wieso bevorzugt sie manche Collections gegenüber anderen?

                      Struppi.

                      1. Hi,

                        Dann erklär mir bitte, warum hat document.images oder document.forms Vorrang vor window.

                        Das kann ich nicht. Ich schrieb ja, daß das Sache des Browserprogrammierers sein dürfte. Wenn *Du* nicht eindeutig bist, verläßt Du dich halt auf *andere*. Und deren "Rangvorstellungen" sind nachweislich von Browser zu Browser unterschiedlich.

                        window.test
                        window.document.images.test
                        window.document.forms.test
                        window.document.links.test
                        Welches hat im Eventhandler Vorrang?

                        Den, den Du angibst. Gibst Du keinen an, dann den, den der Browserprogrammierer meint es könnte schon treffen. Oder vieleicht auch nur der, der zuerst in einer switch...case abgearbeitet wird. ;-) Oder ...

                        Das hat keine Logik und ich finde keine Spezifikation wo das erklärt ist.

                        Da wird es IMHO keine geben. Das Weglassen der Hierarchie und welches Objekt dann "gewinnt" ist AFAIK nirgendwo definiert. Jedenfalls ist mir in 10 Jahren JS und JS-Dokus nie so etwas über die Füße gelaufen (und ich denke, hier wären bereits die Anfänge von JS gefragt - ist ja Basisverhalten).

                        Im Prinzip geht es darum, in welcher Reihenfolge durchsucht die JS Engine die Objekte innerhalb HTML Eventhandler? Und wieso erzeugt sie aus verschiedenen Collections eine einzige Liste? Und wieso bevorzugt sie manche Collections gegenüber anderen?

                        Warum ersetzen (manche) Browser Images einer Collection von "unten", warum (die meisten) von "oben". Mehr als

                        a) weil es der Programmierer so gemacht hat und
                        b) vermeide einfach unsauberen Code

                        wird es dazu IMHO nicht zu sagen geben. ;-)

                        Gruß, Cybaer

                        --
                        Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!
                        1. Dann erklär mir bitte, warum hat document.images oder document.forms Vorrang vor window.

                          Das kann ich nicht. Ich schrieb ja, daß das Sache des Browserprogrammierers sein dürfte. Wenn *Du* nicht eindeutig bist, verläßt Du dich halt auf *andere*. Und deren "Rangvorstellungen" sind nachweislich von Browser zu Browser unterschiedlich.

                          Soweit ich das jetzt getestet habe ist die Reihenfolge in allen Browsern gleich.

                          window.document.images.test und window.document.forms.test werden gleich gehandelt und evtl. als Collection bzw. NodeList ausgegeben.
                          Existieren diese beiden nicht kommt: window.test zum Zuge
                          und ist diese nicht vorhanden window.document.links.test

                          Das ist (ich hab jetzt nicht alles 100% getestet) im IE 4, IE 6, NC 4.75, FF 1.0, OP 7.11 so. Insofern scheint mir da was dahinter zu stecken.

                          b) vermeide einfach unsauberen Code

                          Naja, das bedeutet anscheinend das du jede globale Variabel bzw. selbstdefiniertes Objekt in HTML Handlern mit window.name ansprechen solltest. Hab ich bisher noch nie so gemacht, aber offensichtlich hatte ich bisher Glück das es meistens gut ging (wenn nicht war mir zumindest bis jetzt nicht klar woran es lag)

                          Struppi.

                          1. Hi,

                            Insofern scheint mir da was dahinter zu stecken.

                            Ich würde da nicht soviel hineininterpretieren! :-)

                            Oder neigst Du zu Verschwörungstheorien? Dann frag doch einfach mal SIE?! ;-))

                            Naja, das bedeutet anscheinend das du jede globale Variabel bzw. selbstdefiniertes Objekt in HTML Handlern mit window.name ansprechen solltest.

                            Und window.document.images etc. ;)

                            <faulmodus>OK, letztlich wohl doch nur Vermeidung von problematischen Dateinamen.</faulmodus> ;)

                            Gruß, Cybaer

                            --
                            Hinweis an Fragesteller: Fremde haben ihre Freizeit geopfert, um Dir zu helfen. Helfe Du auch im Archiv Suchenden: Beende deinen Thread mit einem "Hat geholfen" oder "Hat nicht geholfen"!