holgi: appendChild IE & Safari

Hello,

ich glaube, IE und Safari gehen strikter mit appendChild um, nur wie?

Ich habe einen Uploader programmiert. Funktioniert im FF wunderbar. Dieser soll mehrere gleichzeitige Bilderuploads ermöglichen und den Uploadstatus in Form eines 'loading.gif' anzeigen.

Dafür habe ich ein Div, welches unterteilt ist in zwei Divs. Der erste beinhaltet die Iframes, der zweite den Status und wenn fertig das Resultat, also die Thumbs.

Im ersten Div ist zu begin ein Iframe. Im Iframe wird eine zweite PHP geladen, die erstmal nur ein Form + Fileinput anzeigt und bei Submit das Bild entgegennimmt...

Hier der Code:

  
function upload(){  
  var form  = document.getElementsByTagName('form')[0];  
  var left  = parent.document.getElementById('upload_left');  
  var right  = parent.document.getElementById('upload_right');  
  var iframe = parent.document.getElementsByTagName('iframe')[parent.upcount];  
  
  iframe.style.display='none';  
  
  parent.upcount++;  
  form.style.display="none";  
  form.submit();  
  
  right.innerHTML='<div style="width:75px; height:75px; float:left; margin:2px 2px 0px 0px; background:url(images/loading.gif) center no-repeat;">&nbsp;</div>'+right.innerHTML;  
  
  var newform = document.createElement('<iframe>');  
  newform.setAttribute('allowtransparency','true');  
  newform.setAttribute('frameborder','0');  
  newform.setAttribute('src','imageupload.php');  
  newform.setAttribute('class','imageupload');  
  
  left.appendChild(newform);  
  
 }  
  
 function success(imgsrc){  
  var right    = parent.document.getElementById('upload_right');  
  var div    = right.getElementsByTagName('div');  
  var searchstring  = eval("/loading.gif/i");  
  
  for(i=0; i<div.length; i++){  
   if(div[i].style.background.search(searchstring) != -1){  
    div[i].style.background='url(../data/images/quad_3_'+imgsrc+') center no-repeat';  
    return;  
   }  
  }  
 }  

upload() wird onchange bei Fileinput ausgeführt.
success() wird beim onload des Iframes, also nachdem das Bild entgegengenommen und verarbeitet wurde.

Das klappt soweit auch einmal, nur wird mir dann kein nächstes Iframe angezeigt, warum?

Mit innerHTML darf ich nicht arbeiten, denn JS führt dann die anderen Iframes erneut aus, das geht nach hinten los. Ich muss appenChild nehmen, damit die bereits aktiven, uplaodeden Iframes weiterarbeiten und nicht unterbrochen werden.

Jemand eine Idee?!

kollegial, Gruß

  1. Was mir auf Anhieb auffällt, vielleicht liegt der Kernfehler woanders:

    var form  = document.getElementsByTagName('form')[0];

    Kürzer: document.forms[0]

    var left  = parent.document.getElementById('upload_left');
      var right  = parent.document.getElementById('upload_right');
      var iframe = parent.document.getElementsByTagName('iframe')[parent.upcount];

    Kürzer:

    var doc = parent.document,
        left = doc.getElementById('upload_left'),
        ...;

    parent.upcount++;
      form.style.display="none";
      form.submit();

    Ich weiß nicht, ob alle Browser es erlauben, dass File-Upload-Formular per JavaScript abgesendet werden können?!

    right.innerHTML='<div style="width:75px; height:75px; float:left; margin:2px 2px 0px 0px; background:url(images/loading.gif) center no-repeat;">&nbsp;</div>'+right.innerHTML;

    Wie wärs mit einem img-Element anstelle eines leeren divs?

    var newform = document.createElement('<iframe>');

    Das muss document.http://de.selfhtml.org/javascript/objekte/document.htm#create_element@title=createElement('iframe') lauten, du notierst hier keinen Start-Tag, sondern den Elementnamen als String.

    newform.setAttribute('allowtransparency','true');
      newform.setAttribute('frameborder','0');
      newform.setAttribute('src','imageupload.php');
      newform.setAttribute('class','imageupload');

    Attribute solltest du besser mit dem Schema element.attribut = "wert" setzen, also newform.src = "...", newform.className = "..." usw. Manche Browser wie IE tun sich mit der setAttribute-Schreibweise schwer.

    var searchstring  = eval("/loading.gif/i");

    Das eval hier ist unnötig, wenn du einen regulären Ausdruck notieren willst, kannst du einfach folgendes schreiben:

    var searchstring = /loading.gif/i;

    Das \ vor dem Punkt ist nötig, weil . sonst in einem regulären Ausdruck "beliebiges Zeichen" bedeutet.

    for(i=0; i<div.length; i++){

    Du solltst var i schreiben, damit i keine globale Variable ist.

    Einfacher:

    var divs = right.getElementsByTagName('div');
    for (var i = 0, div; div = divs[i]; i++) {
       if (searchstring.test(div.style.background)) {
          div.style.background = "...";
       }
    }

    Mathias

    1. var form  = document.getElementsByTagName('form')[0];
      Kürzer: document.forms[0]

      ja, aber ist das wichtig? falsch ist das ja nicht...

      var left  = parent.document.getElementById('upload_left');
        var right  = parent.document.getElementById('upload_right');

      Kürzer:
      var doc = parent.document,
          left = doc.getElementById('upload_left'),

      nun, so mache ich das überlicherweise auch, doch um ein script erstmal zu machen, lieber ausführlich und nachträglich einstampfen. eigentlich auch egal...

      Ich weiß nicht, ob alle Browser es erlauben, dass File-Upload-Formular per JavaScript abgesendet werden können?!

      es klappt genau ein Mal, im FF, SAF, IE

      Wie wärs mit einem img-Element anstelle eines leeren divs?

      ja, das könnte man auch machen... obs daran liegt?

      Attribute solltest du besser mit dem Schema element.attribut = "wert" setzen, also newform.src = "...", newform.className = "..." usw. Manche Browser wie IE tun sich mit der setAttribute-Schreibweise schwer.

      das kannst du im Safari knicken... schon probiert... :( würde den code aufblähen wegens browserweiche... die richtige schreibweise wird dann auch wichtig (case sens.)

      var searchstring  = eval("/loading.gif/i");

      Das eval hier ist unnötig, wenn du einen regulären Ausdruck notieren willst, kannst du einfach folgendes schreiben:

      var searchstring = /loading.gif/i;

      oha, gut zu wissen. aber wie gesagt, einmal funktioniert alles. nur erscheint kein zweites iframe...

      for(i=0; i<div.length; i++){

      Du solltst var i schreiben, damit i keine globale Variable ist.

      das kann natürlich stimmen (hab in letzter zeit eher in AIR JS gecoded, da geht so vieles) :(

      ich kann mir vorstellen, dass das sowas wie ein sicherheits-ding ist vom IE und safari...

      nunja, nur die paranoiden überleben...

      danke dennoch. werd noch ein wenig probieren.

      1. Bevor wir jetzt weiterhin herumrätseln, zeige uns doch bitte mal ein funktionierendes Online-Beispiel, bei dem der Fehler auftritt, sodass wir das näher untersuchen können.

        Attribute solltest du besser mit dem Schema element.attribut = "wert" setzen, also newform.src = "...", newform.className = "..." usw. Manche Browser wie IE tun sich mit der setAttribute-Schreibweise schwer.

        das kannst du im Safari knicken... schon probiert... :( würde den code aufblähen wegens browserweiche...

        Browserweiche?? Für das Setzen von Attributwerten? Was soll daran im Safari nicht funktionieren?

        oha, gut zu wissen. aber wie gesagt, einmal funktioniert alles. nur erscheint kein zweites iframe...

        "Funktioniert einfach nicht" ist weder eine Beschreibung noch eine Untersuchung. Zeigen die fraglichen Browser JavaScript-Fehler an? Hast du mit Debug-Ausgaben überprüft, ob der Code korrekt ausgeführt wird, ob alle Aufrufe das Gewünschte zurückgeben und die Variablen korrekt gefüllt werden? Wird der Iframe beim zweiten Mal eingefügt? Das DOM kannst du im IE mit der IE Developer Toolbar, in Safari mit dem Web Inspector überprüfen.

        ich kann mir vorstellen, dass das sowas wie ein sicherheits-ding ist vom IE und safari...

        Dann müsste die Ausführung des Codes abbrechen und/oder ein Fehler angezeigt werden, jedenfalls könntest du dem auf die Schliche kommen mit Debugging.

        Mathias

        1. Bevor wir jetzt weiterhin herumrätseln, zeige uns doch bitte mal ein funktionierendes Online-Beispiel, bei dem der Fehler auftritt, sodass wir das näher untersuchen können.

          ich gebe sicherlich nicht meine dyndns raus... *hust*

          Attribute solltest du besser mit dem Schema element.attribut = "wert" setzen, also newform.src = "...", newform.className = "..." usw. Manche Browser wie IE tun sich mit der setAttribute-Schreibweise schwer.

          schon gemacht, Safari will nicht.

          Browserweiche?? Für das Setzen von Attributwerten? Was soll daran im Safari nicht funktionieren?

          anscheinend...

          "Funktioniert einfach nicht" ist weder eine Beschreibung noch eine Untersuchung. Zeigen die fraglichen Browser JavaScript-Fehler an?

          nehme es wörtlich. Das Script tut im Safari nicht das, was es im FF tut. tut tut.

          Hast du mit Debug-Ausgaben überprüft, ob der Code korrekt ausgeführt wird

          Ja, keine Fehlermeldung!

          Wird der Iframe beim zweiten Mal eingefügt?

          nein.

          Das DOM kannst du im IE mit der IE Developer Toolbar, in Safari mit dem Web Inspector überprüfen.

          habe ich alles, nutze ich ...

          ich kann mir vorstellen, dass das sowas wie ein sicherheits-ding ist vom IE und safari...

          Dann müsste die Ausführung des Codes abbrechen und/oder ein Fehler angezeigt werden

          das ist es ja, es wird auch kein Fehler ausgegeben.

          1. "Funktioniert einfach nicht" ist weder eine Beschreibung noch eine Untersuchung.
            Das Script tut im Safari nicht das, was es im FF tut. tut tut.

            Ja, sehr witzig. Aber verarschen kann ich mich auch selbst.

            Mathias

          2. Hi,

            Bevor wir jetzt weiterhin herumrätseln, zeige uns doch bitte mal ein funktionierendes Online-Beispiel, bei dem der Fehler auftritt, sodass wir das näher untersuchen können.

            ich gebe sicherlich nicht meine dyndns raus... *hust*

            Dann lad's verdammt noch mal irgendwo hoch, wenn du Hilfe haben willst.

            Attribute solltest du besser mit dem Schema element.attribut = "wert" setzen, also newform.src = "...", newform.className = "..." usw. Manche Browser wie IE tun sich mit der setAttribute-Schreibweise schwer.

            schon gemacht, Safari will nicht.

            Neben "funktioniert nicht" gewoehne dir bitte auch alle weiteren, ebenso inhaltsleeren Umschreibungen ab.

            MfG ChrisB

            --
            „This is the author's opinion, not necessarily that of Starbucks.“
            1. Dann lad's verdammt noch mal irgendwo hoch, wenn du Hilfe haben willst.

              Neben "funktioniert nicht" gewoehne dir bitte auch alle weiteren, ebenso inhaltsleeren Umschreibungen ab.

              Sagmal, kiffst zu zuviel? ;) Das sieht mir nach einer latenten narzistischen Störung aus... Also entweder kiffst du zu wenig oder zu viel... ;)

              Aber danke der Hilfe bisher.

              kollegial

  2. Hi,

    ich glaube, IE und Safari gehen strikter mit appendChild um, nur wie?

    Das hatten wir heute doch schon mal (https://forum.selfhtml.org/?t=181026&m=1196726)

    var left  = parent.document.getElementById('upload_left');
      var newform = document.createElement('<iframe>');
      left.appendChild(newform);

    Das Element wird in einem Dokument erzeugt, soll aber in ein anderes eingefügt werden.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. Das hatten wir heute doch schon ma

      nada, schau dir den code bitte GENAU an ;)

      var left  = parent.document.getElementById('upload_left');
        var newform = document.createElement('<iframe>');
        left.appendChild(newform);

      da steht parent! also über dem iframe, und dort soll es auch passieren ;)

      gracias

      1. Hi,

        Das hatten wir heute doch schon ma

        nada, schau dir den code bitte GENAU an ;)

        Und du dir bitte das, worauf du hingewiesen wurdest.

        var left  = parent.document.getElementById('upload_left');
          var newform = document.createElement('<iframe>');
          left.appendChild(newform);

        da steht parent! also über dem iframe, und dort soll es auch passieren ;)

        In der Zeile, wo du das Iframe-Element erzeugst (wie von Mathias schoin gesagt, uebrigens falsch) - da steht *nichts* davon, dass du das Element *im* document des parents erzeugst.

        MfG ChrisB

        --
        „This is the author's opinion, not necessarily that of Starbucks.“
        1. var newform = document.createElement('<iframe>');

          In der Zeile, wo du das Iframe-Element erzeugst (wie von Mathias schoin gesagt, uebrigens falsch) - da steht *nichts* davon, dass du das Element *im* document des parents erzeugst.

          muss das? jetz mal ehrlich? warum checkt sowas die AIR-Core und der Firefox? Nur nicht IE und Safari?

          muss es lauten:

          var newform = parent.document.createElement('<iframe>');

          ? was sicherlich sicherer ist, aber unbequemer...

          1. muss das? jetz mal ehrlich? warum checkt sowas die AIR-Core und der Firefox? Nur nicht IE und Safari?

            Vermutlich weil letztere sich an den DOM-Standard halten. Ein Knoten mit einem fremden Besitzerdocument kann für gewöhnlich nur mit importNode in ein anderes überführt werden. Andernfalls müsste appendChild eine WRONG_DOCUMENT_ERR-Exception auslösen.

            Mathias

          2. Hi,

            muss es lauten:

            var newform = parent.document.createElement('<iframe>');

            Nein, auch da sind die spitzen Klammern immer noch fehl am Platze.

            MfG ChrisB

            --
            „This is the author's opinion, not necessarily that of Starbucks.“
            1. var newform = parent.document.createElement('<iframe>');
              Nein, auch da sind die spitzen Klammern immer noch fehl am Platze.

              ;) peinlich... ja, das ist definitiv falsch...

              parent.document.createElement() ist es zumindest nicht...

  3. var newform = document.createElement('<iframe>');

    das ist falsch.

    var newform = document.createElement('iframe');

    richtig.

    und ob mit oder ohne parent. vor dem document macht im Safari und IE keinen Unterschied.

    Ich geh ins Bett.

  4. var newform = document.createElement('<iframe>');
      newform.setAttribute('allowtransparency','true');
      newform.setAttribute('frameborder','0');
      newform.setAttribute('src','imageupload.php');
      newform.setAttribute('class','imageupload');

    left.appendChild(newform);

    Wenn du keinen Testcase lieferst, baue ich mir halt einen selbst.

    Im IE tritt in der appendChild-Zeile eine Exception "Ungültiges Argument" auf. Nach dem Owner-Document-Wechsel klappts.

    Safari hat Probleme, die src für den iframe vor dem appendChild anzunehmen, der iframe blieb leer. Wenn ich das umstelle und das Element erst einhänge, klappts.

    Außerdem würde ich das form.submit(), welches das aktuell angezeigte Dokument auswechselt und alle Objekte aus dem Speicher räumt, erst am Ende der Funktion ausführen. Das scheint nicht unbedingt nötig zu sein, aber erscheint mir robuster.

    Mathias

    1. Safari hat Probleme, die src für den iframe vor dem appendChild anzunehmen, der iframe blieb leer. Wenn ich das umstelle und das Element erst einhänge, klappts.

      Übrigens geben sich newform.src = "..." und setAttribute diesbezüglich nichts.