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 : 7 772

Note :
Aucune note

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

Description

Cliquez pour voir la capture en taille normale
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>"');
 

Historique

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

Commentaires et avis

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

signaler à un administrateur
Commentaire de Socki le 12/05/2009 11:58:30

Bonjour,
J'ai une question, quelles sont les fonctions associées à innerHTML?
merci

Socki

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Bug de Javascript ? InnerHTML [ par DuncanIdaho ] Bonjour; J'ai cherché un bon moment, sur Internet, en créant quelques fonctions...  Au final, je n'arrive pas à comprendre mon problème, ou en tout JavaScript : Utiliser InnerHTML pour changer le contenu d'une balise [ par jeanMOULIN54 ] Bonjour à tous, voilà j'ai utilisé un script trouvé sur le site http://www.journaldunet.com/developpeur/tutoriel/dht/040512-javascript-innerhtml-l Stage bidon, aucune connaissance. Besoin d'aide :< [ par Creature_Funebre ] Bonjour, J'ai poste ici il y a quelques jours pour un projet de stage. Je me devais de faire un script VBScript inclut dans une page web, ce qui perme Stage bidon, aucune connaissance. Besoin d'aide :< [ par Creature_Funebre ] Bonjour, J'ai poste ici il y a quelques jours pour un projet de stage. Je me devais de faire un script VBScript inclut dans une page web, ce qui perme Effacer tag script [ par cucrapock ] Bonjour à tous,je réalise un petit server control avec une partie javascript côté client. Cette dernière créée dynamiquement des tag &lt;script&gt; vi javascript [ par nicodu94 ] Bonjours a tous,Je suis débutant en language web. J'ai un peu étudier html css, et je suis bloqué pour apprendre javascript.Dans dreamweaver  j'arrive Prolbème javascript et firefox [ par coty2 ] Bonsoir à tous!j'ai un petit souci avec un javascript que j'ai confectionné.. ilest un peu beaucoup bancale.. mais bon! Donc explication! sous IE pas Internet explorer et la recupération de function javascript [ par banbanfr ] Bonjour à tous,Voilà j'ai un petit problème existentiel. lolJe bosse sur un projet qui est tout en AJAX et drag n drop jusque là tout va bien.Mon prog problème javascript - XML [ par iraho ] Bonjour, j'ai un souci avec pour faire du xml dynamique avec javascript et j'aurais besoin d'aide. En fait, j'ai code associant xml, xslt et javascrip ajax et php [ par tales ] Bonjour,J'utilise le script ajax suivant :Code : JavaScript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

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

Comparez les prix Nouvelle version


LG KP501

Entre 9€ et 159€


Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,952 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.