web-dev-qa-db-fra.com

Attendez que le document soit prêt dans les modules ES6

Avec le levage, les modules ES6 sont chargés avant que le document ne soit prêt.

Par exemple,

// module.js
console.log('body', document.body);
export let a = 1;

// main.js
import {a} from 'module'

log body null dans la console.

Comment avoir des modules ES6 utilisant la manipulation DOM et requis document ready?

J'ai essayé d'utiliser 

$(document).ready(function() {
  var a = 1;
});

export {a};

dans mon module mais babel m'a renvoyé une erreur Unexpected token.

J'ai aussi essayé

$(document).ready(function() {
  export let a = 1;
});

et j'ai eu une erreur 'import' and 'export' may only appear at the top level.

Mettre à jour:

J'ai le même problème avec

document.addEventListener("DOMContentLoaded",function(){
  var a = 1;
}

export {a};

parce que a n'est pas défini.

c'est-à-dire que les variables à exporter ne sont pas disponibles (voir ma mise à jour).

Mettre à jour:

Voici ma tentative basée sur le code @MaciejSikora:

function Test() {

   document.addEventListener("DOMContentLoaded",()=>{
      this.width = $(window).width();
   });

};

//example object method
Test.prototype.getElement = function(el) {
   return this[el];

};


export { Test };

Dans un autre dossier je fais

var test = new Test();
var width = test.getElement('width');

Mais width n'est pas défini.

12
hadrienj

DOM n’a pas changé dans ES6, ES6 donne de nouvelles fonctionnalités à JavaScript, c’est tout . En pure js existe, événement pour dom chargé (c’est un document prêt de jquery équivalent):

document.addEventListener("DOMContentLoaded",function(){

    //here code
});

Les modules fonctionnant avec l’arborescence DOM peuvent avoir un auditeur à l’intérieur ou doivent être utilisés une fois que dom est prêt . J'ai créé l'exemple DomManipulate pour montrer ce que je veux dire:

var DomManipulate=function(selector){

   document.addEventListener("DOMContentLoaded",()=>{

      this.element=document.querySelector(selector);

      if (typeof this.callback === 'function')
      this.callback();

   });

};

//HERE WE HAVE CALLBACK WHEN OUR MODULE CAN BE USED
DomManipulate.prototype.onReady=function(callback){

    this.callback=callback;

};

DomManipulate.prototype.getElement=function(){
    //example object method

   return this.element;

};

DomManipulate.prototype.write=function(text){

   return this.element.innerText=text;

};


export { DomManipulate };

C'est donc une meilleure approche et nous avons un composant encapsulé.

Exemple d'utilisation:

var d=new DomManipulate("#test");
d.onReady(()=>{d.write("Test text");});

Les modules doivent être indépendants du DOM, la création de modules exportant directement des éléments DOM est une pratique très fausse. Donc, cela peut être fait de deux manières:

  1. Les modules doivent avoir les sélecteurs objet DOM dans les attributs et doivent être appelés une fois que DOM est prêt. Donc, votre module n'a aucune idée de l'endroit où il est appelé, mais il a besoin d'une structure prête pour le DOM. Dans cette situation, le rappel DOM ready est uniquement dans le fichier principal qui utilise des modules et les appelle.

  2. Les modules peuvent avoir des écouteurs prêts pour le DOM, mais nous avons aussi besoin d'informations lorsque le module peut être utilisé (cette situation est illustrée dans l'exemple et la fonction onReady).

12
Maciej Sikora

Essayez de placer votre balise <script> au bas de <body/>. En faisant cela, document.body sera disponible et ne générera pas d'erreur.

5
Pranesh Ravi

Si le script est au bas de la page, alors dom est déjà chargé, inutile donc de 'DOMContentLoaded'. Ou?

0
nimo23