11550 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

J'essaye d'insérer dynamiquement du contenu (avec un script) dans un élément existant, comme une balise div identifié par son attribut id. Ça marche parfaitement si le contenu inséré est du code HTML. Maintenant si j'insère, par exemple :
<script src="URL-DU-SCRIPT" type="text/javascript></script>
Ou encore :
<script type="text/javascript">alert('Je suis un script');</script>
Le script en question n'est pas chargé par le navigateur.

Vous avez une idée ?

Merci
Salut.

J'ai pas bien compris quel est ton problème donc si tu pouvais mettre un bout de ton code ça nous aiderai ...
D'accord - je montre un exemple concret : démonstration. (en haut du menu à droite, vous avez un bouton insérer / retirer le script)

Sous Firefox, en sélectionnant les deux phrases qui apparaissent, et en regardant le code source de la sélection, vous vous apercevrez qu'un script est placé entre les deux paragraphes.

Pourtant, il n'est pas exécuté, alors que c'est bien le but recherché.

J'utilise simplement la propriété innerHTML pour remplir le contenu de ma div. Si cela vous semble utile, voici le script en question (utilisez le UTF-8), plus précisemment il s'agit de cette fonction :
function notEvilAdsPrintElement(id)
{
	if (document.getElementById(id))
	{
		notEvilAds_xmlhttp.open("POST",notEvilAds_xmlresponsefile,false);
		notEvilAds_xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		notEvilAds_xmlhttp.send("notEvilAdsGetId="+id);
		document.getElementById(id).innerHTML = notEvilAds_xmlhttp.responseText;
	}
}

Modifié par Digimag (24 Aug 2007 - 10:29)
CNeo a écrit :
Puisque tu as une fonction qui affiche et masque les phrases il suffit de mettre le "alert" dedans ...
Oui, pas con, mais le but n'est pas de mettre un alert(), le but est de faire un plugin pour Dotclear permettant à chacun d'insérer le code qu'il souhaite, y compris le JavaScript, pour afficher du contenu désactivable par le visiteur.
Yop,

Essaie d'ajouter tes scripts avec un document.write() placé au bon endroit plutot que de passer par le innerHTML pour voir
En effet, le problème du document.write c'est qu'il doit figurer au bon endroit sur la page pour fonctionner. Du coup, impossible d'ajouter quelque chose au sein de la page une fois que le document a été chargé (or c'est le but, le code à afficher est récupéré par XMLHttpRequest).

Et...

Je suis enfin arrivé à faire exécuter du JavaScript en utilisant la méthode append() propre à jQuery, qui effectue un appendChild().

Mais...

Nous tombons dans le problème que je viens de décrire : si le code JavaScript inséré utilise un document.write (c'est le cas du code fourni par Google Adsense), alors que la page a déjà été chargée, c'est le contenu de la page entière qui est remplacé par le texte contenu dans le document.write.

Je ne vois alors qu'une solution : falsifier temporairement l'objet document pour que document.write() pointe sur un élément div par exemple... Savez-vous comment faire ? J'avais pensé à un truc comme ça :
var real_document = document;
document = document.getElementById(divid);

// Ces lignes devraient remplacer la fonction write() par innerHTML...
document.write = function(arg) {
document.innerHTML = arg;
};

// Suit ici le script utilisant le document.write() falsifié
/* ... */

// Pour finir, on remet le bon document en place
document = real_document;
Mais la syntaxe est ici probablement incorrecte.

Vous avez une idée ?

Merci
Modifié par Digimag (24 Aug 2007 - 21:55)
Je pense qu'il faudrait se contenter de ne remplacer que la fonction document.write :

document.write = function (str) {
document.getElementById('une_div').innerHTML += str;
}
Merci, et on n'oublie pas le point-vrigule !
document.write = function (str) {
document.getElementById('une_div').innerHTML += str;
};
C'est parfait, ça marche !

Et on a bien le droit d'écrire un_element.appendChild('<p>Du code <em>HTML</em></p>'); ?

C'est la dernière question qui reste avant le Résolu...
Modifié par Digimag (26 Aug 2007 - 16:20)
Bonjour,
Digimag a écrit :
Merci, et on n'oublie pas le point-vrigule !

pas necessaire en fin de ligne pour javascript.
a écrit :
Et on a bien le droit d'écrire un_element.appendChild('<p>Du code <em>HTML</em></p>'); ?

Smiley eek Oh la! tu confonds avec innerHTML.
chmel a écrit :
Et on a bien le droit d'écrire un_element.appendChild('<p>Du code <em>HTML</em></p>'); ?

Smiley eek Oh la! tu confonds avec innerHTML.
Justement c'est bien ça le problème. Si je mets du code JavaScript avec innerHTML, le code n'est pas exécuté par le navigateur. Si en revanche j'utilise ma méthode append() de jQuery, le code s'exécute. Un extrait de jQuery :

// Map the jQuery namespace to the '$' one
var $ = jQuery;

jQuery.fn = jQuery.prototype = {
	init: function(a,c) {
		// Make sure that a selection was provided
		a = a || document;

		// HANDLE: $(function)
		// Shortcut for document ready
		if ( jQuery.isFunction(a) )
			return new jQuery(document)[ jQuery.fn.ready ? "ready" : "load" ]( a );

		// Handle HTML strings
		if ( typeof a  == "string" ) {
			// HANDLE: $(html) -> $(array)
			var m = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(a);
			if ( m )
				a = jQuery.clean( [ m[1] ] );

			// HANDLE: $(expr)
			else
				return new jQuery( c ).find( a );
		}

		return this.setArray(
			// HANDLE: $(array)
			a.constructor == Array && a ||

			// HANDLE: $(arraylike)
			// Watch for when an array-like object is passed as the selector
			(a.jquery || a.length && a != window && !a.nodeType && a[0] != undefined && a[0].nodeType) && jQuery.makeArray( a ) ||

			// HANDLE: $(*)
			[ a ] );
	},

[...]

	append: function() {
		return this.domManip(arguments, true, 1, function(a){
			this.appendChild( a );
		});
	},

[...]

	domManip: function(args, table, dir, fn){
		var clone = this.length > 1, a; 

		return this.each(function(){
			if ( !a ) {
				a = jQuery.clean(args, this.ownerDocument);
				if ( dir < 0 )
					a.reverse();
			}

			var obj = this;

			if ( table && jQuery.nodeName(this, "table") && jQuery.nodeName(a[0], "tr") )
				obj = this.getElementsByTagName("tbody")[0] || this.appendChild(document.createElement("tbody"));

			jQuery.each( a, function(){
				fn.apply( obj, [ clone ? this.cloneNode(true) : this ] );
			});

		});
	}
};
Je ne comprends pas exactement ce que fait la fonction append(), j'avais cru qu'elle utilisait appendChild(). Mais je viens de vérifier, en remplaçant append() de jQuery par un appendChild(), ça ne fonctionne plus (erreur d'exécution JavaScript).

Je m'y perds.

Sinon, pour restaurer le document.write, est-ce que je peux écrire quelque chose comme
old_write = document.write;
document.write = function(str){...};
[...]
document.write = old_write;
?

Merci Smiley smile
bonjour,
Je ne connais pas jquery, mais tu peux remplacer avantageusement innerHTML par la fonction prposée par julien royer, et pour y ajouter du javascript fonctionnel à la volée, une solution :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>Tewt</title>
<style>
.jaune{background-color:#ff0}
</style>
<script type="text/javascript">
<!--
( function() { 
var createEl = function(n) {
	var a, i = 0, e = document.createElementNS ? document.createElementNS("http://www.w3.org/1999/xhtml", n) : document.createElement(n);
	while ((a = arguments[++i])) {
		if (typeof a === "string") {e.appendChild(document.createTextNode(a));}
	  else if (a.nodeName) {e.appendChild(a);}
	  else {for (var p in a) {e[p] = a[p];}}
	}
	return e;
}
p = createEl("p", "Pouet ",
  c=createEl("a", {"href": "#", "title": "tsoin", "className": "jaune"}, "coin"),
  ".");
c.onclick=function(){alert('coucou');return false}
;
} ) ();
//-->
</script>
</head>
<body>
<p><a href="#" onclick="document.body.appendChild(p);return false">ajouter html avec script </p>
<p><a href="#" onclick="document.body.removeChild(p);return false">retirer le code </p>
</body>
</html> 
. Et si tu veux faire mieux, AddEvent et StopEvent
Modifié par chmel (28 Aug 2007 - 02:16)