Michael Brendel: Imageverwaltung unter Mozilla

Folgendes Problem:
-------------------
Ich möchte mittels JavaScript zur Laufzeit den verfügbaren Platz im Browser für ein Bild berrechnen und mir dann ein Bild mittels eines Servlet in eben dieser Grösse ausgeben lassen. Die Anwendung soll es erlauben, den verfügbaren Platz zur Laufzeit zu verändern (ausblenden von NavigationsLeiste, etc.)

Folgender Code funktionier dabei bestens unter den aktuellen Browsern IE und Opera, aber leider nicht unter Mozilla.

JavaScript-Funktion:
--------------------
...
function appendWindowSizeOnURL(url) {
  url=url +
      "?width="+document.getElementById("imageHolder").offsetWidth+
      "&height="+document.getElementById("imageHolder").offsetHeight;
  document.getElementById("image").setAttribute("src", url);
  return;
}
...

Aufruf im HTML:
--------------------
...
<td align="center" id="imageHolder" width="100%">
  <img src="javascript:appendWindowSizeOnURL('ImageServlet');" id="image" width="100%" />
</td>
...

Nach dem Ausführen des Scripts sieht das Image-Element etwa so aus: <img src="ImageServlet?width=800&height=460" id="image" width="100%" />

Das Servlet macht nun nichts weiter, als das Bild auf eben jene Werte zu skalieren und als Quelle bereitzustellen.
Das eigentliche Problem liegt nun darin, dass Mozilla das Bild nach einem Klick auf einen Link, der die verfügbare Grösse verändert und somit den Reload des Bildes mit den neuen Parametern erfordert, nicht mehr anzeigt. Es gibt aber weder eine Fehlermeldung vom Browser (Bild nicht gefunden) oder vom Javascript. Es wird auch gar nicht erst die Funktion appendWindowSizeOnURL(url) aufgerufen.
Erst ein Druck auf die F5-Taste bzw. ein manueller Reload der Seite lösen das Problem. Allerdings ist diese Massnahme nicht erwünscht.

Ich hoffe, dass mein Problem Verstanden wurde und mir jemand bei diesem kniffligen Fall weiterhelfen kann.

MfG
Michael Brendel

  1. Hi

    Folgendes Problem:

    Ich möchte mittels JavaScript zur Laufzeit den verfügbaren Platz im Browser für ein Bild berrechnen und mir dann ein Bild mittels eines Servlet in eben dieser Grösse ausgeben lassen.

    wann genau soll dies passieren?

    document.getElementById("image").setAttribute("src", url);

    ich hätte es so gemacht:
    document.getElementById("image").src = url;

    <img src="javascript:appendWindowSizeOnURL('ImageServlet');" id="image" width="100%" />

    Ein javascript-Label im src-Attribut? Scheint mir zweifelhaft.

    Das eigentliche Problem liegt nun darin, dass Mozilla das Bild nach einem Klick auf einen Link,

    aha, vielleicht solltest du das JS besser in diesen Link tun bzw. per Eventhandler aufrufen?

    Gruß
    Wurf

    1. Danke erstmal für deine Vorschläge

      Hi

      Folgendes Problem:

      Ich möchte mittels JavaScript zur Laufzeit den verfügbaren Platz im Browser für ein Bild berrechnen und mir dann ein Bild mittels eines Servlet in eben dieser Grösse ausgeben lassen.
      wann genau soll dies passieren?

      Da die Funktion im src-Attribute des img-Elements aufgerufen wird, also beim Zugriff auf die Bilddatei (d.h.: onload scheidet aus, da bei onload das Bild mit seiner Grösse schon als Anzeige im Browser existiert)

      document.getElementById("image").setAttribute("src", url);
      ich hätte es so gemacht:
      document.getElementById("image").src = url;

      Das probier ich gleich mal aus, sollte aber den selben Effekt haben.

      <img src="javascript:appendWindowSizeOnURL('ImageServlet');" id="image" width="100%" />
      Ein javascript-Label im src-Attribut? Scheint mir zweifelhaft.

      Das sollte ebenso gültig sein, wie ein javascript-Aufruf im href-Attribut des a-Elements.

      Das eigentliche Problem liegt nun darin, dass Mozilla das Bild nach einem Klick auf einen Link,
      aha, vielleicht solltest du das JS besser in diesen Link tun bzw. per Eventhandler aufrufen?

      Ja die Idee hatte ich auch schon, wollte diese aber nur als absolute "Notlösung" einsetzen.

      Gruß
      Wurf

      Danke nochmal.

      1. document.getElementById("image").setAttribute("src", url);
        ich hätte es so gemacht:
        document.getElementById("image").src = url;
        Das probier ich gleich mal aus, sollte aber den selben Effekt haben.

        ...den hat es auch.

    2. Ok, ich hol dann doch mal etwas weiter aus.
      Also ich habe ein Servlet, welches sowohl für die Darstellung der Webseite als auch für das Holen von Bildern verantwortlich ist.
      Diese beiden Aktionen werden durch einen Parameter unterschieden.
      Ein Link, der also meine komplette Anwendung anzeigt sieht dann etwa so aus:
      http://localhost/ImageServlet?mode=generateLayout&view=fullscreen

      während alle Bilder, die in dieser Anwendung auftauchen in etwa folgendes src-Attribut haben:
      http://localhost/ImageServlet?mode=getImage&width=800&height=450

      wobei natürlich dir letzte Teil der URL (&width=800&height=450) mittels des JavaScripts zur Laufzeit (beim holen des Bildes) erst berechnet wird.

      Die Anwendung enthält nun weitere Links, die die Darstellung der Anwendung im wesentlichen ändern (zbsp. ein-/ausblenden von thumbnailliste und navigation, vollbilddarstellung, etc.)
      Diese Designveränderungen werden wieder mittels Parameter an das Servlet geschickt, welches ein XML-Baum erzeugt, der mittels XSLT zu einer HTML-Seite transformiert wird. Und genau in diesem XSL-Stylesheet gibt es die Anweisung für die Darstellung der Bilder (bzw. hier des Hauptbildes)

      --- beginn code snip ---
      <xsl:template name="image">
        <xsl:if test="$displayedFile != ''" >
          <xsl:variable name="url" select="concat($home,$displayedFile,'?mode=getImage')" />
          <img width="100%" id="image" src="javascript:appendWindowSizeOnURL('{$url}');" />
        </xsl:if>
      </xsl:template>
      --- code snip end ---

      1. Hi

        wobei natürlich dir letzte Teil der URL (&width=800&height=450) mittels des JavaScripts zur Laufzeit (beim holen des Bildes) erst berechnet wird.

        nein, nicht _beim_ Holen. Die Berechnung muss vorher erfolgen.
        Warum berechnest du die Werte nicht, wenn die Seite fertig geladen ist (onload-Event) und setzt dann die src den Bildes neu?

        Gruß
        Wurf

        1. Hi

          wobei natürlich dir letzte Teil der URL (&width=800&height=450) mittels des JavaScripts zur Laufzeit (beim holen des Bildes) erst berechnet wird.
          nein, nicht _beim_ Holen. Die Berechnung muss vorher erfolgen.
          Warum berechnest du die Werte nicht, wenn die Seite fertig geladen ist (onload-Event) und setzt dann die src den Bildes neu?

          Sorry aber ich glaube, du hast mein grundsätzliches Problem nicht so ganz verstanden. Ich habe Serverseitig "riesige Bilder" die mittels eines Servlets skaliert und ausgegeben werden sollen. Die Parameter, die für die Skalierung notwendig sind, bekomme ich aus dem verfügbaren Platz des Imageholders. Das src-Attribute des img-Elements ruft nun ein JavaScript auf, dass den verfügbaren Platz ermittelt und ihn einfach an eine URL hängt, die als neues src-Attribut geschrieben wird. Erst jetzt wird das eigentliche Bild mittels des Servlets berechnet und ausgegeben. Würde ich deine Methode verwenden, so würde ich erst ein Bild (grösse weiss noch keiner, aber unter umständen "riesig") laden, um es danach mit dem gleichen skalierten Bild zu ersetzen. Das würde sicher wie meine bisherige Methode funktionieren, nur das ich eben ein Bild lade um es dann zu ersetzen (eventuelles Performance Problem). Das eigentliche Problem liegt wohl irgendwie darin, dass Mozilla bei einem internen Link der nur das Layout verändert, nicht alle Elemente neu zu laden scheint. Allerdings ist mir dann schleierhaft, wieso gar kein Bild angezeigt wird.

          Danke
          Michael

          Gruß
          Wurf

          1. Hi nochmal

            Sorry aber ich glaube, du hast mein grundsätzliches Problem nicht so ganz verstanden.

            doch habe ich, ich glaube du denkst einfach zu kompliziert

            Würde ich deine Methode verwenden, so würde ich erst ein Bild (grösse weiss noch keiner, aber unter umständen "riesig") laden

            das habe ich nicht behauptet. Du musst natürlich zunächst irgendein kleines Defaultbild laden.
            Alternativ kannst du auch das komplette img-Element per DHTML anlegen.

            Gruß
            Wurf

            1. Hi nochmal

              Sorry aber ich glaube, du hast mein grundsätzliches Problem nicht so ganz verstanden.
              doch habe ich, ich glaube du denkst einfach zu kompliziert

              Würde ich deine Methode verwenden, so würde ich erst ein Bild (grösse weiss noch keiner, aber unter umständen "riesig") laden
              das habe ich nicht behauptet. Du musst natürlich zunächst irgendein kleines Defaultbild laden.
              Alternativ kannst du auch das komplette img-Element per DHTML anlegen.

              Gruß
              Wurf

              So ich hab noch ein bissl rumexperimentiert und folgendes festgestellt. Beim ersten Ausführen des HTML-Codes kann Mozilla das javascript im src-Attribut verarbeiten. Bei einem 2. Aufruf selbiger Seite über eine "Selbstverlinkung" steht dann unter Seiteninformation/Media/URL: "javascript:appendWindowSizeOnURL('http://127.0.0.1:8080/ImageServlet/Beispielbilder/Wasserlilien.jpg?mode=getImage')". Das gibt es so natürlich nicht und merkwürdigerweise führt er eben das Script nicht aus. Obwohl es mit einem Refresh der Seite oder eben beim ersten Aufruf noch funktioniert. Irgendwie bin ich jetzt verwirrt und kann den Fehler nicht finden.

              Danke
              Michael

              1. Hi nochmal

                Sorry aber ich glaube, du hast mein grundsätzliches Problem nicht so ganz verstanden.
                doch habe ich, ich glaube du denkst einfach zu kompliziert

                Würde ich deine Methode verwenden, so würde ich erst ein Bild (grösse weiss noch keiner, aber unter umständen "riesig") laden
                das habe ich nicht behauptet. Du musst natürlich zunächst irgendein kleines Defaultbild laden.
                Alternativ kannst du auch das komplette img-Element per DHTML anlegen.

                Gruß
                Wurf
                So ich hab noch ein bissl rumexperimentiert und folgendes festgestellt. Beim ersten Ausführen des HTML-Codes kann Mozilla das javascript im src-Attribut verarbeiten. Bei einem 2. Aufruf selbiger Seite über eine "Selbstverlinkung" steht dann unter Seiteninformation/Media/URL: "javascript:appendWindowSizeOnURL('http://127.0.0.1:8080/ImageServlet/Beispielbilder/Wasserlilien.jpg?mode=getImage')". Das gibt es so natürlich nicht und merkwürdigerweise führt er eben das Script nicht aus. Obwohl es mit einem Refresh der Seite oder eben beim ersten Aufruf noch funktioniert. Irgendwie bin ich jetzt verwirrt und kann den Fehler nicht finden.

                Mich beschleicht so langsam das Gefühl, dass es sich hierbei um eine Security-Massnahme seitens Mozilla gegenüber JS handelt, um eventuelle Endlosschleifen, das einbringen gefährlichen Codes oder ähnliches auszuschliessen. Jedenfalls hat Google bei der Suche nach "<img src="javascript:" einige Internet-Security Seiten ins Spiel gebracht. Jetzt weiss ich auch warum es unter dem IE funktioniert ;-).
                Dann werde ich wohl über ein explizites Event-handling nicht drum herum kommen. Ich dank dir jedoch nochmal recht herzlich für deine Vorschläge.

                Gruss
                Michael