'$(document).ready()'に相当するjQuery以外の機能は何ですか?


444

非jQueryに相当するものは$(document).ready()何ですか?


4
あなたはjQueryの再現したい場合は$(document).ready()任意のライブラリを使用せずにイベントを、これに表情を与える:stackoverflow.com/questions/1795089/...を
CMS

@OP:のバニラJavaScriptの実装のためのプロのJavaScriptテクニックのページ89をチェックしてください$(document).ready()- books.google.com/...。またaddEvent、Dean Edwardsによって記述されたイベントバインディングの抽象化も使用しています。そのコードも本に含まれています:)
Russ Cam

回答:


75

良い点$(document).ready()は、それが前に発火するということwindow.onloadです。ロード機能は、外部アセットや画像を含むすべてがロードされるまで待機します。$(document).readyただし、DOMツリーが完了して操作できる場合に発生します。jQueryなしでDOMを準備したい場合は、このライブラリにチェックインすることができます。誰かreadyがjQueryから一部だけを抽出しました。その素晴らしくて小さい、あなたはそれが便利であると思うかもしれません:

Google Codeでdomready


4
DomReadyコードネットワーク!githubの@CMS経由:github.com/cms/domready/network
Kzqai

44
これは質問に答えることも、jQuery以外のコードを表示することもありません。どうしてそんなに多くの賛成票を得たのですか?
ダニエルW.

3
@DanielW。シンプルで実用的だからです。私たちのほとんどは、DOMがJavaScriptコードで使用できるように準備する方法を探してここに来ました。
abarazal

ええ、でも私たちの一部は実際の答えを求めてここに来ました。
Slbox

611

これはECMAから完全に機能します

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

window.onloadjQueryのに等しくない$(document).readyので、$(document).ready唯一のDOMツリーに待機しながら、window.onload外部の資産及び画像を含むすべての要素を確認してください。

編集Jan Derkの観察のおかげで、IE8以前の同等物が追加されました。MDNのこのリンクから、このコードのソースを読むことができます。

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

以外にも他のオプションがあります"interactive"。詳細については、MDNリンクを参照してください。


ベンジャミンに同意する。attachEventを単純に使用することはできません。たとえば、Chromeでは次のようになります:Uncaught TypeError:document.attachEventは関数ではありません。Jan Derkによるリンクされた回答を使用してください。
Manuel Arwed Schmidt、2016

9
このスクリプトが呼び出されたときにドキュメントが既に読み込まれている場合はどうなりますか?何も起こりません:(
oriadam

8
@Deerloper Nope、Chromeコンソールでdocument.addEventListener("DOMContentLoaded",function(){console.log(123)})試してみました-何も起こりませんでした:今すぐ試してください
oriadam

2
ブラウザでのDOMContentLoadedのサポート:caniuse.com/domcontentloaded
Guillaume

1
@elliottregan真実このスレッドを汚染しないようにコメントを削除します。同じことをすべて実行することをお勧めします:)そして、必要に応じてコメントを指摘して、必要に応じて1つのコメントを付けます。OCの質問を超えているため、これは余分なものです
ソスペドラ

43

私がまとめた小さなこと

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);

それの使い方

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

2番目の引数を渡すことにより、コールバックが実行されるコンテキストを変更することもできます

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

domReady(init, console);

2
ありがとうございました。下位互換性があるのが気に入っています。前進することは、恵まれない人々を後に残すことを意味するのではありません。(何らかの理由で)最新のブラウザを使用できないのは残念です...
CO

28

2018年ですので、ここにすばやく簡単な方法があります。

これによりイベントリスナーが追加されますが、既に発生している場合は、domが準備完了状態にあるか、それが完了していることを確認します。これは、サブリソース(画像、スタイルシート、フレームなど)の読み込みが完了する前または後に起動できます。

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!"));

追加の読み


更新

TypeScriptを含む、私が書いた標準のES6インポートおよびエクスポートを使用するいくつかのクイックユーティリティヘルパーを次に示します。多分私はこれらを依存関係としてプロジェクトにインストールできる簡単なライブラリにすることに取りかかることができます。

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);
  }
}

TypeScript

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);
  }
}

約束

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/#readyによると、IE8で引き続き機能する優れた代替品は

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');
});

改善:個人的には、型がfn関数かどうかもチェックします。そして@elliottreganが提案したように、使用後にイベントリスナーを削除します。

私がこの質問に後で答える理由は、私がこの答えを探していたが、ここでは見つけられなかったためです。そして、これが最良の解決策だと思います。


1
はい、これは私の意見では最良の答えです。読みやすく、DOMが既にロードされている場合でもコードを実行します。追加するのは、イベントが発生した後にイベントリスナーを削除することだけです。
エリオットレガン

14

標準ベースの置き換えであるDOMContentLoadedがあり、ブラウザの90%以上でサポートされていますが、IE8ではサポートされていません(以下のコードは、JQueryによるブラウザサポート用に使用されています)

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

以下に示すように、jQueryのネイティブ関数は、単なるwindow.onloadよりもはるかに複雑です。

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
新しいjQueryは古いブラウザーのサポートを廃止し、現在はを使用するDOMContentLoadedloadイベントしかありaddEventListenerません。最初にその火は両方のリスナーを削除するため、2回は発生しません。
jcubic

8

ライブラリのない単純なバニラJavaScriptでは?エラーです。$は単なる識別子であり、定義しない限り未定義です。

jQueryは$それ自体を「すべてのオブジェクト」として定義します(jQuery他のライブラリと競合せずに使用できることからも知られています)。jQuery(またはそれを定義する他のライブラリ)を使用して$いない場合は、定義されません。

それとも、同等の機能がプレーンなJavaScriptにあるのかと質問していますか?その場合は、おそらくが必要ですwindow.onload。これは完全に同等ではありませんが、バニラJavaScriptで同じ効果に近づくための最も簡単な方法です。


39
この回答(および以下の他の回答)の多くの反対投票者:この質問が尋ねられたとき、それは単に「JavaScriptの$(document).ready()とは何ですか?jqueryではありません。それは何ですか?」jQueryがロードされていない単純なJavaScriptでそれが何を意味するのかを彼が尋ねているように思えました。私の答えでは、私はその質問に答えようとしただけでなく、jQueryや他のライブラリーがない平凡なJavaScriptに最も簡単に答えられるようにしました。すべての余分なコンテキストは、元のポスターではなく、質問が何を求めているのかを推測する他の人々によって追加されたことに注意してください。
ブライアンキャンベル

5

最近のブラウザーで最も簡単な方法は、適切なGlobalEventHandlersonDOMContentLoadedonloadonloadeddata(...)を使用することです。

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

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

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

DOMContentLoadedイベントは、スタイルシート、画像、サブフレームの読み込みが完了するのを待たずに、最初のHTMLドキュメントが完全に読み込まれて解析されたときに発生します。非常に異なるイベントロードは、完全にロードされたページを検出するためにのみ使用する必要があります。DOMContentLoadedの方がはるかに適切な場所でloadを使用することは非常に人気のある間違いであるため、注意が必要です。

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

使用される関数はIIFEであり、準備が整ったときにトリガーされるため、この場合に非常に役立ちます。

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

スクリプトの最後に配置する方が明らかに適切です。

ES6では、それをアロー関数として記述することもできます。

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

最善の方法はDOM要素を使用することです。矢印の付いたIIFEをトリガーする変数が準備できるまで待つことができます。

動作は同じですが、メモリへの影響は少なくなります。

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

多くの場合、少なくとも私のブラウザでは、ドキュメントオブジェクトは準備ができたときにもトリガーされます。構文は非常に優れていますが、互換性についてさらにテストする必要があります。

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

DOMが要素の読み込みを完了する前にIIFEがトリガーする可能性はありますか?
CTS_AE 2018

確かに、それはクロージャ内の単なる関数、無名関数です。
NVRM 2018

0

本体のonLoadも代替手段になる可能性があります。

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

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

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

</body>
</html>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.