web-dev-qa-db-fra.com

Le code à l'intérieur de l'événement DOMContentLoaded ne fonctionne pas

J'ai utilisé

<!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>

mais il semble que le code à l'intérieur de document.addEventListener('DOMContentLoaded', function () {}); ne soit pas en cours de chargement.

Si je supprime cela de mon code, cela fonctionne soudainement.

J'ai fait un JS Bin ici .

8
Jamgreen

C'est probablement parce que l'événement DOMContentLoaded a déjà été déclenché à ce stade. La meilleure pratique en général consiste à vérifier document.readyState pour déterminer si vous devez ou non écouter l'événement.

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() {}
27
jAndy

L'événement a déjà déclenché au moment où le code le connecte. La manière Babel standalone fonctionne en répondant à DOMContentLoaded en recherchant et en exécutant tous les scripts type="text/babel" de la page. Vous pouvez le voir dans le fichier 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);
}

Exécutez simplement le code directement, sans attendre l'événement, car vous savez que Babel seul l'attendra pour vous.

Notez également que si vous placez votre script à la fin du corps, juste avant la balise de fermeture </body>, il n'est pas nécessaire d'attendre DOMContentLoaded même si vous n'utilisez pas Babel. Tous les éléments définis au-dessus du script existeront et seront disponibles pour votre script.


Dans un commentaire que vous avez demandé:

Mais j'utilise Babel seul en développement, mais je le compilerai à l'avance lorsque je serai en production. Dois-je le rajouter lorsque je commence la production?

Assurez-vous simplement que votre balise script se trouve à la fin de body comme décrit ci-dessus, et qu'il n'est pas nécessaire d'utiliser l'événement.

Si vous avez quand même intérêt à l'utiliser, vous pouvez vérifier si l'événement a déjà eu lieu en cochant document.readyState (après avoir suivi le lien, faites défiler un peu):

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 passe par ces étapes (faites défiler légèrement à partir du lien ci-dessus):

Renvoie "loading" pendant le chargement du document, "interactive" une fois l'analyse terminée mais charge toujours les sous-ressources, et "complete" une fois chargé.

11
T.J. Crowder

Merci à Ruslan & voici l'extrait de code complet avec le détachement pratique du gestionnaire DOMContentLoaded après utilisation.

'use strict';
var dclhandler = false;
if (document.readyState !== 'loading') {
    start();
} else {
    dclhandler = true;
    document.addEventListener('DOMContentLoaded', start);
}
function start() {
    if (dclhandler) { document.removeEventListener('DOMContentLoaded', start); }
    console.log('Start the site`s JS activities');
}
0
bob-12345