Pourquoi mes scripts ajoutés dynamiquement (ajax, xslt, ...) avec .innerhtml ne marchent-ils pas ?

Soyez le premier à donner votre avis sur cette source.

Snippet vu 11 475 fois - Téléchargée 19 fois

Contenu du snippet

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 / Exemple :


// 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>"');

A voir également

Ajouter un commentaire

Commentaires

Socki
Messages postés
15
Date d'inscription
lundi 27 avril 2009
Statut
Membre
Dernière intervention
12 mai 2009
-
Bonjour,
J'ai une question, quelles sont les fonctions associées à innerHTML?
merci

Socki
HighSoul
Messages postés
1
Date d'inscription
lundi 13 décembre 2004
Statut
Membre
Dernière intervention
4 août 2008
-
J'ai utilisé la solution de MAX3315 et ça marche nickel aussi sur Safari.

Merci pour cette solution lumineuse...
FREMYCOMPANY
Messages postés
278
Date d'inscription
jeudi 12 janvier 2006
Statut
Membre
Dernière intervention
22 décembre 2008
-
@MAX : Pas mal comme solution. C'est toujours à retenir !
cs_MaX3315
Messages postés
170
Date d'inscription
mercredi 18 juin 2003
Statut
Membre
Dernière intervention
11 mai 2009
-
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:

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.
Steph115
Messages postés
163
Date d'inscription
mercredi 22 octobre 2003
Statut
Membre
Dernière intervention
3 février 2012
-
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)((\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

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.