begin process at 2008 08 30 00:18:33
1 233 952 membres
470 nouveaux aujourd'hui
14 294 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

POURQUOI MES SCRIPTS AJOUTÉS DYNAMIQUEMENT (AJAX, XSLT, ...) AVEC .INNERHTML NE MARCHENT-ILS PAS ?


Information sur la source

Catégorie :Trucs & Astuces Classé sous : innerhtml, script, ajax, javascript, xslt Niveau : Initié Date de création : 12/04/2007 Date de mise à jour : 01/07/2008 21:23:05 Vu : 6 377

Note :
Aucune note

Commentaire sur cette source (12)
Ajouter un commentaire et/ou une note

Description

Sous IE, les éléments ajoutés par innerHTML ne bénéficient pas du même soutient que les autres éléments de la page...
Les ID ont tendance à être "oublié", les scripts sont toujours escamotés... bref très désagrable...

Voici ici une solution que j'ai développé pour palier le problème...

Il parait que la partie CSS (<style>) ne fonctionne pas, je dois dire que je ne l'ai jamais essayée...

Source

  • // setInnerHTML Sécurisé
  • function setInnerHTML(divContent, HTML) {
  • divContent.innerHTML=HTML;
  • try {
  • var All=divContent.getElementsByTagName("*");
  • for (var i=0; i<All.length; i++) {
  • All[i].id=All[i].getAttribute("id")
  • All[i].name=All[i].getAttribute("name")
  • // Correction pour activer les classes (plus mise à jour selon ce qui est demandé par les commentaires
  • if (!All[i].className) { All[i].className=All[i].getAttribute("class") }
  • }
  • } catch (ex) {}
  • try {
  • //if (window.external && window.ActiveXObject && window.XMLHttpRequest) { throw ("IE7 : OK"); }
  • var AllScripts=HTML.extractTags("script");
  • var Before = new Array()
  • AllScripts.forEach(function (v) {
  • for (var i=0; i<Before.length; i++) {
  • if (Before[i]==v) { return false; }
  • }
  • Before.push(v)
  • setTimeout(v,0);
  • //var script = document.createElement("script");
  • //script.innerHTML=v;
  • //document.body.appendChild(script);
  • })
  • } catch (ex) {}
  • try {
  • var AllStyles=HTML.extractTags("style");
  • AllStyles.forEach(function (v) {
  • var s=document.createStyleSheet()
  • s.cssText=v;
  • s.enabled=true;
  • }, true)
  • } catch (ex) {}
  • }
  • // EXTRAIT DE PROTOTYPE ET DE FREMYCOMPANY API FOR PROTOTYPE
  • String.prototype.extractTags=function(tag) {
  • var matchAll = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'img');
  • var matchOne = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'im');
  • return (this.match(matchAll) || []).map(function(scriptTag) {
  • return (scriptTag.match(matchOne) || ['', ''])[1];
  • });
  • }
  • Object.prototype.forEach=function(delegate, ownpropertiesonly) {
  • if (typeof(delegate)=="function") {
  • if (this instanceof Array && typeof(ownpropertiesonly)=="undefined") {
  • ownpropertiesonly=true;
  • }
  • for (key in this) {
  • var ok = (!ownpropertiesonly);
  • if (!ok) {
  • try {
  • ok=this.hasOwnProperty(key)
  • } catch (ex) {}
  • }
  • if (ok) {
  • try { delegate(this[key], key, this) } catch(e) {
  • // ...
  • }
  • }
  • }
  • }
  • return false;
  • }
  • Object.prototype.map=function(iterator) {
  • var results = [];
  • this.forEach(function(value, index) {
  • results.push(iterator(value, index));
  • });
  • return results;
  • }
            // setInnerHTML Sécurisé
            function setInnerHTML(divContent, HTML) {
                divContent.innerHTML=HTML; 
                try {
                  var All=divContent.getElementsByTagName("*");
                  for (var i=0; i<All.length; i++) {
                    All[i].id=All[i].getAttribute("id")
                    All[i].name=All[i].getAttribute("name")
                    // Correction pour activer les classes (plus mise à jour selon ce qui est demandé par les commentaires
                    if (!All[i].className) { All[i].className=All[i].getAttribute("class") }
                  }
                } catch (ex) {}
                try {
                  //if (window.external && window.ActiveXObject && window.XMLHttpRequest) { throw ("IE7 : OK"); }
                  var AllScripts=HTML.extractTags("script");
                  var Before = new Array()
                  AllScripts.forEach(function (v) {
                    for (var i=0; i<Before.length; i++) {
                        if (Before[i]==v) { return false; }
                    }
                    Before.push(v)
                    setTimeout(v,0);
                    //var script = document.createElement("script");
                    //script.innerHTML=v;
                    //document.body.appendChild(script);
                  })
                } catch (ex) {}
                try {
                  var AllStyles=HTML.extractTags("style");
                  AllStyles.forEach(function (v) {
                    var s=document.createStyleSheet()
                    s.cssText=v;
                    s.enabled=true;
                  }, true)
                } catch (ex) {}
            }

            // EXTRAIT DE PROTOTYPE ET DE FREMYCOMPANY API FOR PROTOTYPE
             
            String.prototype.extractTags=function(tag) {
                var matchAll = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'img');
                var matchOne = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'im');
                return (this.match(matchAll) || []).map(function(scriptTag) {
                  return (scriptTag.match(matchOne) || ['', ''])[1];
                });
              }
             
            Object.prototype.forEach=function(delegate, ownpropertiesonly) {
                    if (typeof(delegate)=="function") {
                        if (this instanceof Array && typeof(ownpropertiesonly)=="undefined") {
                            ownpropertiesonly=true;
                        }
                        for (key in this) {
                            var ok = (!ownpropertiesonly);
                            if (!ok) {
                                try {
                                    ok=this.hasOwnProperty(key)
                                } catch (ex) {}
                            }
                            if (ok) {
                                try { delegate(this[key], key, this) } catch(e) {
                                    // ...
                                }
                            }
                        }
                    }
                    return false;
                }
             
            Object.prototype.map=function(iterator) {
                var results = [];
                this.forEach(function(value, index) {
                  results.push(iterator(value, index));
                });
                return results;
              }

Conclusion

Bon après qques corrections, le code fonctionne sans problème !
Utilisation :
setInnerHTML(document.getElementById('ID'), '<script>alert("ok")<\/script><style>body { background-color: royalblue; }<\/style>"');
12 avril 2007 20:48:12 :
Corrige le problème de la contrainte n° 1 !
13 avril 2007 18:50:29 :
Correction d'un bug qui faisait mal fonctionner le script sous IE
13 avril 2007 18:54:51 :
Exemple d'utilisation
01 juillet 2008 21:23:05 :
Voir commentaires
  • signaler à un administrateur
    Commentaire de FREMYCOMPANY le 12/04/2007 18:26:06

    Deux contraintes :
    - Les scripts avec SRC ne sont pas évalués
    - Les scripts doivent déclarer les fonctions "window.maFunction=function() { ... }" et non pas "function maFunction() { ... }"

  • signaler à un administrateur
    Commentaire de f6xara le 12/04/2007 18:38:23

    Pour que le javascript soit éxecuter dans l ajax, il faut faire un eval sur les balises script.
    Object.prototype.evalScripts = function(text){
    var script, regexp = /<script[^>]*>([\s\S]*?)<\/script>/gi;
    while ((script = regexp.exec(this.text))) eval(script[1]);
    }

  • signaler à un administrateur
    Commentaire de FREMYCOMPANY le 12/04/2007 18:49:59

    Ben pas nécéssairement...
    Regarde ma fonction setInnerHTML se débrouille sans...

  • signaler à un administrateur
    Commentaire de etiennexxx9 le 14/04/2007 03:36:37

    Salut,

    Une autre façon d'inclure un script à une page, est de l'ajouter dynamiquement au tag head.
    Voici une petite fonction qui montre comment faire:

    function IncludeScript(Filename)
    {
    var script = document.createElement('script');
    script.setAttribute('src', Filename);
    script.setAttribute('type', 'text/javascript');
    document.getElementsByTagName('head')[0].appendChild(script);
    }

    Pour inclure un script avec le code directement dans le tag, je ne l'ai jamais fait dynamiquement.

    Etienne

  • signaler à un administrateur
    Commentaire de FREMYCOMPANY le 14/04/2007 15:00:21

    Si ca marche, tant mieux... Ca me semble même plus propre mais le problème est qu'avec AJAX on doit choisir... Eval de JavaScript ou InnerHTML... Or parfois on voudrais faire les deux, d'où mon script... mais en effet, si on veut juste ajouter un script au document, c'est lourd inutilement...

  • signaler à un administrateur
    Commentaire de iocha le 11/09/2007 21:22:24

    Salut à tous
    Pourquoi les class ne sont-elles pas interprétées ???

  • signaler à un administrateur
    Commentaire de Steph115 le 23/10/2007 23:40:42

    Bonjour,

    Merci pour ce script effectivement les classes ne marches pas.

    @f6xara
    Comment utilise tu ton exemple ?
    Marche t-il avec les css ?

    Merci à vous tous,

  • signaler à un administrateur
    Commentaire de Steph115 le 24/10/2007 00:11:41

    Hey Hey Hey

    J'ai trouvé la solution :):):)

    En fait il suffit tout simplement de commenter la ligne
    All[i].className=All[i].getAttribute("class");

    Moi ca marche sous IE7 et Firefox

    ATTENTION
    Pour ceux qui inclut déjà prototype (prototype lui meme ou dérivé exemple:scriptaculous)
    vous devez enlever les deux dernieres fonctions Object.prototype

    Voici mon code final :

    // setInnerHTML Sécurisé
    function setInnerHTML(divContent, HTML) {
    divContent.innerHTML=HTML;
    try {
    var All=divContent.getElementsByTagName("*");
    for (var i=0; i<All.length; i++) {
    All[i].id=All[i].getAttribute("id")
    All[i].name=All[i].getAttribute("name")
    //All[i].className=All[i].getAttribute("class")
    }
    } catch (ex) {}
    try {
    var AllScripts=HTML.extractTags("script");
    AllScripts.forEach(function (v) {
    eval(v);
    })
    } catch (ex) {}
    try {
    var AllStyles=HTML.extractTags("style");
    AllStyles.forEach(function (v) {
    var s=document.createStyleSheet()
    s.cssText=v;
    s.enabled=true;
    }, true)
    } catch (ex) {}
    }

    String.prototype.extractTags=function(tag) {
    var matchAll = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'img');
    var matchOne = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
    return (scriptTag.match(matchOne) || ['', ''])[1];
    });
    }


    Cordialement,

  • signaler à un administrateur
    Commentaire de Steph115 le 24/10/2007 00:29:47

    Après d'autres tests
    (je sais ce n'est pas bien il aurait fallu tester depusi le début, mais on ne vois pas tout :))

    Voici le script qui marche sous IE et Firefox
    Je rajoute Object.prototype uniquement si on est sous IE
    ATTENTION je précise bien que pour mon cas j'inclus protoype.js dans toutes mes pages
    donc je suis obligé de faire ce test car sinon firefox ne peut pas redeclarer une deuxieme dois les deux fonctions.

    // setInnerHTML Sécurisé
    function setInnerHTML(divContent, HTML) {
        divContent.innerHTML=HTML;
        try {
          var All=divContent.getElementsByTagName("*");
          for (var i=0; i<All.length; i++) {
            All[i].id=All[i].getAttribute("id")
            All[i].name=All[i].getAttribute("name")
            //All[i].className=All[i].getAttribute("class")
          }
        } catch (ex) {}
        try {
          var AllScripts=HTML.extractTags("script");
          AllScripts.forEach(function (v) {
            eval(v);
          })
        } catch (ex) {}
        try {
          var AllStyles=HTML.extractTags("style");
          AllStyles.forEach(function (v) {
            var s=document.createStyleSheet()
            s.cssText=v;
            s.enabled=true;
          }, true)
        } catch (ex) {}
    }

    String.prototype.extractTags=function(tag) {
        var matchAll = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'img');
        var matchOne = new RegExp('(?:<'+tag+'.*?>)((\n|\r|.)*?)(?:<\/'+tag+'>)', 'im');
        return (this.match(matchAll) || []).map(function(scriptTag) {
          return (scriptTag.match(matchOne) || ['', ''])[1];
        });
      }

    //Detect IE5.5+
    version=0;
    if(navigator.appVersion.indexOf("MSIE")!=-1)
    {
    temp=navigator.appVersion.split("MSIE");
    version=parseFloat(temp[1]);
    }
    // NON IE browser will return 0
    if(version>=5.5)
    {
    Object.prototype.forEach=function(delegate, ownpropertiesonly) {
        if (typeof(delegate)=="function") {
            if (this instanceof Array && typeof(ownpropertiesonly)=="undefined") {
                ownpropertiesonly=true;
            }
            for (key in this) {
                var ok = (!ownpropertiesonly);
                if (!ok) {
                    try {
                        ok=this.hasOwnProperty(key)
                    } catch (ex) {}
                }
                if (ok) {
                    try { delegate(this[key], key, this) } catch(e) {
                        // ...
                    }
                }
            }
        }
        return false;
    }

    Object.prototype.map=function(iterator) {
        var results = [];
        this.forEach(function(value, index) {
          results.push(iterator(value, index));
        });
        return results;
    }
    }

    Cordialement,
    Stéphanos

  • signaler à un administrateur
    Commentaire de MaX3315 le 21/07/2008 08:51:40

    Si ca peut servire à d'autre qui sont confronter à ce type de problème il y a aussi une autre solution pour l'insertion et l'execution de javascript via ajax.

    Il suffit d'ajouter à notre code html à insérer via innerHTML une image avec l'attribut onload=""

    Exemple:
    <img src="spacer.gif" onload="document.maVariable=true;
    function maFonction(aEvent)
    {
      if(document.maVariable) { alert(true); }
    }
    Event.observe('unId','click',maFonction);
    />

    Par exemple.

    Cela fonctionne sous IE6/7 et sous Firefox 2/3.

    C'est peut-être une méthode un peu plus directe pour insérer du code HTML avec javascript à interpréter.

  • signaler à un administrateur
    Commentaire de FREMYCOMPANY le 21/07/2008 10:34:17

    @MAX : Pas mal comme solution. C'est toujours à retenir !

  • signaler à un administrateur
    Commentaire de HighSoul le 04/08/2008 15:24:03

    J'ai utilisé la solution de MAX3315 et ça marche nickel aussi sur Safari.

    Merci pour cette solution lumineuse...

Ajouter un commentaire

Pub



Appels d'offres

Recherche developpeur ...
Budget : 700€
SITE MARCHAND LOCATION...
Budget : 3 000€
SITE MARCHAND POUR HOTEL
Budget : 4 000€

CalendriCode

Août 2008
LMMJVSD
    123
45678910
11121314151617
18192021222324
25262728293031

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS