51

利用した

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
</head>
<body>
  <button type="button" id="button">Click</button>
  <pre id="output">Not Loading...</pre>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.17.0/babel.min.js"></script>
  <script type="text/babel">
    document.addEventListener('DOMContentLoaded', function () {
      const button = document.getElementById('button');
      const output = document.getElementById('output');

      output.textContent = 'Loading...';

      addEventListener('click', function () {
        output.textContent = 'Done';
      });
     });
  </script>
</body>
</html>

しかし、内部のコードdocument.addEventListener('DOMContentLoaded', function () {});が読み込まれていないようです。

これをコードから削除すると、突然機能します。

ここで JS Binを作成しました。

4

9 に答える 9

117

DOMContentLoadedこれは、この時点でイベントが既に発生している可能性が高いためです。一般的なベスト プラクティスは、document.readyStateをチェックして、そのイベントをリッスンする必要があるかどうかを判断することです。

if( document.readyState !== 'loading' ) {
    console.log( 'document is already ready, just execute code here' );
    myInitCode();
} else {
    document.addEventListener('DOMContentLoaded', function () {
        console.log( 'document was not ready, place code here' );
        myInitCode();
    });
}

function myInitCode() {}
于 2016-10-12T08:17:56.400 に答える
15

コードがイベントをフックするまでに、イベントはすでに発生しています。Babel スタンドアロンの動作方法は、ページ上のすべてのスクリプトをDOMContentLoaded見つけて実行することによって応答することです。type="text/babel"これは次のindex.jsファイルで確認できます。

// Listen for load event if we're in a browser and then kick off finding and
// running of scripts with "text/babel" type.
const transformScriptTags = () => runScripts(transform);
if (typeof window !== 'undefined' && window && window.addEventListener) {
  window.addEventListener('DOMContentLoaded', transformScriptTags, false);
}

イベントを待たずにコードを直接実行するだけです。Babel スタンドアロンがイベントを待機することがわかっているからです。

</body>また、スクリプトをボディの最後、終了タグの直前に置くと、DOMContentLoadedBabel を使用しなくても待機する必要はありません。スクリプトの上で定義されたすべての要素が存在し、スクリプトで使用できるようになります。


あなたが尋ねたコメントで:

しかし、私は開発で Babel スタンドアロンを使用していますが、本番環境に入るときにプリコンパイルします。本番環境に移行したら、再度追加する必要がありますか?

scriptタグがbody上記のように最後にあることを確認してください。イベントを使用する必要はありません。

とにかく使用することが重要な場合は、チェックしてイベントが既に実行されているかどうかを確認できますdocument.readyState(リンクをたどった後、少し上にスクロールします)。

function onReady() {
    // ...your code here...
}
if (document.readyState !== "loading") {
    onReady(); // Or setTimeout(onReady, 0); if you want it consistently async
} else {
    document.addEventListener("DOMContentLoaded", onReady);
}

document.readyStateこれらの段階を経ます (上記のリンクから少し上にスクロールします)。

"loading"Document の読み込み中、"interactive"解析が完了したがサブリソースの読み込み中、および読み込みが完了した時点で戻ります"complete"

于 2016-10-12T08:18:41.950 に答える