Kai Meder: prototype-Property verliert wert

<CODE>
Image.prototype._width  = -1;
Image.prototype._height = -1;

Image.prototype._preload = new Image();

Image.prototype._loaded = function(e) {

alert("_loaded: " + this._width + "/" + this._height);
}

Image.prototype.load = function(src) {

this.src = "/dbprakt/views/img/loading_img.gif";
 alert("load: " + this._width + "/" + this._height);

this._preload.onload = this._loaded;
 this._preload.src = src;
}

var img = elem('img', $('foo'));
img.title = 'test';
img._width = 50;
img.load('http://maps.bzzt.net/users-euro-big.jpg', 50);
</CODE>

ich setze die property _width auf 50.
in load() wird dies auch korrekt ausgegeben aber im event-handler _loaded() werden die default-werte -1/-1 ausgegeben.

kann mir da jemand weiterhelfen, kann mir das überhaupt nicht erklären. hat das was mit dem event-handling zu tun?

gruß und dank,
kai

  1. <CODE>
    [...]
    Image.prototype._loaded = function(e) {

    alert("_loaded: " + this._width + "/" + this._height);
    }
    [...]
    </CODE>

    habe die antwort selbst gefunden: _loaded ist nicht mehr an das Image gebunden, sondern an Image._preload...

    Habe das ganze jetzt so gelöst, dass ich über
    <CODE>
    this._preload.ref = this
    </CODE>
    eine referenz auf das eigtl Image-Objekt speichere.

    geht das auch edler?

    gruß und dank,
    kai

    1. <CODE>
      [...]
      Image.prototype._loaded = function(e) {

      alert("_loaded: " + this._width + "/" + this._height);
      }
      [...]
      </CODE>

      habe die antwort selbst gefunden: _loaded ist nicht mehr an das Image gebunden, sondern an Image._preload...

      Habe das ganze jetzt so gelöst, dass ich über
      <CODE>
      this._preload.ref = this
      </CODE>
      eine referenz auf das eigtl Image-Objekt speichere.

      geht das auch edler?

      gruß und dank,
      kai

      Pass nur auf, dass durch solche Verweise keinen IE Memory Leak verursachtst... was das ist, kannst du ja googlen...

      1. Pass nur auf, dass durch solche Verweise keinen IE Memory Leak verursachtst... was das ist, kannst du ja googlen...

        danke für den tip!

        das viel größere problem: ich bin einfach mal davon ausgegangen, dass mir der IE ein Image.prototype zur Verfügung stellt. dass das gar nicht der Fall ist, ist übelst...
        damit kann ich alles quasi in die tonne treten.
        gibts "irgendeine" lösung für dieses problem?

        1. das viel größere problem: ich bin einfach mal davon ausgegangen, dass mir der IE ein Image.prototype zur Verfügung stellt. dass das gar nicht der Fall ist, ist übelst...
          damit kann ich alles quasi in die tonne treten.
          gibts "irgendeine" lösung für dieses problem?

          Nein.

          Struppi.

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

          wieso denkst du dir auch so eine komplizierte Objektstruktur aus? Du erweiterst den Image-Prototyp, indem du ihm ein Image anhängst... äh, diese Rekursion ist zu hoch für mein kleines Gehirn:

          function O () {}  
          O.prototype.e = new O;  
          var o = new O;  
          alert(o.e.e.e.e.e.e.e.e.e.e.e.e.e.e.e.e.e.....);
          

          Das heißt, ich würde keinesfalls Image als Konstruktor erweitern, sondern einen eigenen bauen, z.B.:

          function VorschauBild (elem, src) {  
            var self = this;  
            this.image = elem;  
            this.preloadImage = new Image;  
            this.image.src = "loading.png";  
            this.preloadImage.src = src;  
            this.preloadImage.onload = function () {  
              self.image.src = this.src;  
            };  
          }  
            
          new VorschauBild($("bild"), "bild.png");
          

          (Jetzt mal vereinfacht.)

          Mathias

          1. function VorschauBild (elem, src) {

            var self = this;
              this.image = elem;
              this.preloadImage = new Image;
              this.image.src = "loading.png";
              this.preloadImage.src = src;
              this.preloadImage.onload = function () {
                self.image.src = this.src;
              };
            }

            new VorschauBild($("bild"), "bild.png");

              
            weil genau dieses (meines) Objekt-erweiterende Prototyping die eigentliche Stärke von  Java-Script ausmacht, imho.  
            Ein spezielles Objekt für einen Zweck coden, finde ich wesentlich weniger smart als das existierende Image einfach zu erweitern.  
            Aber werde ich jetzt wohl nicht drumrumkommen...  
              
            Danke für deinen Kommentar,  
            Kai
            
            1. Hallo,

              weil genau dieses (meines) Objekt-erweiterende Prototyping die eigentliche Stärke von  Java-Script ausmacht, imho.

              Man könnte es höchstens noch so sehen, dass hier ein »spezielles Image« vorliegt. Dann würde man einen neuen Konstruktor schaffen, der prototypisch Image bzw. HTMLImageElement beerbt. Dieses spezielle Objekt müsste man dann noch ins Dokument einhängen.

              function besonderesBild () {  
                 var self = this;  
                 this.load = function (src) {  
                    this.src = "vorschau.png";  
                    this.preloadImage = new Image;  
                    this.preloadImage.src = src + "?" + (new Date).getTime();  
                    this.preloadImage.onload = function () {  
                       self.src = this.src;  
                    };  
                 };  
              }  
              besonderesBild.prototype = document.createElement("img");  
                
              window.onload = function () {  
               var meinBild = new besonderesBild();  
               document.body.appendChild(meinBild);  
               meinBild.load("vollbild.png");  
              };
              

              Das Problem ist, dass das in der Theorie hinhaut, in der Praxis aber ebensowenig Cross-Browser umsetzbar ist.

              Man kann also alle Images prototypisch erweitern, sodass bestehende img-Elemente im Dokument bereits einen Austauschmechanismus mit Preload haben, oder ein besonderes Image erzeugen, das prototypisch erbt. Ich finde es aber genauso passend, den Bildwechsel als Prozess zu sehen, den man als Objekt darstellen kann. Der besteht dann aus zwei Images, mit denen operiert wird. So lässt sich auch die etwas seltsame Struktur »Image hat Image (hat Image ...)« vermeiden.

              Mathias

              1. Man könnte es höchstens noch so sehen, dass hier ein »spezielles Image« vorliegt. Dann würde man einen neuen Konstruktor schaffen, der prototypisch Image bzw. HTMLImageElement beerbt. Dieses spezielle Objekt müsste man dann noch ins Dokument einhängen.

                function besonderesBild () {

                var self = this;
                   this.load = function (src) {
                      this.src = "vorschau.png";
                      this.preloadImage = new Image;
                      this.preloadImage.src = src + "?" + (new Date).getTime();
                      this.preloadImage.onload = function () {
                         self.src = this.src;
                      };
                   };
                }
                besonderesBild.prototype = document.createElement("img");

                window.onload = function () {
                var meinBild = new besonderesBild();
                document.body.appendChild(meinBild);
                meinBild.load("vollbild.png");
                };

                
                >   
                > Das Problem ist, dass das in der Theorie hinhaut, in der Praxis aber ebensowenig Cross-Browser umsetzbar ist.  
                
                Warum ist dieses Beispiel nicht Cross-Browser umsetzbar? Wenn der IE keinen Image.prototype bereitstellt, ist dann der umgekehrte Weg (dein Code) á la CustomObject.prototype = Image auch verbaut?  
                  
                
                > Man kann also alle Images prototypisch erweitern, sodass bestehende img-Elemente im Dokument bereits einen Austauschmechanismus mit Preload haben, oder ein besonderes Image erzeugen, das prototypisch erbt. Ich finde es aber genauso passend, den Bildwechsel als Prozess zu sehen, den man als Objekt darstellen kann. Der besteht dann aus zwei Images, mit denen operiert wird. So lässt sich auch die etwas seltsame Struktur »Image hat Image (hat Image ...)« vermeiden.  
                
                Da hast du völlig Recht.  
                  
                Vielen Dank für die guten Anregungen und Kommentare,  
                Kai
                
                1. Hallo,

                  besonderesBild.prototype = document.createElement("img");

                  Das Problem ist, dass das in der Theorie hinhaut, in der Praxis aber ebensowenig Cross-Browser umsetzbar ist.
                  Warum ist dieses Beispiel nicht Cross-Browser umsetzbar? Wenn der IE keinen Image.prototype bereitstellt, ist dann der umgekehrte Weg (dein Code) á la CustomObject.prototype = Image auch verbaut?

                  IE unterstützt zwar allgemein die prototype-Eigenschaft und auch das Erzeugen von img-Elementobjekten, aber er erlaubt nicht, ein DOM-Elementobjekt als Prototyp zu verwenden. Beziehungsweise das geht in die Hose, weil es dann nicht mehr als Elementobjekt ins Dokument eingehängt werden kann.

                  Das liegt letztlich alles an derselben Unzulänglichkeit - DOM-Objekte sind nicht prototypisch erweiterbar im IE. Allerdings unterstützt Opera das Einfügen von erweiterten Elementobjekten auch nicht, ich wüsste nicht, wie man ihm das beibringen kann.

                  Mathias

  2. Ich kann mir nicht erklären, was du mit dem Konstrukt bezweckst.

    Einmal erweiterst du das Image Objekt um dann darin ein Imgae Objekt zu deklarieren. Für mich sieht das alles sehr verwirrend und unnötig aus.

    was hast du genau vor?

    Struppi.

    --
    Javascript ist toll (Perl auch!)
    1. ein großes bild im hintergrund laden, währenddessen ein loading.gif anzeigen. sobald das bild geladen ist, dieses anzeigen.