Enrico: Für mich nicht nachvollziehbare Meldung "... is undefined"

Hallo,

ich hänge gerade an dynamischen Bilderwechseln via JavaScript.

Über CSS kann ich es nicht umsetzen, weil ich sonst leere div-Elemente hätte und HTML-Elemente sollen ja nicht leer sein sollen/dürfen.

Ich habe in meiner HTML-Testumgebung erst mal nur eine Grafik eingebunden:

  
<img id="Home" src="../IMG/TextlinkHome0.png" width="66" height="23">  

Eine nach dem vollständigen Laden der Seite aufzuführende JavaScript-Funktion geht dann alle img-Tags durch und soll die Wechsel zuweisen:

  
var imgs = document.getElementsByTagName("img"),  
    x = 0,  
    Anzahl = imgs.length;  
  
for (; x < Anzahl; x++)  
{  
   if (!!imgs[x].id)  
   {  
      imgs[x].onmouseover = function()  
      {  
    ---> src = imgs[x].getAttribute("src"); <---  
  
         alert(src);  
  
         // x.setAttribute("src", img[x].src.replace("0", "1"));  
      }  
  
      imgs[x].onmouseout = function()  
      {  
  
      }  
   }  
}  

Ich verstehe nicht, warum die Fehlerkonsole in der gekennzeichneten Zeile "img[x] is undefined" ausgibt, irgendeine andere beliebige alert-Meldung aber problemlos anzeigt.

Wenn img[x] undefiniert wäre, dann dürfte doch gar nicht erst die bei mouseover zugewiesene Funktion aufgerufen und somit auch keine beliebige alert-Meldung anzeigt werden, oder?

Gruß,
Enrico

  1. Hallo,

    Wenn img[x] undefiniert wäre, dann dürfte doch gar nicht erst die bei mouseover zugewiesene Funktion aufgerufen und somit auch keine beliebige alert-Meldung anzeigt werden, oder?

    Ich vermute, das Problem ist, dass der Wert von x nicht der ist, den x beim Erzeugen der Mouseover-Funktion hatte, sondern der Wert beim Verlassen der Schleife (also Anzahl). Und imgs[Anzahl] ist undefiniert, das letzte Element wäre imgs[Anzahl-1].

    Du müsstest aber über "this" innerhalb der mouseover-Funktion bereits Zugriff auf das Image-Objekt haben (alert(this.src))

    Hope that helps.

    Viele Grüsse,
    Jörg

    1. Hallo Jörg,

      vielen Dank für Deine Hilfe und die Lösung meines Problems! :-)

      Komisch, dass der Wert x innerhalb der Funktion nicht mehr dem ursprünglichen Wert x entspricht, aber über "this" komme ich weiter.

      Gruß,
      Enrico

      1. Hallo,

        Komisch, dass der Wert x innerhalb der Funktion nicht mehr dem ursprünglichen Wert x entspricht

        Eigentlich nicht, denn der Wert von x wird ja sofort in der Schleife weiter gezählt, die Mouseover-Funktion wird irgendwann später ausgeführt. Aber da fall ich auch immer mal wieder rein ;)

        Wenn Dich die Details interssieren und Du des Englischen mächtig bist, guck Dir mal diesen Artikel, insbesondere "The infamous loop problem" an, dort wird ein sehr ähnliches Problem wie Deins mit entsprechender Lösung beschrieben.

        Aber ist ja gut, wenn Du's so mit this schon lösen konntest.

        Viele Grüsse,
        Jörg

      2. Hallo Enrico,

        Komisch, dass der Wert x innerhalb der Funktion nicht mehr dem ursprünglichen Wert x entspricht, aber über "this" komme ich weiter.

        Nein, denn Du befindest Dich ja in einem Callback. Der hat einen völlig anderen Kontext als die Funktion, in der er an das Event angebunden wurde, und er wird zu einem viel späteren Zeitpunkt ausgeführt (wenn das Mouseover-Event eintritt).

        Gruß
        Stefanie

  2. Hi Enrico,

    eine Gelegenheit meine Kenntnisse zu erweitern.

    du schreibst:
    if (!!imgs[x].id) -> imgs[x].getAttribute("src");

    also wenn
    img[1].id === false --> get src von img[1]
    denmnach hat zB TextlinkHome1.png keine id !?

    Kannst du mir sagen, wie das zusammenhängt, oder warum du es so machst?

    var imgs = document.getElementsByTagName("img"),
        x = 0,
        Anzahl = imgs.length;

    for (; x < Anzahl; x++)
    {
       if (!!imgs[x].id)
       {
          imgs[x].onmouseover = function()
          {
        ---> src = imgs[x].getAttribute("src"); <---

    alert(src);

    // x.setAttribute("src", img[x].src.replace("0", "1"));
          }

    imgs[x].onmouseout = function()
          {

    }
       }
    }

      
    Viele Grüße aus LA
    
    -- 
    ralphi
    
    1. Hallo,

      if (!!imgs[x].id) -> imgs[x].getAttribute("src");
      also wenn
      img[1].id === false --> get src von img[1]

      nein, gerade andersrum. Zweimal negieren ergibt wieder den Originalwert, vorausgesetzt es war von Anfang an ein Boolean.
      Und Werte, die nicht von Anfang an Boolean sind, werden erst zu einem solchen konvertiert, dann negiert, dann nochmal negiert.

      Dasselbe Ergebnis hätte man aber auch ohne die doppelte Verneinung, denn if () erwartet sowieso einen boolschen Ausdruck. Was nicht boolean ist, wird also sowieso konvertiert.

      Kannst du mir sagen, wie das zusammenhängt, oder warum du es so machst?

      In diesem Fall würde mich auch interessieren, wozu das gut sein soll.

      Ciao,
       Martin

      --
      Die letzten Worte des stotternden Beifahrers:
      Frei... frei... frei... freilich kommt da was!!
      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
      1. Hi Martin,

        if (!!imgs[x].id) -> imgs[x].getAttribute("src");
        also wenn
        img[1].id === false --> get src von img[1]

        nein, gerade andersrum. Zweimal negieren ergibt wieder den Originalwert, vorausgesetzt es war von Anfang an ein Boolean.

        also

        if (!!imgs[x].id)  
        // =  
        if (imgs[x].id != false)
        

        wieder was gelernt - danke :-)

        Viele Grüße aus LA

        --
        ralphi
  3. Hallo Enrico,

    ich hänge gerade an dynamischen Bilderwechseln via JavaScript.

    Über CSS kann ich es nicht umsetzen, weil ich sonst leere div-Elemente hätte und HTML-Elemente sollen ja nicht leer sein sollen/dürfen.

    also das verstehe ich jetzt nicht. Warum darf eine DIV-Box nicht leer sein? Warum muss denn die DIV-Box leer sein?

    Mein css-Bildwechsler für Mausdrüber und Mausklick sieht so aus:

    .bild_bild img { position:absolute; opacity:1 }  
    .bild_bild img + img { position:static; opacity:0 }  
    .bild_bild:hover img { opacity:0 }  
    .bild_bild:hover img + img { opacity:1 }  
    .bild_bild:focus img { opacity:0 }  
    .bild_bild:focus img + img { opacity:1 }  
    img { transition: opacity 2s }
    
    <figure tabindex="0" class="bild_bild">  
      <img src="Sonnenblume.jpg" alt="Sonnenblume"><img src="Sonnenblume_Mitte.jpg" alt="Sonnenblume Ausschnitt">  
      <figcaption>Sonnenblume<br><span class="kleiner">(Mouseover vergrößert die Mitte)</span></figcaption>  
    </figure>
    

    s. http://www.j-berkemeier.de/Spiralen.html

    Gruß, Jürgen

    1. Om nah hoo pez nyeetz, JürgenB!

      Folgende klugscheißerische Verbesserungsvorschläge habe ich:

      <figcaption>Sonnenblume<br><span class="kleiner">(Mouseover vergrößert die Mitte)</span>
      </figcaption>

      ~~~html
      <figcaption>Sonnenblume<small>Mouseover vergrößert die Mitte</small>  
      </figcaption>
      
      figure small { display: block; }  
      figure small::before { content: "("; }  
      figure small::after { content: ")"; }
      

      Sowie noch folgende alternative Idee, die ein Bild einspart und wegen des Zoom-Effekts bestimmt auch noch schick aussieht.

      <figure tabindex="0" class="bild_bild">
        <img src="Sonnenblume.jpg" alt="Sonnenblume"><img src="Sonnenblume_Mitte.jpg" alt="Sonnenblume Ausschnitt">
      </figure>

        
      ~~~html
      <figure tabindex="0" class="bild_bild">  
        <div><img src="Sonnenblume.jpg" alt="Sonnenblume"></div>  
      </figure>
      
      figure div {  
        position: relative;  
        height: 250px;  
        width: 250px;  
        overflow: hidden;  
      }  
      figure img {  
        position: absolute;  
        overflow: hidden;  
        height: 250px;  
        width: 250px;  
        transition: all ease 2s;  
      }  
      figure:hover img {  
        height: 750px;  
        width: 750px;  
        left: -250px;  
        top: -250px;  
      }
      

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Gast und Gastritis.

      1. Hallo Matthias,

        Folgende klugscheißerische Verbesserungsvorschläge habe ich:

        ich hab's befürchtet ...

        <figcaption>Sonnenblume<br><span class="kleiner">(Mouseover vergrößert die Mitte)</span>

        </figcaption>

        
        > ~~~html
        
        <figcaption>Sonnenblume<small>Mouseover vergrößert die Mitte</small>  
        
        > </figcaption>
        
        

        figure small { display: block; }

        figure small::before { content: "("; }
        figure small::after { content: ")"; }

          
        ohne Worte  
          
        
        >   
        > Sowie noch folgende alternative Idee, die ein Bild einspart und wegen des Zoom-Effekts bestimmt auch noch schick aussieht.  
        >   
        > > ~~~html
        
        <figure tabindex="0" class="bild_bild">  
        
        >   <img src="Sonnenblume.jpg" alt="Sonnenblume"><img src="Sonnenblume_Mitte.jpg" alt="Sonnenblume Ausschnitt">  
        > </figure>
        
        

        <figure tabindex="0" class="bild_bild">

        <div><img src="Sonnenblume.jpg" alt="Sonnenblume"></div>
        </figure>

        
        > ~~~css
        
        figure div {  
        
        >   position: relative;  
        >   height: 250px;  
        >   width: 250px;  
        >   overflow: hidden;  
        > }  
        > figure img {  
        >   position: absolute;  
        >   overflow: hidden;  
        >   height: 250px;  
        >   width: 250px;  
        >   transition: all ease 2s;  
        > }  
        > figure:hover img {  
        >   height: 750px;  
        >   width: 750px;  
        >   left: -250px;  
        >   top: -250px;  
        > }
        
        

        interessante Variante. Leider reagiert left/top nicht auf die transition, aber mit margin-left/margin-top gehs.

        Gruß, Jürgen

        1. Om nah hoo pez nyeetz, JürgenB!

          interessante Variante. Leider reagiert left/top nicht auf die transition, aber mit margin-left/margin-top gehs.

          Auch nicht, wenn sie für img explizit mit Null festgelegt werden?

          Matthias

          --
          Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Feme und Femen.

          1. Hallo Matthias,

            interessante Variante. Leider reagiert left/top nicht auf die transition, aber mit margin-left/margin-top gehs.

            Auch nicht, wenn sie für img explizit mit Null festgelegt werden?

            dann geht's. Ich hatte das bei den margins auch gemacht.

            Gruß, Jürgen