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

jQuery Discussion :

$.getScript() après $.load() [AJAX]


Sujet :

jQuery

  1. #1
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut $.getScript() après $.load()
    Bonjour à tous,

    Je voudrais charger en AJAX un contenu HTML dans ma page, puis une fois le contenu HTML ajouté, exécuter un script lui aussi chargé en AJAX. Ma première approche fût d'utiliser les fonctions $.load et $.getScript.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $("#container").load("page.html", function(){ $.getScript("script.js"); });
    Cela fonctionne mais n'est pas très optimisé: le chargement du script se fait une fois la page HTML chargée, alors que les deux requêtes pourraient se faire en parallèle. Je sais que certaines librairies comme headJS parviennent à charger des choses en parallèle tout en conservant l'ordre d'exécution correct. Sauriez-vous quel mécanisme est utilisé pour cela ?

    J'ai une solution de secours qui est de charger tous mes scripts en AJAX au démarrage puis d'appeler des callbacks propres à chaque page, mais je voudrais trouver quelque-chose de mieux.

    Merci de partager votre savoir
    One Web to rule them all

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Points : 22 933
    Points
    22 933
    Billets dans le blog
    125
    Par défaut
    Bonsoir

    $.getScript() charge et exécute un script. Si le contenu de "page.html" est concerné par le fonctionnement du script, ton approche est optimale. Même requirejs ne fera pas mieux.

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Non, ce qui serait optimal serait de lancer toutes les requêtes XHR au même moment, de stocker les réponses temporairement et de dépiler dans l'ordre une fois toutes les requêtes finies. C'est ce que font les librairies comme head.js ou LABjs ; et ça peut réduire considérablement le temps de chargement total comparé à un chargement l'un après l'autre. C'est même plus rapide de charger un ensemble de JS en parallèle plutôt que de charger un seul JS concaténé.

    Je pense avoir une petite idée: charger en AJAX le script, stocker xhr.responseText dans un élément <script> et ajouter le script à la page après l'insertion du HTML issu de la seconde requête. Mais je dois encore réfléchir à comment faire ça qu'importe l'ordre dans lequel aboutissent les requêtes. Si quelqu'un voit une façon simple de faire ça, je suis preneur.
    One Web to rule them all

  4. #4
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    Je suis parvenu à faire ce que je souhaitais :

    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
    29
     
    $.fn.loadWithScript = function(html_url, js_url){
        var pageLoaded = false, scriptLoaded = false;
        var scriptText;
        jQuery.ajax({
            type: 'GET',
            url: js_url,
            success: function(text){
                scriptText = text;
                scriptLoaded = true;
                if(pageLoaded) runScript();
            },
            dataType: 'text',
            cache: true
        });
     
        function runScript(){
            var script = document.createElement("script");
            script.text = scriptText;
            document.head.insertBefore(script, document.head.firstChild);
        }
     
        $.fn.load.call(this,html_url,function(){
            pageLoaded = true;
            if(scriptLoaded) runScript();
        });
    };
     
    $("#container").loadWithScript("page.html", "js/test.js");
    Bon le code est loin d'être parfait, je ne reprends pas tous les arguments de load et je perds le mapping source du script en chargeant dans un nouvel élément script en inline. Mais bon ça fait le job pour le moment.
    One Web to rule them all

  5. #5
    Rédacteur/Modérateur

    Avatar de SylvainPV
    Profil pro
    Inscrit en
    Novembre 2012
    Messages
    3 375
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2012
    Messages : 3 375
    Points : 9 944
    Points
    9 944
    Par défaut
    J'ai été amené à retravailler le script pour overrider la fonction $.fn.load de jQuery. Ca donne ceci :
    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
     
    (function(d,e,j){$.fn.load=function(url,o,cb){
        var p,q=[],c=o, h, f=function(){ $.each(q,function(i,s){ if(h&&s)$('head').append(s)}) };
        if(!$.isFunction(o)){ c=cb; }
        p=$.isArray(o.js)?o.js:o.js?[o.js]:[];
        o=o.data||null;
        cb=function(){ h=true; f(); c.apply(this,arguments); };
        $.each(p,function(i,u){
            $.ajax({type:"GET",dataType:"text",url:u,complete:function(x){
                var s=d.createElement(e); s.text=x.responseText; q[i]=s; f();
            }});
            q[i]=null;
        });
        j.call(this,url,o,cb);
    }})(document,'script', $.fn.load);
    Usage:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $("#container").load("page.html",{ data: { foo: "bar" }, js:["js/script1.js","js/script2.js"] });
    Si ça peut aider quelqu'un qui cherche une implémentation rapide.
    A+
    One Web to rule them all

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [ComboBox] Ajout d'un record après load
    Par nikko49 dans le forum Ext JS / Sencha
    Réponses: 3
    Dernier message: 14/11/2013, 13h04
  2. Réponses: 2
    Dernier message: 05/02/2013, 13h39
  3. [AJAX] JS ne fonctionne plus après .load()
    Par Spire_ dans le forum jQuery
    Réponses: 11
    Dernier message: 29/10/2012, 14h31
  4. [Débutant] champs textbox se vide après load
    Par Serico dans le forum VB.NET
    Réponses: 1
    Dernier message: 12/06/2012, 13h46
  5. Remettre sur écoute fancybox après .load()
    Par cleecky dans le forum jQuery
    Réponses: 4
    Dernier message: 10/11/2011, 12h21

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