Entwickler-Ecke

Programmiersprachen (Client) - [JS/IE] Probleme mit dem readyState


Heiko - Di 03.11.09 22:22
Titel: [JS/IE] Probleme mit dem readyState
Hallo ihr,

ich suche momentan verzweifelt nach der Ursache eines Problems mit dem IE. Dieser unterstützt ja nicht das DOMReadyEvent. Von daher muss man auf den ReadyState zurückgreifen, der zwei Zustände kennt:

C#-Quelltext
1:
if(document.readyState == "interactive" || document.readyState == "complete")                    

"complete" tritt ein, wenn wirklich alles geladen ist. Also Bilder iFrames etc.. "interactive" soll eintreten, sobald das Skript vollständig geladen wurde, nur halt ohne externe Daten.


Nur leider bekomme ich manchmal bei getElementById beim readystate=interactive null zurück, wes wegen mein JS-Code nicht läuft. Ursache ist, dass ein Bild noch nicht geladen wurde. Allerdings tritt das Problem nur bei etwa 1/10 der Seitenaufrufe (bei mir lokal auf). Allerdings will ich nicht auf complete zurückgreifen, da ich iFrames verwenden muss - und falls die mal sehr langsam Laden, würde mein JS-Code sehr spät ausgeführt werden, was ich nicht will. Hat einer von euch eine elegeante Lösung dafür?


Yogu - Fr 06.11.09 19:31

Hallo Heiko,

ich kannte das DOMReadyEvent gar nicht, und habe deshalb folgendes gebastelt:


JavaScript-Quelltext:
1:
2:
3:
4:
5:
6:
7:
8:
9:
function init() {    
  if (document.getElementById('EinWichtigesSteuerelement') == null) {
    setTimeout("Init();"50);
    return;
  }

  EigentlicheInitialisierung();
}
setTimeout("init();"0);

Bei 90% aller Seitenaufrufe dauert dieses Skript kaum merklich länger, und manchmal wird der Aufbau eben um 50 Millisekunden verzögert. Das merkt kein menschliches Auge.

Grüße,
Yogu


Heiko - Sa 07.11.09 21:39

Hi Yogu,

die Lösung halte ich für unschön ;).

Ich hatte es zum Zeitpunkt des Posts so hier umgangen:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
  addEventDomReady: function(func)
  {
        //W3C-compliant browser
        if(document.addEventListener) {
          document.addEventListener("DOMContentLoaded", func, false);
        }
        //IE
        else
        {
          document.onreadystatechange =
            function()
            {
              if(document.readyState == "interactive" || document.readyState == "complete"){
                //look if we can already start or not (because in 1 of 10 cases there could be problems)
                if (document.getElementById('container') != null) {
                  //remove listener because this event should called only one time
                  document.onreadystatechange = null;
                  func();
                }
              }else if(document.readyState == "complete"){
                func();
              }
            }
        }
  },

Allerdings ist das auch unschön, denn zum einem wieder Elementabhängig und zum anderem kommt das complete-Event teilweise sehr spät, wenn das interactive fehlschlug.

Yahoo nutzt eine Mischform:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
EU._dri = setInterval(function()
  {
    var rs = document . readyState;
    if ("loaded" == rs || "complete" == rs) {
      clearInterval(EU . _dri);EU . _dri = null;EU . _ready();
    }
  } , EU . POLL_INTERVAL);

Finde ich aber auch unschön, da anfangs immer ein Timer mitläuft. Allerdings habe ich an dem Code erkannt, das scheinbar das Problem nur beim auslösen des Events mit incomplete auftritt, jedoch nicht im Zustand incomplete.

Aus diesem Grund habe ich jetzt diesen Code hier, der auch problemlos funktioniert:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function addEventDomReady()
{
  document.onreadystatechange =
    function()
    {
      if(document.readyState == "interactive" ){
        document.onreadystatechange = null;
        window.window.setTimeout("MyFunc()"0);
      }else if(document.readyState == "complete"){
        MyFunc();
      }
         }
}

function MyFunc(){
  document.getElementById("container").innerHTML = 5;
}

addEventDomReady();


Trotzdem danke für deinen Tipp ;).

Grüße
Heiko