11521 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
Je n'arrive pas à faire apparaître une image dans une fenêtre pop-up alors que ça marche sans problème dans la fenêtre principale. Je travaille avec Firefox 56.0.1
Merci de votre aide.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>pop-up + image</title>
        <script type="text/javascript">
			function show() {
				// image dans fenêtre principale : ça marche
				var oDiv = document.getElementById('div1') ;
				var oImg = document.createElement('img') ;
				oImg.src = "cats.png" ;
				oDiv.appendChild(oImg) ;
				// création de la pop-up : ça marche
				var options = "width=400, height=400 ,top=100, left=100" ;
				var win = window.open("", "", options);
				win.parent.document.title = "Pop-up" ;
				var oBody = document.createElement('body') ;
				win.document.body = oBody ;
				var oDiv = document.createElement('div') ;
				oBody.appendChild(oDiv) ;
				// image dans la pop-up : l'image n'apparaît pas
				var oImg = document.createElement('img') ;
				oImg.src = "cats.png" ;
				oDiv.appendChild(oImg) ;
			}
		</script>
    </head>
    <body onload="show()">
        <div id="div1"></div>
    </body>
</html>

Modifié par dix_de_der (26 Oct 2017 - 23:23)
Modérateur
Salut,

C'est normal... Je t'invite à bien lire la signature de la méthode open de l'objet Window. Je pense notamment au premier argument Smiley cligne
Modifié par niuxe (26 Oct 2017 - 23:53)
Merci de ta réponse Smiley smile mais elle ne résout pas mon problème.
La doc du premier argument de open() indique effectivement que l'on peut passer l'url d'une image. En fait, pour le site que je développe c'est un tableau que je crée dynamiquement dans une fenêtre pop-up et dans quelques cellules de ce tableau je mets une image. Il faut donc que j'arrive à faire apparaître l'image dans une structure DOM...
De plus j'ai vérifié que la structure body+div est bien crée dans la fenêtre pop-up. En effet si je remplace l'insertion d'image oDiv.appendChild(oImg) ; par une insertion de message oDiv.innerHTML = "hello world !" ; le message apparaît bien !
Modérateur
dix_de_der a écrit :
Merci de ta réponse Smiley smile mais elle ne résout pas mon problème.
La doc du premier argument de open() indique effectivement que l'on peut passer l'url d'une image. En fait, pour le site que je développe c'est un tableau que je crée dynamiquement dans une fenêtre pop-up et dans quelques cellules de ce tableau je mets une image. Il faut donc que j'arrive à faire apparaître l'image dans une structure DOM...


En lisant ton code, je vois bien que tu comprends pas tellement comment fonctionne cette méthode.
Je vais te donner la marche à suivre (bien que dans l'absolue, je ne te conseille pas d'utiliser window.open dû à un souci d'ergonomie entres autres) :
1. créer un fichier html (gabarit) où il y aura ta structure html (ton petit tableau) avec des mots clef (ex : {{SRC_IMG}})
2. dans ta fenêtre mère, tu indiques l'url du fichier html dans ta méthode open (mais pas que...) Tout ton code appendchild, createElement, etc. fait mal à la tête !
3. lorsque la fenêtre mère est chargée, tu lances la méthode open (je lie ton code et ça me parait suspect Smiley hum >>>-----------> intérêt null )

Le problème étant que ta page appelée n'est pas dynamisée n'est ce pas ? Pas de problème, une querystring va t'aider. Dans l'étape 2, je viens de t'indiquer de saisir l'url. Tu vas ajouter des arguments nommés supplémentaires pour que tu puisses les récupérer par la suite. Smiley cligne

4. Dans la fenêtre enfant, tu vas ouvrir un script qui va dynamiser ton fameux tableau. Tu vas avoir besoin de :
- les attributs location et search de l'objet Window (bien regarder comment ça fonctionne Smiley cligne )
- la méthode split() de l'objet String
- la méthode replace() de l'objet String

Si les données de ton tableau à dynamiser sont conséquentes, un fichier JSON ou XML devrait t'aider. Dans ce cas là, tu passes en paramètres de ton url de ta page mère un identifiant (je ne parle pas d'un id html) seulement et dans la page enfant, tu vas chercher l'identifiant avec les données correspondantes dans le JSON ou XML (AJAX).

Là, je viens de t'indiquer comment le faire en JS. On peut très bien le faire en python ou php ou ... D'ailleurs, ce serait plus simple à dynamiser.

au passage, tu ne donnes pas suffisamment d'élément pour qu'on t'aide (règle 13 du forum). La solution que je t'ai donné est relativement limité (loop <tr> ? besoin de handlebars/underscore , Backbone/underscore/jcuicui , React ? Smiley ohwell )
Modifié par niuxe (27 Oct 2017 - 01:17)
Je ne comprends pas trop ta réponse, le code que je montre est du grand classique qu'on voit partout...
Ça ne me sert pas à grand chose de charger un fichier html gabarit parce que les dimensions du tableau dépendent de données que je ramène d'une base de données mysql. Tout au plus je pourrais y déclarer l'objet vide table (<table id="matable"></table>) mais il faudrait de toutes façons que j'insère dynamiquement les lignes, les cellules et les images.
Modifié par dix_de_der (27 Oct 2017 - 08:34)
Suite à la réponse de niuxe j'ai testé ce que ça donne en passant par un fichier gabarit, et ça marche ! Merci niuxe. Moralité : il n'est pas équivalent de créer une structure DOM à partir du body par chargement d'un fichier html ou par instructions javascript avec des appendChild. Ce n'est dit nulle part...
Pour le fun voici comment on peut tester avec un seul fichier html récursif Smiley biggrin
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>pop-up + image</title>
        <script type="text/javascript">
			function show() {
				// image dans fenêtre principale
				var oDiv = document.getElementById('div1') ;
				var oImg = document.createElement('img') ;
				oImg.src = "cats.png" ;
				oDiv.appendChild(oImg) ;
				// création de la pop-up
				if( window.name.toString() != "popup") {
					var options = "width=400, height=400 ,top=100, left=100" ;
					var win = window.open("wImage.html", "popup", options);
				}
			}
		</script>
    </head>
    <body onload="show()">
        <div id="div1"></div>
    </body>
</html>

Modifié par dix_de_der (27 Oct 2017 - 09:07)
Modérateur
dix_de_der a écrit :
Ce n'est dit nulle part...

Le premier paramètre doit être une URL valide. En renvoyant une chaîne c'est invalide. La «page» ouverte est probablement nulle, sans même de DOM donc.
La doc Mozilla https://developer.mozilla.org/fr/docs/Web/API/Window/open autorise le premier paramètre en chaîne vide : "Si strUrl est une chaîne vide, une nouvelle fenêtre vide de tout contenu (l'URL about:blank sera chargée) est créée avec les barres d'outils par défaut de la fenêtre principale."

Par contre il est écrit juste dessous :
Notez que les URL distantes ne seront pas chargées instantanément. Lorsque l'appel à window.open() se termine et renvoie sa valeur, la fenêtre contient toujours about:blank. Le chargement proprement dit de l'URL est reporté et ne commence effectivement qu'après la fin de l'exécution du bloc de script courant. La création de la fenêtre d'une part et le chargement de la ressource référencée d'autre part sont faits de manière asynchrone.
Ce qui laisse imaginer que, peut-être, la fenêtre n'est pas en état de se voir insérer une image juste après le open() avec une URL vide. Pourtant elle est en état de recevoir un texte à afficher...
Modifié par dix_de_der (27 Oct 2017 - 11:57)
Modérateur
Au temps pour moi, en effet, sorry Smiley smile

Du coup ce code peut fonctionner:


var options = "width=400, height=400 ,top=100, left=100" ;
var win = window.open("", "", options);
var div = document.createElement("div");
div.innerHTML = 'youhou';
win.document.body.appendChild( div );
Oui.
Mais si on remplace div.innerHTML = 'youhou'; par div.appendChild(Image) ; ça ne marche plus, l'image n'apparaît pas !
J'ai opté pour l'ouverture d'un fichier html avec un body vide :
var win = window.open("vide.html", "", options);
var foo = function() { show(win); } ;
win.addEventListener('load', foo, false);

où show(win) remplit le body de win avec tableau et images.
c'est orthodoxe et ça marche Smiley smile
Modérateur
ça marche parfaitement aussi avec une image…


var options = "width=400, height=400 ,top=100, left=100" ;
var win = window.open("", "", options);
var img = document.createElement("img");
img.src = 'https://cdnf.alsacreations.net/avatars/1509052097-68139-cocotte-150.png';
win.document.body.appendChild( img );


Par contre la fenêtre n'ayant pas d'URL, une URL relative est probablement problématique.
Meilleure solution
kustolovic a écrit :

Par contre la fenêtre n'ayant pas d'URL, une URL relative est probablement problématique.


Ça c'est la bonne remarque !
Je suis revenu à ma version initiale, j'ai mis l'URL de l'image en absolu et ça marche.
Merci kustolovic ! Le problème est résolu.