'$ (Document) .ready ()' nin jQuery eşdeğeri nedir?


444

JQuery olmayan eşdeğeri $(document).ready()nedir?


4
Herhangi $(document).ready()bir kütüphane kullanmadan jQuery'nin etkinliğini yeniden oluşturmak istiyorsanız , şuna bir göz atın: stackoverflow.com/questions/1795089/…
CMS

@OP: $(document).ready()- books.google.com/… adresinin vanilya JavaScript uygulaması için Pro JavaScript Teknikleri sayfasının 89. sayfasına göz atın . Ayrıca addEvent, kod da kitapta bulunan Dean Edwards tarafından yazılan olay bağlayıcı soyutlamayı kullanır :)
Russ Cam

Yanıtlar:


73

Hakkında güzel bir şey $(document).ready() daha önce ateş olmasıdır window.onload. Load fonksiyonu, harici varlıklar ve görüntüler dahil her şey yüklenene kadar bekler. $(document).readyancak, DOM ağacı tamamlandığında ve manipüle edilebildiğinde ateşlenir. DOM'u jQuery olmadan hazır hale getirmek istiyorsanız, bu kütüphaneye giriş yapabilirsiniz. Birisi jQuery'den sadece bir readykısmını çıkardı. Güzel ve küçük ve yararlı bulabilirsiniz:

zaten Google Code'da


4
DomReady kod ağı! github'da @CMS aracılığıyla: github.com/cms/domready/network
Kzqai

45
Bu soruya cevap vermez ve herhangi bir jQuery kodu göstermez. Nasıl bu kadar çok oy aldı?
Daniel W.

3
@DanielW. Çünkü basit ve pratik. Çoğumuz buraya DOM'un javascript kodu tarafından kullanılmaya hazır olduğundan emin olmak için bir yol aramaya geldik.
abarazal

Evet ama bazılarımız buraya gerçek bir cevap için geldik.
Slbox

614

ECMA'dan mükemmel çalışıyor

document.addEventListener("DOMContentLoaded", function() {
  // code...
});

window.onloadJQuery için eşit olmadığını $(document).readyçünkü $(document).readysadece DOM ağacına bekler iken window.onloaddış öğelere ve görüntüler dahil tüm unsurları kontrol edin.

EDIT : Jan Derk'in gözlemi sayesinde IE8 ve daha eski eşdeğeri eklendi . MDN'de bu kodun kaynağını şu bağlantıdan okuyabilirsiniz :

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "interactive") {
        // Initialize your application or run some code.
    }
}

Bunun dışında başka seçenekler de var "interactive". Ayrıntılar için MDN bağlantısına bakın.


Benjamin ile aynı fikirde. AttachEvent'i kullanamazsınız. Örneğin, Chrome'da şunları elde edersiniz: Uncaught TypeError: document.attachEvent bir işlev değildir. Jan Derk'in bağlantılı cevabını kullanın.
Manuel Arwed Schmidt

9
Bu komut dosyası çağrıldığında belge zaten yüklenmişse ne olur? Hiçbir şey olmayacak :(
oriadam

8
@Deerloper Nope, sadece Chrome konsolunda denedim - hiçbir şey olmadı: document.addEventListener("DOMContentLoaded",function(){console.log(123)})şimdi deneyin
oriadam

2
DOMContent desteği Tarayıcılara yüklendi
Guillaume Husta

1
@elliottregan doğru Bu konuyu kirletmemek için yorumu kaldırmak Hepinizi aynı şeyi öneririz :) Ve gerekirse bir yorum izin gerekirse yorum bırakın. OC sorularının ötesine geçtiği için bu fazladan bir şey
sospedra

43

Bir araya getirdiğim küçük bir şey

domready.js

(function(exports, d) {
  function domReady(fn, context) {

    function onReady(event) {
      d.removeEventListener("DOMContentLoaded", onReady);
      fn.call(context || exports, event);
    }

    function onReadyIe(event) {
      if (d.readyState === "complete") {
        d.detachEvent("onreadystatechange", onReadyIe);
        fn.call(context || exports, event);
      }
    }

    d.addEventListener && d.addEventListener("DOMContentLoaded", onReady) ||
    d.attachEvent      && d.attachEvent("onreadystatechange", onReadyIe);
  }

  exports.domReady = domReady;
})(window, document);

Bu nasıl kullanılır

<script src="domready.js"></script>
<script>
  domReady(function(event) {
    alert("dom is ready!");
  });
</script>

Ayrıca, ikinci bir argüman ileterek geri aramanın çalıştığı içeriği de değiştirebilirsiniz

function init(event) {
  alert("check the console");
  this.log(event);
}

domReady(init, console);

2
Teşekkür ederim. Geriye dönük uyumlu olması hoşuma gidiyor. İlerlemek, daha az şanslı insanları geride bırakmak anlamına gelmez. Modern bir tarayıcıyı kullanamamak (herhangi bir nedenle) talihsiz ...
CO

28

Şimdi 2018 olduğuna göre hızlı ve basit bir yöntem.

Bu bir olay dinleyicisi ekleyecektir, ancak daha önceden işlenmişse dom'un hazır durumda olup olmadığını veya tamamlandığını kontrol edeceğiz. Bu, alt kaynakların yüklenmesi tamamlandıktan önce veya sonra (resimler, stil sayfaları, çerçeveler vb.) Tetiklenebilir.

function domReady(fn) {
  // If we're early to the party
  document.addEventListener("DOMContentLoaded", fn);
  // If late; I mean on time.
  if (document.readyState === "interactive" || document.readyState === "complete" ) {
    fn();
  }
}

domReady(() => console.log("DOM is ready, come and get it!"));

Ek Okumalar


Güncelleme

İşte yazdığım standart ES6 Import & Export kullanan bazı hızlı yardımcı program yardımcıları. Belki bunları bir bağımlılık olarak projelere yüklenebilecek hızlı bir kütüphane haline getirebilirim.

JavaScript

export const domReady = (callBack) => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', callBack);
  }
  else {
    callBack();
  }
}

export const windowReady = (callBack) => {
  if (document.readyState === 'complete') {
    callBack();
  }
  else {
    window.addEventListener('load', callBack);
  }
}

daktilo ile yazılmış yazı

export const domReady = (callBack: () => void) => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', callBack);
  }
  else {
    callBack();
  }
}

export const windowReady = (callBack: () => void) => {
  if (document.readyState === 'complete') {
    callBack();
  }
  else {
    window.addEventListener('load', callBack);
  }
}

sözler

export const domReady = new Promise(resolve => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', resolve);
  }
  else {
    resolve();
  }
});

export const windowReady = new Promise(resolve => {
  if (document.readyState === 'complete') {
    resolve();
  }
  else {
    window.addEventListener('load', resolve);
  }
});

16

Http://youmightnotneedjquery.com/# göre zaten IE8 ile çalışan güzel bir yedek

function ready(fn) {
  if (document.readyState != 'loading') {
    fn();
  } else if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn);
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState != 'loading')
        fn();
    });
  }
}

// test
window.ready(function() {
    alert('it works');
});

gelişmeler : Şahsen ben de türünün fnbir işlev olup olmadığını kontrol ediyorum . Ve @elliottregan olarak önerdiği olay dinleyicisini kullanımdan sonra kaldırın.

Bu soruyu geç cevaplamamın nedeni, bu cevabı aradığım ama burada bulamadığım için. Ve bence bu en iyi çözüm.


1
Evet, bence en iyi cevap bu. Kolay okunur ve DOM zaten yüklenmiş olsa bile kodu çalıştırır. Ekleyeceğim tek şey, olay tetiklendikten sonra eventlistener'ı kaldırmaktır.
elliottregan

14

IE8 tarafından değil, tarayıcıların% 90'ından fazlası tarafından desteklenen , DOMContentLoaded standartlarına uygun bir değiştirme var (Yani tarayıcı desteği için JQuery tarafından kod kullanımının altında) :

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

jQuery'nin yerel işlevi , aşağıda gösterildiği gibi, sadece window.onload'dan çok daha karmaşıktır.

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, false );

    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.isReady ) return;

            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

1
Yeni jQuery eski tarayıcılar için desteği bıraktı ve şimdi sadece DOMContentLoadedve loadolayları kullanıyorlar addEventListenerve önce bu ateş her iki dinleyiciyi de kaldırıyor, bu yüzden iki kez ateş etmiyor.
jcubic

8

Düz vanilya JavaScript'lerinde, kitaplığı yok mu? Bu bir hata.$yalnızca bir tanımlayıcıdır ve siz tanımlamazsanız tanımsızdır.

jQuery $kendi "her şey nesnesi" olarak tanımlar ( jQuerydiğer kütüphanelerle çakışmadan kullanabilmeniz için de bilinir ). JQuery (veya onu tanımlayan başka bir kütüphane) kullanmıyorsanız, $tanımlanmaz.

Yoksa düz JavaScript'te eşdeğerinin ne olduğunu mu soruyorsunuz? Bu durumda, muhtemelen window.onloadtam olarak eşdeğer olmayan, ancak vanilya JavaScript'te aynı etkiye yaklaşmanın en hızlı ve en kolay yoludur.


39
Bu cevabın (ve aşağıdaki diğerleri) birçok aşağılayıcı için: bu soru sorulduğunda, basitçe şöyle dedi: "Javascript'te $ (document) .ready () nedir? Jquery değil. Nedir?" JQuery yüklü olmayan düz vanilya JavaScript'te bunun ne anlama geldiğini soruyor gibiydi. Cevabımda, bu soruyu cevaplamaya çalıştım ve bunun anlamı olması durumunda jQuery veya diğer kütüphaneler olmadan düz vanilya JavaScript'e en yakın kolay cevabı verdim. Tüm ekstra bağlamın, orijinal poster değil, sorunun ne istediğini tahmin eden diğer insanlar tarafından eklendiğini unutmayın.
Brian Campbell

5

Son tarayıcılarda en kolay yol , onDOMContentLoaded , onload , onloadeddata (...) için uygun GlobalEventHandlers kullanmak olacaktır.

onDOMContentLoaded = (function(){ console.log("DOM ready!") })()

onload = (function(){ console.log("Page fully loaded!") })()

onloadeddata = (function(){ console.log("Data loaded!") })()

DOMContentLoaded olayı, ilk HTML belgesi tamamen yüklendiğinde ve ayrıştırıldığında, stil sayfaları, görüntüler ve alt çerçevelerin yüklenmesini beklemeden tetiklenir. Çok farklı bir olay yükü, yalnızca tam yüklü bir sayfayı algılamak için kullanılmalıdır. DOMContentLoaded'in çok daha uygun olacağı yükü kullanmak inanılmaz derecede popüler bir hatadır, bu yüzden dikkatli olun.

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded

Kullanılan işlev, hazır olduğunda kendini tetiklediği için bu durumda çok yararlı olan bir IIFE'dir:

https://en.wikipedia.org/wiki/Immediately-invoked_function_expression

Açıkçası herhangi bir komut dosyasının sonuna yerleştirmek daha uygundur.

ES6'da bir ok işlevi olarak da yazabiliriz:

onload = (() => { console.log("ES6 page fully loaded!") })()

En iyisi DOM öğelerini kullanmaktır, oklu IIFE'yi tetikleyen herhangi bir değişkenin hazır olmasını bekleyebiliriz.

Davranış aynı olacaktır, ancak daha az bellek etkisi olacaktır.

footer = (() => { console.log("Footer loaded!") })()
<div id="footer">

Çoğu durumda, belge nesnesi de hazır olduğunda , en azından tarayıcımda tetikleniyor . Sözdizimi çok güzel, ancak uyumluluklarla ilgili daha fazla teste ihtiyaç duyuyor.

document=(()=>{    /*Ready*/   })()

DOM, öğeleri yükledikten sonra bir IIFE tetikleyebilir mi?
CTS_AE

Elbette, sadece bir fonksiyon, anonim bir fonksiyon, kapanışta.
NVRM

0

Yük üzerindeki gövde de bir alternatif olabilir:

<html>
<head><title>Body onLoad Exmaple</title>

<script type="text/javascript">
    function window_onload() {
        //do something
    }
</script>

</head>
<body onLoad="window_onload()">

</body>
</html>
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.