Javascript - Belgenin yüklü olup olmadığını belirleme (IE 7 / Firefox 3)


163

Belge yüklendikten sonra bir işlevi çağırmak istiyorum, ancak belge henüz yüklemeyi bitirmiş veya bitirmemiş olabilir. Eğer yüklendiyse, sadece fonksiyonu çağırabilirim. Yüklemediyse, bir olay dinleyicisi ekleyebilirim. Onload çağrılmadığından zaten tetiklendikten sonra bir eventlistener ekleyemiyorum. Peki belgenin yüklenip yüklenmediğini nasıl kontrol edebilirim? Aşağıdaki kodu denedim ama tamamen çalışmıyor. Herhangi bir fikir?

var body = document.getElementsByTagName('BODY')[0];
// CONDITION DOES NOT WORK
if (body && body.readyState == 'loaded') {
    DoStuffFunction();
} else {
    // CODE BELOW WORKS
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

5
"Belge yüklendikten sonra bir işlevi çağırmak istiyorum, ancak belge henüz yüklemeyi bitirmiş veya bitirmemiş olabilir." Bu hesaplanmaz.
Richard Simões

7
Kod bloğu başlangıçta çalıştırıldığında kontrol sahibi olmadığı anlamına geliyor, ancak belge yüklemeyi bitirmeden önce DoStuffFunction () çağrılmamasını istiyor.
Ben Blank

Yanıtlar:


257

Galambalazlar tarafından bahsedilen tüm koda gerek yoktur. Saf JavaScript'te yapmanın çapraz tarayıcı yolu basitçe test etmektir document.readyState:

if (document.readyState === "complete") { init(); }

Ayrıca jQuery bunu yapar.

JavaScript'in nereye yüklendiğine bağlı olarak, bu bir aralık içinde yapılabilir:

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        init();
    }
}, 10);

Aslında, document.readyStateüç eyalet olabilir:

Belge yüklenirken "yükleme", ayrıştırmayı bitirip yine de alt kaynakları yüklemeyi tamamladıktan sonra "etkileşimli" ve yüklendikten sonra "tamam" değerini döndürür. - Mozilla Developer Network şirketinde document.readyState

Dolayısıyla, yalnızca DOM'nin hazır olması gerekiyorsa, kontrol edin document.readyState === "interactive". Sayfanın hazır olması için resimler de dahil olmak üzere tüm öğeleri kontrol edin document.readyState === "complete".


3
@costa, document.readyState == "complete"resimler de dahil olmak üzere her şeyin yüklenmiş olduğu anlamına gelir.
laurent

Her iki olayın birleşimini kullanıyorum document.readyStateve işlevin DOM ayrıştırıldıktan sonra veya daha sonra çağrıldığına bağlı olarak başladığından emin olmak için kullanıyorum. İnteraktif için bir etkinlik var mı readyState?
Tomáš Zato - Monica'yı

3
Kullanırdım /loaded|complete/.test(document.readyState). Bazı tarayıcılar document.readyState"tamamlandı" yerine "yüklendi" olarak ayarlandı . Ayrıca, document.readyState fontların yüklendiğinden emin DEĞİLDİR, eklenti olmadan bunu test etmenin gerçek bir yolu yoktur.
Ryan Taylor

2
Ne olmuş document.onreadystatechange? Tarayıcılar destekliyorsa, bu daha akıcı görünmektedir. stackoverflow.com/questions/807878/…

2
document.readyState !== "loading""DOM için hazır" durumunu kontrol etmenin daha iyi olacağını düşünüyorum . Bu readyState, herhangi bir nedenle ("etkileşimli" durumdan sonra) geç kontrol edilirse sorunların kırpılmasını önler .
rnevius

32

Kütüphaneye gerek yok. jQuery bu komut dosyasını bir süre kullanmıştır, btw.

http://dean.edwards.name/weblog/2006/06/again/

// Dean Edwards/Matthias Miller/John Resig

function init() {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // kill the timer
  if (_timer) clearInterval(_timer);

  // do stuff
};

/* for Mozilla/Opera9 */
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
  var script = document.getElementById("__ie_onload");
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      init(); // call the onload handler
    }
  };
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      init(); // call the onload handler
    }
  }, 10);
}

/* for other browsers */
window.onload = init;

1
Tam olarak ne aradığım - jQuery.ready jQuery kitaplığı olmadan çalışır. Thanx!
stricjux

3
Sorunun konusunu tamamen kaçırdım. initGönderdiğiniz bu kod, sayfa zaten yüklendikten sonra dahil edilirse çalışmaz, bu da OP'nin noktasıdır: komut dosyasının ne zaman dahil edildiğini kontrol edemez. (sadece setIntervalşubenin çalışacağına dikkat edin )
Roatin Marth

3
Bu bir kütüphaneye aittir. Diğer tüm tekerleklerle birlikte insanlar genellikle yeniden icat ederler.
b01

14

Muhtemelen JS programlamayı kolaylaştıran jQuery gibi bir şey kullanmak istersiniz.

Gibi bir şey:

$(document).ready(function(){
   // Your code here
});

Sonra ne yapmak gibi görünüyor.


2
Ve eğer
jQuery'nin

7
Net olmadığı takdirde ready(), belge yüklendikten sonra çağrılırsa , iletilen işlev hemen çalıştırılır.
Ben Blank

2
@ Boş: Tabii belge yüklendikten sonra elbette jQuery'nin kendisi dahil değilse;)
Roatin Marth

@Roatin Marth - Aslında bu da işe yarıyor. (Sadece FF8 ve IE8'de jQuery 1.7.1 ile denedi.)
Ben Blank

35
-1: cevap mantıklı olsa bile OP hiç jQuery'den bahsetmedi. Tüm jQuery projesini sadece belgeyi hazır hale getirmek için kullanmak çok fazladır.
marcgg

8
if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

En son Chrome'da çalışmıyor gibi görünüyor document.loadedher zaman tanımsız
Aniket

Bu 2010'du :). Şimdi kullanacağımbody.readyState === 'loaded'
Jman

6

Bu kodun aslında yükte çalışmasını istiyorsanız , şu anda değil (yani resimlerin de yüklenmesi gerekir), ne yazık ki hazır işlevi sizin için yapmaz. Genellikle böyle bir şey yapıyorum:

Belge javascript'ine dahil et (yani her zaman onload ateşlemeden önce çağrılır):

var pageisloaded=0;
window.addEvent('load',function(){
 pageisloaded=1;
});

Sonra kodunuz:

if (pageisloaded) {
 DoStuffFunction();
} else {
 window.addEvent('load',DoStuffFunction);
}

(Ya da tercih çerçevenizdeki eşdeğeri.) Bu kodu, gelecekteki sayfalar için javascript ve resimlerin önbelleğe alınması için kullanıyorum. Aldığım şeyler bu sayfa için hiç kullanılmadığından, görüntülerin hızlı bir şekilde indirilmesine öncelik vermesini istemiyorum.

Daha iyi bir yol olabilir, ama henüz bulamadım.


4

Mozila Firefox bunun onreadystatechangebir alternatif olduğunu söylüyor DOMContentLoaded.

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "complete") {
        initApplication();
    }
}

In DOMContentLoadedMozila doc diyor ki:

DOMContentLoaded olayı, stil sayfaları, resimler ve alt çerçevelerin yüklenmesini bitirmesini beklemeden belge tamamen yüklendiğinde ve ayrıştırıldığında tetiklenir (load olayı tam yüklü bir sayfayı algılamak için kullanılabilir).

loadOlayın tam belge + kaynak yüklemesi için kullanılması gerektiğini düşünüyorum .


3

JQuery ile yukarıda olan en kolay ve en çok kullanılan yoldur. Ancak saf javascript kullanabilirsiniz, ancak başından okunması için bu komut dosyasını kafada tanımlamaya çalışın. Aradığın şey window.onloadolay.

Aşağıda bir sayaç çalıştırmak için oluşturduğum basit bir komut dosyası var. Sayaç 10 tekrardan sonra durur

window.onload=function()
{
    var counter = 0;
    var interval1 = setInterval(function()
    { 
        document.getElementById("div1").textContent=counter;
        counter++; 
        if(counter==10)
        {
            clearInterval(interval1);
        }
    },1000);

}

2

Bunu dene:

var body = document.getElementsByTagName('BODY')[0];
// CONDITION DOES NOT WORK
if ((body && body.readyState == 'loaded') || (body &&  body.readyState == 'complete') ) {
    DoStuffFunction();
} else {
    // CODE BELOW WORKS
    if (window.addEventListener) {
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload',DoStuffFunction);
    }
}

1

Başka bir çözümüm var, Uygulamamın yeni uygulaması oluşturulduğunda başlatılması gerekiyor, bu yüzden şöyle görünüyor:

function MyApp(objId){
     this.init=function(){
        //.........
     }
     this.run=function(){
          if(!document || !document.body || !window[objId]){
              window.setTimeout(objId+".run();",100);
              return;
          }
          this.init();
     };
     this.run();
}
//and i am starting it 
var app=new MyApp('app');

bildiğim tüm tarayıcılarda çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.