worst_case: Bild aus Kamera laden

Hallo,

ich möchte auf einem Webserver ein Bild aus einer Kamera (Instar 9010) laden. Hierzu habe ich folgenden Code:

function bild_neuladen()
{
    var kommando = '..' + upcam_url + 'cgi-bin/hi3510/mjpegstream.cgi?-chn=11' + '&-usr=*****&-pwd=*****';


    if (first_start == 0)
    {
	preload.src = document.getElementById('camimage').src = kommando;
	first_start = 1;
    }
    else
    {
	document.getElementById('camimage').src = preload.src;
	preload.src = kommando;
    }


    preload.onload = function() { bild_neuladen(); }
}
Quelltext hier

Wenn ich mit Chrome oder Firefox auf die Webseite mit dem Kamerabild zugreife funktioniert alles ohne Probleme, nur Applegeräte (Safari) zeigen das Bild meist nicht an. Manchmal kommt das Bild beim ersten mal, wenn ich aber auf eine andere Webseite wechsel und wieder zurück auf die Webseite mit dem Kamerabild komme, wird das Bild nicht angezeigt.

Wenn hat einen Tip ?

  Danke
   worst_case

Edit Rolf B: Credentials gelöscht

  1. Hallo worst_case,

    ich möchte auf einem Webserver...

    <selfhtml-interrupt>
    Möchtest Du das? Das ist JavaScript, das sind DOM Operationen, das ist ein Webclient (also der Browser), kein Server.

    URLs wie &-usr=*****&-pwd=***** in die wilde weite Welt zu verteilen ist tödlich. Ich kenne dein Kamerasystem nicht, aber die Befürchtung ist, dass man mit Kenntnis von usr und pwd die Kontrolle über die Kamera übernehmen kann.

    Noch tödlicher ist, die Defaultwerte stehen zu lassen, wonach es bei Dir aussieht. Ändere das bitte. Dringend.

    Wenn die Kamera nur unter deiner Aufsicht betrieben wird und nur in deinem hausinternen Netz, dann ist es nicht so dringend. Aber besser wär's trotzdem.
    </selfhtml-interrupt>

    Applegeräte (Safari) zeigen das Bild meist nicht an.

    Das ist schwierig zu diagnostizieren. Du schreibst "Geräte". Sind das mehrere iPhones? Oder auch Apple Desktops oder iPads?

    Auf einem iPhone ist die Fehlersuche schwieriger, weil Mobiltelefone keine Browser-Entwicklerwerkzeuge haben. Bei Android kann man das über USB debuggen, wie das bei Apple geht, weiß ich nicht. Auf einem Mac sollte der Safari Entwicklerwerkzeuge haben. Wenn der Fehler da auch auftritt, solltest Du dort zuerst ansetzen.

    Läuft der Request auf einen Timeout? Apple verwendet vielleicht andere Timeoutwerte. Das siehst Du in den Entwicklerwerkzeugen, die auch ein Safari hat. Schau auf die Netzwerkzugriffe und in die Konsole, ob Fehler protokolliert werden.

    Die erste Frage ist, ob das Problem im Safari liegt oder ob die Kamera mit Safari-Requests nicht klarkommt. Das sollte sich auf diese Weise herausfinden lassen.

    Ob dein JavaScript okay ist, kann ich nicht beurteilen. Es sieht aber merkwürdig aus, und es fehlt auch Entscheidendes. Vor allem ist unklar, was es mit den globalen Variablen first_start und preload auf sich hat, und wie der erste Aufruf von bild_neuladen zu Stande kommt. Es kann sein, dass Safari ein paar Dinge anders timed und es dadurch zu sogenannten Race-Conditions kommt, die das von Dir geschilderte "mal geht's, mal geht's nicht" erklären können.

    Eventuell musst Du mehr Code zeigen, und Du müsstest vielleicht auch erklären, was Du mit dieser first_start und bild_neuladen-Logik erreichen möchtest.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Servus Rolf,

      vielen Dank für deine Ausführungen. Ich möchte das noch kurz berichtigen.

      Kamera und Webserver stehen am gleichen Ort. Der Apache2 Webserver "leitet/verbindet" die feste IP der Kamera mittels ProxyPass/ProxyPassReserve mit einem Namen "/kamera_m1/

      Wenn ich von außen (trotzdem alles Intranet) auf den Webserver mittels Browser von einem anderen Rechner auf dem Webserver zugreife, holt mir mein "javascript" von der Webseite das Bild von der Kamera und zeigt es im <img> tag an.

      Die Variablenvar first_start=0; var preload = new Image();

      werden im globalen Teil des script deklariert.

      Der "first_start" soll bewirken, das beim 2. Durchlauf das "vorgeladene" Bild angezeigt wird, danach wieder ein Bild von der Kamera geholt wird. Ich will damit bezwecken, dass das Bild immer erst vorgeladen wird, bevor es angezeigt wird.

      Passworte und Usernamen ... ist klar ;-)

      Testgeräte: Ipad und Iphone geht nicht. (Apple-PC habe ich keinen) Android, Windows und Linuxgeräte funktionieren

       Gruß
      

      worst_case

      1. Hallo worst_case,

        okay. Du hast also ein img Element mit der ID camimage.

        ...
        <body>
        ...
           <img id="camimage" src="???">
        ...
        </body>
        

        Und Du hast JS dieser Art

        var first_start = 0,
            preview = new Image();
        
        function bild_neuladen() {
           ...kennen wir schon...
        }
        

        Ansonsten müsstest Du bitte die Zähne etwas weiter auseinanderbringen. Wenn Du eine Race-Condition drin hast, die das auslöst, reicht das alles nicht.

        Wie findet der erste Aufruf von bild_neuladen statt? Das geht aus deinem Code nicht hervor, du zeigst eine Funktion, die sich zwar als load-Handler registrieren möchte, aber ohne einen ersten Aufruf passiert da nichts.

        Hat das img Element im HTML einen load-Eventhandler? Welchen Wert hat sein src Attribut zu Anfang?

        Ist das alles, was Du an Script auf der Seite hast? Oder gibt's noch anderes, was da reinmengen kann?

        Das ist alles noch sehr undurchsichtig. Sorry, aber im Moment sind wir noch an einer Stelle, die bei einem Werkstattanruf so aussähe:

        • "Bei meinem Auto klappert was, wie repariere ich das?"
        • "Von wo kommt es, wie klingt es, passiert es nur bei bestimmten Geschwindigkeiten oder bei Kurven?"
        • "Ja, also es kommt von vorn".

        Auto in die Werkstatt bringen (=Link zur Seite schicken) wäre hilfreicher. Es sei denn, da sind Infos bei, die keiner sehen sollte - wie z.B. Credentials.

        Rolf

        --
        sumpsi - posui - obstruxi
        1. OK ... wird gemacht, Zähne sind auseinander ;-)

          Warum die Formatierung hier nicht passt, keine Ahnung. Mir geht es nur um das Bild neu zu laden. Die Steuerung der Kamera funktioniert. (drehen/schwenken/zoom/focus usw.)

          <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
          <head>
          <title>Kamera Rechenreiniger</title>
              <meta HTTP-EQUIV="Content-Type" content="text/html ; charset=utf-8">
              <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
              <meta http-equiv="Pragma" content="no-cache">
              <meta http-equiv="Expires" content="0">
          
              <link rel="icon" type="image/png" href="gif/favicon/favicon.png">
              <link rel="stylesheet" type="text/css" href="/allgemein.css">
          
              <script src="/format.js" type="text/javascript"></script>
          
          <style type="text/css">
          	table { table-layout:fixed; position:absolute;border-collapse:collapse; border:2px solid #000000; border-collapse:separate ; border-spacing:2px;}
          	th {font-family:verdana,Arial; font-size:12pt;border:1px solid #000000; background-color:#6DCEEE; text-align:center;}
          	td {font-size:10pt; border:1px solid #000000;}
          	.eingabe {color:blue; font-weight:bold; cursor:pointer;}
          	.schalter {width:65px; height:50px; display:block; margin-left:auto; margin-right:auto; cursor:pointer;}
          	.schaltertext {font-size:7pt; text-align:center;font-weight:bold;background-color:yellow}
          	area {cursor:pointer;}
          	input {cursor:pointer;}
          </style>
          
          
          <script language="JavaScript" type="text/javascript">
          var upcam_url = "/kamera_maschine_1/";
          
          var upcam_ptzObj = {
          	"stop" : 0,
          	"up" : 1,
          	"down" : 2,
          	"left" : 3,
          	"right" : 4,
          	"upleft" : 18,
          	"upright" : 19,
          	"downleft" : 20,
          	"downright" : 21,
          	"home" : 23,
          	"vscan" : 24,
          	"hscan" : 25,
          	"zoomin" : 31,
          	"zoomout" : 32,
          	"focusin" : 33,
          	"focusout" : 34 }
          
          var xmlHttp= new XMLHttpRequest();
          var xmlfehler=0;
          var param;
          var httpRequest;
          var response;
          var zufall;
          var counter=0;
          var TimerID;
          var first_start=0;
          var preload = new Image();
          
          
          function uhrzeit_stellen()
          {
          const heute = new Date();
          
              var DatumZeit = heute.getFullYear() + '.' + (heute.getMonth()+1) + '.' + heute.getDate() + '.' + heute.getHours() + '.' + heute.getMinutes() + '.' + heute.getSeconds();
              var kommando = '..' + upcam_url + 'cgi-bin/hi3510/param.cgi?cmd=setservertime&-time=' + DatumZeit + '&-timezone=Europe%2FAthens&-dstmode=off' + '&usr=admin&pwd=admin';
              var camimage_obj = document.getElementById('camimage');
              camimage_obj.src = kommando;
              TimerID = setTimeout(bild_neuladen,1000);
          }
          
          function bild_neuladen()
          {
              clearTimeout(TimerID);
              var kommando = '..' + upcam_url + 'cgi-bin/hi3510/mjpegstream.cgi?-chn=11' + '&-usr=admin&-pwd=admin';
          
          
              if (first_start == 0)
              {
          	preload.src = document.getElementById('camimage').src = kommando;
          	first_start = 1;
              }
              else
              {
          	document.getElementById('camimage').src = preload.src;
          	preload.src = kommando;
              }
          
              var e = document.getElementById("zeit");
              preload.onload = function() { bild_neuladen(); }
          }
          
          function upcam_ptzcmdSubmit(casename)
          {
              var upcam_xmlhttp;
          
          	if (window.XMLHttpRequest)
          	{ // code fuer IE7+, Firefox, Chrome, Opera, Safari
          	    upcam_xmlhttp = new XMLHttpRequest();
          	}
          	else
          	{ // code fuer IE6, IE5
          	    upcam_xmlhttp = new ActiveObject("Microsoft.XMLHTTP");
          	}
          
          	clearTimeout(TimerID);
          
          	var kommando = '..' + upcam_url + 'cgi-bin/hi3510/ptzctrl.cgi?-step=0&-act='+casename+'&-speed=45&usr=admin&pwd=admin';
          	upcam_xmlhttp.open("get",kommando, true);
          	upcam_xmlhttp.send(null);
          
          	TimerID = setTimeout("bild_neuladen()", 2000);
          
          }
          
          function upcam_auswahl_position(number)
          {
          	for(i=1;i<=8;i++)
          	{ farbe = document.getElementById('pos_' + i).style.backgroundColor = "#DCDCDC"; }
          	document.getElementById('pos_' + number).style.backgroundColor = "green";
          }
          //#########################################################################
          function upcam_position_laden()
          {
          var farbe;
          
              for(i=1;i<=8;i++)
              {
          	farbe = document.getElementById('pos_' + i).style.backgroundColor;
          	if (farbe == "green")
          	{
          	    clearTimeout(TimerID);
          	    var  xmlHttp = new XMLHttpRequest();
          	    var kommando = '..' + upcam_url + 'cgi-bin/hi3510/param.cgi?cmd=preset&-act=goto&-status=1&-number='+i+'&usr=admin&pwd=admin';
          	    xmlHttp.open("get",kommando, true);
          	    xmlHttp.send(null);
          	    TimerID = setTimeout("bild_neuladen()", 2000);
          	    break;
          	}
              }
          }
          
          function upcam_position_speichern()
          {
          var farbe;
          
              for(i=1;i<=8;i++)
              {
          	farbe = document.getElementById('pos_' + i).style.backgroundColor;
          	if (farbe == "green")
          	{
          	    var  xmlHttp = new XMLHttpRequest();
          	    var kommando = '..' + upcam_url + 'cgi-bin/hi3510/param.cgi?cmd=preset&-act=set&-status=1&-number='+i+'&usr=admin&pwd=admin';
          	    xmlHttp.open("get",kommando, true);
          	    xmlHttp.send(null);
          	    alert("Position " + i + " wurde gespeichert");
          	    break;
          	}
              }
          }
          
          function upcam_position_loeschen()
          {
          var farbe;
          
              for(i=1;i<=8;i++)
              {
          	farbe = document.getElementById('pos_' + i).style.backgroundColor;
          	if (farbe == "green")
          	{
          	    if (confirm('Wollen Sie die Position: ' + i + ' wirklich löschen ?'))
          	    {
          		var  xmlHttp= new XMLHttpRequest();
          		var kommando = '..' + upcam_url + 'cgi-bin/hi3510/param.cgi?cmd=preset&-act=set&-status=0&-number='+i+'&usr=admin&pwd=admin';
          		xmlHttp.open("get",kommando, true);
          		xmlHttp.send(null);
          		alert("Position " + i + " wurde gelöscht");
          		break;
          	    }
          	}
              }
          }
          
          function step_function(keycode)
          {
              switch (keycode)
              {
          	case 37:	// left
          		upcam_ptzcmdSubmit('left');
          		break;
          	case 35:	// down & left
          		upcam_ptzcmdSubmit('downleft');
          		break;
          	case 36:	// up & left
          		upcam_ptzcmdSubmit('upleft');
          		break;
          	case 38:	// up
          		upcam_ptzcmdSubmit('up');
          		break;
          	case 33:	// up & right
          		upcam_ptzcmdSubmit('upright');
          		break;
          	case 39:	// up
          		upcam_ptzcmdSubmit('right');
          		break;
          	case 34:	// down & right
          		upcam_ptzcmdSubmit('downright');
          		break;
          	case 40:	// down
          		upcam_ptzcmdSubmit('down');
          		break;
          	case 107:	// plus
          		upcam_ptzcmdSubmit('zoomin');
          		break;
          	case 109:	// minus
          		upcam_ptzcmdSubmit('zoomout')
          		break;
          	case 106:	// " mal (x)"
          		upcam_ptzcmdSubmit('focusin');
          		break;
          	case 111:	// "geteilt (/)"
          		upcam_ptzcmdSubmit('focusout');
          		break;
              }
          }
          </script>
          </head>
          
          <body bgcolor="#DCDCDC" onload="uhrzeit_stellen();" onkeydown="step_function(event.keyCode);" onkeyup="upcam_ptzcmdSubmit('stop');">
          
          <a id="adresse" style="position:absolute ; left:10px; top:25px;">.</a>
          
          <!-- Kamerabild -->
          <img src="" id="camimage" alt="Kamerabild" title="meine Kamera" style="position:absolute ; left:10 ; top:60 ; height:640px; width:1024px;">
          
          <!-- Kamerasteuerung -->
              <img src="../gif/kamera/kamerasteuerung.png" usemap="#pt_map" id="ptImg" style="position:absolute; left:1050; top:60;"/>
          	<map id="pt_map" name="pt_map">
          	    <area id="ptzLeftUp" shape="poly" onMouseDown="upcam_ptzcmdSubmit('upleft')"  onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="6,55,26,24,53,7,74,52,61,60,52,73"/>
          	    <area id="ptzUp" shape="poly" onMouseDown="upcam_ptzcmdSubmit('up')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="56,8,75,52,89,48,106,52,126,8,88,1"/>
          	    <area id="ptzRightUp" shape="poly" onMouseDown="upcam_ptzcmdSubmit('upright')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="124,9,106,52,119,63,127,75,171,56,152,27"/>
          	    <area id="ptzLeft" shape="poly" onMouseDown="upcam_ptzcmdSubmit('left')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="7,57,1,90,8,125,51,109,47,90,52,75"/>
          	    <area id="vpatrol" shape="circle" onMouseDown="snapDown()" onmouseup="snapUp()" coords="90,90,39" />
          	    <area id="ptzRight" shape="poly" onMouseDown="upcam_ptzcmdSubmit('right')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="171,58,128,76,131,89,128,104,172,123,177,88"/>
          	    <area id="ptzLeftDown" shape="poly" onMouseDown="upcam_ptzcmdSubmit('downleft')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="51,108,9,126,26,154,55,170,73,129,61,120"/>
          	    <area id="ptzDown" shape="poly" onMouseDown="upcam_ptzcmdSubmit('down')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="124,171,91,177,55,170,76,127,91,132,107,126"/>
          	    <area id="ptzRightDown" shape="poly" onMouseDown="upcam_ptzcmdSubmit('downright')" onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="171,126,150,153,124,170,109,126,120,117,128,103"/>
          	    <area id="ptzFocusIn" shape="poly" onMouseDown="upcam_ptzcmdSubmit('focusin')"  onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="2,2,52,2,2,52"/>
          	    <area id="ptzFocusOut" shape="poly" onMouseDown="upcam_ptzcmdSubmit('focusout')"  onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="2,128,2,178,52,178"/>
          	    <area id="ptzZoomIn" shape="poly" onMouseDown="upcam_ptzcmdSubmit('zoomin')"  onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="128,2,178,2,178,52"/>
          	    <area id="ptzZoomOut" shape="poly" onMouseDown="upcam_ptzcmdSubmit('zoomout')"  onMouseOut="upcam_ptzcmdSubmit('stop')" onMouseUp="upcam_ptzcmdSubmit('stop')" coords="178,128,178,178,128,178"/>
          	</map>
          
          	<table style="position:absolute; left:1050; top:260;">
          	    <tr>
          		<td colspan="4" align="center" style="font-size:14pt;">Position</td>
          	    </tr>
          
          	    <tr>
          		<td align="middle"><input id="pos_1" type="button" value="1" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(1)"></td>
          		<td align="middle"><input id="pos_2" type="button" value="2" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(2)"></td>
          		<td align="middle"><input id="pos_3" type="button" value="3" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(3)"></td>
          		<td align="middle"><input id="pos_4" type="button" value="4" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(4)"></td>
          	    </tr>
          	    <tr>
          		<td align="middle"><input id="pos_5" type="button" value="5" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(5)"></td>
          		<td align="middle"><input id="pos_6" type="button" value="6" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(6)"></td>
          		<td align="middle"><input id="pos_7" type="button" value="7" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(7)"></td>
          		<td align="middle"><input id="pos_8" type="button" value="8" style="background-color:#DCDCDC" onMouseDown="upcam_auswahl_position(8)"></td>
          	    </tr>
          
          	    <tr>
          		<td colspan="2"><input type="button" value="LADEN" onMouseDown="upcam_position_laden()"></td>
          		<td colspan="2"><input type="button" value="SETZEN" onMouseDown="upcam_position_speichern()"></td>
          	    </tr>
          	    <tr>
          		<td colspan="4" align="center"><input type="button" value="LÖSCHEN" style="background:red;" onMouseDown="upcam_position_loeschen()"></td>
          	    </tr>
          	    </table>
          
          </body>
          </html>
          
          1. Hallo

            OK ... wird gemacht, Zähne sind auseinander ;-)

            Warum die Formatierung hier nicht passt, keine Ahnung.

            Ich habe die Formatierung korrigiert. Du hattest den Code als „Inlinecode“ (in Backticks eingeschlossen) formatiert, jetzt ist er als Codeblock (jeweils beginnend und endend mit ~~~) formatiert.

            Tschö, Auge

            --
            „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
          2. Hallo worst_case,

            da es deine persönliche Seite ist, mit der vermutlich niemand sonst konfrontiert wird als Du, unterlasse ich jetzt mal die Liste der Punkte, die man gegen dein HTML vorbringen könnte. Nur so viel:

            • HTML 4 ist out. Heute nimmt man HTML 5, und die Doctype-Angabe dazu sieht so aus:

              <!doctype html>
              

              fertig.

            • Man muss nicht alles absolut positionieren. Das erschwert das Design erheblich. Schau Dir Flexbox und Grid an. Das gilt auch für deine Button-„Tabelle“ - das geht auch als Grid.

            • Eine Image-Map ist ebenfalls eine knifflige Sache, vor allem, weil die Area-Angaben in px sind. Wenn das Hintergrundbild der Kamerasteuerung abstrakt ist (also kein verschörkeltes Foto), könntest Du überlegen, es mit SVG neu zu zeichnen, als inline-SVG zu verwenden und die Maus-Events direkt auf die SVG-Pfade zu legen.

            Eventregistrierungen mit on-Attributen sind möglich, machen das HTML aber schwerer lesbar. Beschäftige Dich mit unobtrusive Javascript - in diesem Einleitungsartikel findet Du die Links zu addEventListener und Co.

            Den globalen XMLHttpRequest verwendest Du nicht. Der kann weg.

            Dein Ablauf ist also:

            • Das load Event auf dem Body ruft uhrzeit_stellen() auf. Dort wird das src Attribut des camimage gesetzt und ein 1s timer gestellt, der bild_neuladen aufruft. Die URL, die Du da setzt, sieht mir aber nicht nach einer Bild-URL aus, sondern nach einer Steuer-URL. Hier wäre ein XMLHttpRequest wohl sinnvoller.

            • In bild_neuladen wird der Timer beendet - was nicht nötig ist. Das brauchst Du nur, um einen noch nicht abgelaufenen Timer zu unterbrechen. Dann baust Du eine neue URL und setzt sie für Image-Objekt und <img> Element. D.h. jetzt laufen zwei Requests auf die gleiche Ressource parallel los. Das scheint mir nicht geschickt zu sein. Das passiert aber nur beim ersten Mal, danach wird jeweils der preload-Source in den img Source übertragen.

            Soll der load-Handler dafür sorgen, dass es zu einem "Dauerfeuer" von Nachladevorgängen kommt? Bist Du sicher, dass der load-Handler auch bei unveränderter URL und unverändertem Kamerabild gerufen wird? Das könnte man auf einem iPhone „beweisen“, indem man irgendwo den aktuellen Timestamp auf die Seite einbaut und bei jedem bild_neuladen Aufruf aktualisiert. Denn wenn deine load-Schleife einmal abbricht, ist der Zyklus unterbrochen. Und ein Mobilgerät kann sich bei sowas durchaus anders verhalten als ein Desktop-Browser, um Ressourcen zu sparen.

            Eine Alternative zum load-Handler wäre ein setInterval-Aufruf, der bild_neuladen bspw. alle 500ms aufruft. Diese Zeit musst Du für deine Bedingungen passend wählen. Das Image-Objekt hat eine Eigenschaft "complete", die true ist, wenn das Bild fertig geladen ist. Damit könntest Du pro Intervall prüfen, ob das neue Bild schon da ist. Wenn nicht, überspringst Du einen Updatezyklus.

            Rolf

            --
            sumpsi - posui - obstruxi