IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[DOM] Include en JS


Sujet :

JavaScript

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut [DOM] Include en JS
    Bonjour à tous,
    Je viens vers vous avec un soucis que je ne parviens pas à régler meme en "googlelisant" à fond...j'ai bien peur que la solution n'existe pas, mais au cas ou je préfère quand meme demander votre avis...


    Voila, dans le cadre du developpement d'un mini framework JS, je me refuse à includer systématiquement une ribambelle de fichier JS (1 par type de composants) dans chacun des mes fichiers HTML.

    Ce que je veux, c'est avoir une seul balise script pointant vers un fichier "engine.js" et que ce soit celui-ci qui include (ou non) les composant (fichier js) dont la page à besoin

    Ca parait compliqué, mais je m'y retrouve et tout fonctionne bien à un (gros) détail près.

    En effet, ma fonction pour includer utiliser le DOM pour créer une nouvelle balise de type "script" puis lui affecter un type (text/javascript) et un src (chemin vers le js en question).

    Le soucis, c'est que quand j'utilise cette fonction, bien que le script soit bien ajouté à l'arbre DOM (en mettant en simple alert() en début du fichier à includer, on voit bien que le script est interprété puisque l'alert apparait à l'execution), les fonctions déclarées dans le JS includé ne sont pas directement accessible. Il me faut sortir de la fonction ayant fait l'include avant qu'elle ne soient accessible.

    pour illustrer un peu voici 2 petits exemples:


    ce qui marche po:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
     
       <html>
         <head
           <script type='text/javascript'>
     
                  function include(sFilePath) {
     
                      var oScript = document.createElement('script');
                      oScript.type = 'text/javascript';
                      oScript.src = sFilePath;
                      document.getElementsByTagName('heade')[0].appendChild(oScript);
     
                  }
     
                  function test() {
     
                        include('monfichier.js');
                        fonctiondansmonfichier();
     
                  }
     
            </script>
          </head>
          <body>
                 <input type='button' OnClick='test();'>
          </body>
    </html>
    ce qui marche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
     
       <html>
         <head
           <script type='text/javascript'>
     
                  function include(sFilePath) {
     
                      var oScript = document.createElement('script');
                      oScript.type = 'text/javascript';
                      oScript.src = sFilePath;
                      document.getElementsByTagName('heade')[0].appendChild(oScript);
     
                  }
     
                  function test() {
     
                        include('monfichier.js');
     
                  }
     
            </script>
          </head>
          <body>
                 <input type='button' OnClick='test();'>
                 <input type='button' OnClick='fonctiondansmonfichier();'>
          </body>
    </html>

    Voila, bah si quelqu'un pouvait me dire comment faire en sorte de pouvoir dierctement utiliser les fonctions ajouter ainsi ca m'arrangerait très beaucoup [smile]

    merci d'avoir lut jusqu'au bout en tous cas

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Lorsqu'une fonction javascript est lancée, elle récupère le contexte javascript actuel (variables, fonctions, environnement...) donc, quand tu appelles ta fonction include, le futur script ne fait pas partie du contexte javascript et ne pourra donc être accessible (comme tu le faisais remarquer) qu'après être sorti de la fonction.
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    merci de ta réponse.

    c'est bien ce que je pensais....mais dans ce cas, ai-je une possibilité de faire un include + l'executer d'une fonction includer sans intervention de l'utilisateur ? (car à ma connaissance, la seule facon de "sortir" du contexte c'est d'arréter le script et d'attendre que l'utilisateur fasse une action....ou éventuelement lancer un setTimeout pointant vers ma fonction externe, mais c'est très moche

  4. #4
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Bonjour,
    heade ?

    Ca n'existe pas, ça ...

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Alors oui j'ai fais une faute de frappe en mettant "heade" à la place de "head". Seulement les fonctions que je vous ai donner ne sont pas celle qui j'utilise, j'ai juste tenter d'isoler le plus important pour la compréhension du problème en écrivant ces fonctions au moment ou j'ai rédiger ce sujet.

    A force de chercher sur ce problème, j'ai fini par comprendre ce qu'il se passe, sauf pour autant savoir comment y remédier:
    En Javascript, lorsqu'on appelle une fonction (ou qu'un évènement utilisateur intervient), un contexte d'exécution est créé. La autres fonctions des différents scripts (ainsi que les variables globales, etc.) sont copiés comme propriété de l'objet "contexte" (qu'on peut utiliser via la variable "this" que vous connaissez surrement). Lorsque ma fonction ajoute le script externe à l'arbre DOM, le contexte n'est pas mit à jour, ce qui explique que les fonctions déclarées dans mon script externe ne sont pas connu par le contexte de la fonction appelante. Il n'y à que lorsque qu'une nouvelle fonction sera appeller (par un événement utilisateur ou éventuellement un setTimeout) qu'un nouveau contexte sera créer et que les nouvelles fonctions serons accessible.
    En gros, il faudrait que je puisse demander à l'interpréteur JS du navigateur de recharger le contexte d'execution de la fonction....mais je cherche encore comment faire (si toutes fois cela est possible)

    merci en tous cas pour ta réponse

  6. #6
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par E.Bzz Voir le message
    Bonjour,
    heade ?

    Ca n'existe pas, ça ...

    A+
    pas faux ça !
    Et tant qu'à faire, fermer la balise <head> peut aussi s'avérer utile
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    heu....les bouts de code que je vous ai donner, je les ai écris au moment de la redaction du sujet...ils ne sont pas tester et sont encore moins un copier/coller de mes codes de developpement, ils ne sont là que pour clarifier les choses, si j'avais dû vous donner l'intégralité de mes codes mon poste aurait fait 3km de long....l'important était de vous faire comprendre mon problème via un petit exemple plutot que m'étendre en un long texte....

    sans compter qu'avec les fautes de frappe que j'ai fais en rédigeant ces petits exemple, à l'execution, rien n'aurait fonctionner du tout...je n'aurai donc pas poster avec un problème aussi précis que le mien

  8. #8
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Citation Envoyé par nihaoma Voir le message
    ou éventuelement lancer un setTimeout pointant vers ma fonction externe, mais c'est très moche
    Ben oui, mais ça réglerait visiblement le problème.

    ... à moins de privilégier l'esthétique du code par rapport au résultat fonctionnel

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    ce n'est pas tant un soucis esthétique (quoi que cela est pour moi une certaine importance), c'est plus une question de phylosophie...lancer un évènement que tu ne maitrisera plus (et donc utiliser de la mémoire, occuper le listener et le parser) juste pour lancer l'execution d'une fonction ca me parrait moyen....

    mais effectivement, si vraiment il n'y à pas d'autre solution, j'y passerai, c'est juste que je ne trouve pas que ce soit du code propre et que je préfère perdre un peu de temps à trouver des solutions valides et "W3C compliant" plutot que le première bout de scotch qui me passe sous la main

  10. #10
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Citation Envoyé par nihaoma Voir le message
    je préfère perdre un peu de temps à trouver des solutions valides et "W3C compliant" plutot que le première bout de scotch qui me passe sous la main
    Le problème est peut être qu'avec ta solution actuelle, tu marches déjà sur la limite

    Dans l'absolu, déterminer les include JS à fournir au client en fonction de ses besoins pourrait (devrait ??) être fait par le serveur avant d'envoyer le tout au client.

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  11. #11
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 220
    Points
    91 220
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par E.Bzz Voir le message
    Le problème est peut être qu'avec ta solution actuelle, tu marches déjà sur la limite

    Dans l'absolu, déterminer les include JS à fournir au client en fonction de ses besoins pourrait (devrait ??) être fait par le serveur avant d'envoyer le tout au client.

    A+
    Encore une fois, on ne peut qu'approuver ta remarque
    Sinon, peut-être une solution (à tester) :
    Créer une fonction à part que tu appelles après l'inclusion de ton script et qui prend en paramètre le nom de ta fonction et qui lui-même l'appelle ???
    Du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function test() {
                        include('monfichier.js');
                        test2('fonctiondansmonfichier()');
                  }
    function test2(fonction){
        eval(fonction);
    }
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  12. #12
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    J'ai peur que ça ne permette pas de se débarrasser du contexte initial (celui de test() ).

    Par contre, pourquoi cette fonction test() ?

    Si c'est au chargement de la page, pourquoi pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <head>
           <script type='text/javascript'>
                  function include(sFilePath) {
     
                      var oScript = document.createElement('script');
                      oScript.type = 'text/javascript';
                      oScript.src = sFilePath;
                      document.getElementsByTagName('head')[0].appendChild(oScript);
     
                  }
     
    include('monfichier.js');
    fonctiondansmonfichier();
    </script>
    Ici, include('monfichier.js') et fonctiondansmonfichier() auront chacun leur contexte. Celui de la 2° tenant compte des modif de la 1°.

    Non ?

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par E.Bzz Voir le message
    Le problème est peut être qu'avec ta solution actuelle, tu marches déjà sur la limite

    Dans l'absolu, déterminer les include JS à fournir au client en fonction de ses besoins pourrait (devrait ??) être fait par le serveur avant d'envoyer le tout au client.

    A+

    dans l'absolue oui, sauf si on parle d'un framework en standalone, un outil ne necessitant pas de serveur...

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 39
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par E.Bzz Voir le message
    J'ai peur que ça ne permette pas de se débarrasser du contexte initial (celui de test() ).

    Par contre, pourquoi cette fonction test() ?

    Si c'est au chargement de la page, pourquoi pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <head>
           <script type='text/javascript'>
                  function include(sFilePath) {
     
                      var oScript = document.createElement('script');
                      oScript.type = 'text/javascript';
                      oScript.src = sFilePath;
                      document.getElementsByTagName('head')[0].appendChild(oScript);
     
                  }
     
    include('monfichier.js');
    fonctiondansmonfichier();
    </script>
    Ici, include('monfichier.js') et fonctiondansmonfichier() auront chacun leur contexte. Celui de la 2° tenant compte des modif de la 1°.

    Non ?

    A+
    déja essayer, non le contexte sera ici le contexte dit "global" qui sera rechargé une fois tout le code ne faisant pas parti d'une fonction executé.

  15. #15
    Membre expérimenté Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Points : 1 388
    Points
    1 388
    Par défaut
    le futur script ne fait pas partie du contexte javascript et ne pourra donc être accessible (comme tu le faisais remarquer) qu'après être sorti de la fonction.
    C'est pas vrai ca.

    Le problème que tu rencontres n'est pas un problème de contexte mais simplement d'asynchronisme. Ce qui ce passe c'est que quand tu fais le appendChild de ton script, le fichier ciblé par ton .src n'est pas chargé encore, donc forcément, les instructions immédiatement suivantes ne pourront pas utiliser les fonctions décrites dans ce fichier.

    1ere solution:
    L'objet DOM script possède une méthode (onreadystatechange pour IE, et onchange pour FF (ou l'inverse, je sais plus) qui permet de vérifier, comme en ajax, l'état d'avancement du chargement. En l'utilisant, tu peux faire que les instructions qui doivent suivre le chargement soient bien appelées une fois celui ci fini. Par exemple, comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    function include(sFilePath, onComplete)
    {
       // ...
       scr.onload= function()
      {
          onComplete(); // la fonction qui contient tout ce que tu veux faire apres le chargement de ton script
      }
    }
    Plus de précisions ici

    2e solution:
    La méthode précédente ne marche pas sous safari je crois, donc il faut faire autrement si tu as besoin de la compatibilité avec ce navigateur. L'idée est simple: tu fais une requete Ajax sur le script à charger, et tu ajoutes le contenu du xhr.responseText à la propriété innerHTML de ton script. Tu n'as plus ensuite qu'a appeler la fonction onComplete comme dans l'exemple précédent.

  16. #16
    Expert éminent sénior

    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    13 474
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2007
    Messages : 13 474
    Points : 36 571
    Points
    36 571
    Par défaut
    Merci pour ces précisions qui tombent à point, DoubleU

    A+
    Pour tout savoir sur l'utilisation du forum

    En postant votre message, n'oubliez pas les Règles du Club.

  17. #17
    Expert confirmé
    Avatar de le_chomeur
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2006
    Messages
    3 653
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 3 653
    Points : 4 835
    Points
    4 835
    Par défaut
    source trouvée sur le net :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    var js;
    function include_js(file) {
        var html_doc = document.getElementsByTagName('head').item(0);
        js = document.createElement('script');
        js.setAttribute('type', 'text/javascript');
        js.setAttribute('src', file);
        html_doc.appendChild(js);
     
        // alert state change
        js.onreadystatechange = function () {
            alert(js.readyState);
     
            if (js.readyState == 'complete') {
                // safe to call a function
                // found in the new script
                imready();
            }
        }
        return false;
    }
    source originale : http://www.phpied.com/category/javascript/page/3/

    la démo : http://www.phpied.com/files/jinc/test_ready.html
    est ton ami fait gagner du temps à ceux qui aident , donc un message avec la balise résolu laisse plus de temps pour résoudre d'autres problèmes

    Premier ministre du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts )

Discussions similaires

  1. #include "math.h" et #include <math.h>
    Par pounka dans le forum C
    Réponses: 4
    Dernier message: 01/05/2003, 21h06
  2. XML DOM et gros fichiers
    Par Manu_Just dans le forum APIs
    Réponses: 4
    Dernier message: 28/03/2003, 09h50
  3. [DOM/SAX]Choix...
    Par miss8 dans le forum APIs
    Réponses: 4
    Dernier message: 17/03/2003, 18h37
  4. pb formatage document XML généré par un dom tree
    Par lionel69 dans le forum APIs
    Réponses: 11
    Dernier message: 17/10/2002, 09h53
  5. Réponses: 3
    Dernier message: 04/09/2002, 09h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo