11548 sujets

JavaScript, DOM et API Web HTML5

Salut,

Voila j'essaie depuis un moment d'imprimer le contenu d'un div sur un click et seulement celui-ci, quelque soit son niveau d'imbrication.

Je sais qu'il existe la solution qui consiste à créer une feuille css pour l'impression, mais celle-ci ne peut me satisfaire car elle serrait trop fastidieuse et je veux pouvoir, par exemple, inclure deux boutons d'impression sur une même page et que ces deux boutons lance des impressions sur des div différents.

Dans un premier temps j'ai tenté la méthode suivante:
NB: les codes qui suivent requiers la librairie Prototype.js

		Event.observe(submitPrint,'click', function(e){

			/*On récupère les childs du body*/
			var childsBody = $(document.body).childElements();

			/*Puis on les fait disparaitre ou retirer du body*/
			childsBody.each(function(child) {
				child.hide();
				//child.remove();
			});

			/*On insère le div à imprimer dans le body*/
			$(document.body).insert(divPrint);

			/*On lance l'impression*/
			window.print();

			/*On replace le div à son ancien emplacement*/
			parent_divPrint.insert(divPrint);

			/*Enfin on fait réapparaitre ou on réinsère les childs du body*/
			childsBody.each(function(child) {
				child.show();
				//$(document.body).insert(child);
			});

		}.bind(this));


Cette méthode marche parfaitement pour IE, mais pas pour FF (Il me semble avoir compris que c'était un problème récurant aux navigateurs type gecko due à l'architecture du DOM). Les childs pourtant supprimés ou cachés apparaissent à l'impression.

J'ai donc cherché à passer par un autre moyen, en utilisant une nouvelle fenêtre:

		Event.observe(submitPrint,'click', function(e){

		var DocumentContainer = divPrint;

       		/*On ouvre une nouvelle fenêtre*/
       		var WindowObject = window.open('', "dataPrint",
       		       		"width=700,height=300,top=150,left=150"); 

       		/*On écrit le code html du div à imprimer*/
        	WindowObject.document.write(DocumentContainer.innerHTML);
                WindowObject.document.close();

                /*On donne le focus à la fenêtre et on lance une impression de son contenu*/
        	WindowObject.focus();
        	WindowObject.print();

       		/*Enfin on ferme la nouvelle fenêtre*/
        	WindowObject.close();

		}.bind(this));


Et là super cela marche aussi sous Firefox, seulement il y a un MAIS et pas des moindres.
Le div à imprimer comporte des graphiques et ces derniers sont créés à partir de balises canvas (utilisation d'un émulateur canvas pour IE). Et évidement mes graphes sont vides au passage dans la nouvelle fenêtre. Logique car le code html d'un canvas est 'vide'.

Connaissez vous une méthodes pour imprimer un seul div quelque soit sont contenu?

Sinon si le passage par un nouvelle fenêtre est obligatoire pour Firefox; Comment puis-je faire un insert au body de la nouvelle fenêtre? en espérant que cela résolve mon problème.
Du genre:
NB: ce code n'est pas correct
WindowObject.document.body.insert(DocumentContainer);

Modifié par Glopp (01 Jun 2009 - 14:05)
Désolé pour tout ce bla bla Smiley murf

J'étais persuadé que la fonction insert de prototype pouvait être utilisée vu que je la lançait à partir d'une page la contenant Smiley langue

Donc suffit de faire un appendChild:
WindowObject.document.body.appendChild(DocumentContainer);


Cela poura toujours servir pour d'autres! Smiley cligne
En fait j'ai un petit souci sous IE, je n'arrive pas à faire l'appendChild
IE bloque sur:
WindowObject.document.body


habituellement, pour accéder au body, j'utilise:
$(document.body)


mais ici $(WindowObject.document.body) ne marche pas Smiley ohwell
Salut,

Je n'ai toujours pas trouvé comment accèder au body de la nouvelle fenêtre Smiley confus .

Une idée?
Bon finalement, je me suis aperçus, en regardant les codes sources des nouvelles fenêtre à l'appel de window.open(), que IE et FF ne réagissant pas de la même façon.

En effet IE ouvre une fenêtre totalement vide sans aucune balise alors que FF créé une structure minimale avec les balise doctype html, head et body. Ce qui explique le fait que je ne parvenais pas à accéder au body sous IE.

Donc avant de faire mon appendChild je créé moi même la structure de ma page.

Seulement, j'ai bien un body, je peux y accéder, afficher son contenu... mais impossible de faire un appendChild Smiley eek

voici le code modifié:

	Event.observe(submitPrint,'click', function(e){

		var DocumentContainer = divPrint;

       		/*On ouvre une nouvelle fenêtre*/
       		var WindowObject = window.open('', "dataPrint",
       		       		"width=700,height=300,top=150,left=150"); 

       		/*On écrit la structure de la page afin d'être sur d'avoir un bon doctype et un body  */
        	WindowObject.document.write(
        	'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
        	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
        	<head>
        	        	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        	</head>
        	<body>
        	        	Du texte pour le test.
        	</body>
        	</html>');
                WindowObject.document.close();

                /*on change le titre [b]-> changement ok sur la nouvelle fenêtre[/b]*/
                WindowObject.document.title = 'Page d'impression';

                /*on récupère le body de la nouvelle fenêtre*/
                var bodyPrint = WindowObject.document.getElementsByTagName('body')[0];
                //var bodyPrint = WindowObject.document.body;

                /*on affiche le contenu du body [b]-> Du texte pour le test.[/b]*/
		alert(bodyPrint.innerHTML );	

                /*on ajoute le div à imprrimer [b]-> sous IE bug[/b]*/
		bodyPrint.appendChild(divPrint);

                /*On donne le focus à la fenêtre et on lance une impression de son contenu*/
        	WindowObject.focus();
        	WindowObject.print();

       		/*Enfin on ferme la nouvelle fenêtre*/
        	WindowObject.close();

		}.bind(this));



C'est pas que j'ai l'impression d'être un peu seul Smiley murf , mais là je vois pas comment m'en sortir Smiley sweatdrop .
Pour ceux qui suivent Smiley murf , la fonction appendChild passe pour les balises non canvas.

C'est du au fait que pour ie j'utilise un js qui émule ces balises, j'ai donc ajouté le script au moment du WindowObject.document.write :

<!--[if IE]>
<script type="text/javascript" src="./lib/excanvas.js"></script>
<![endif]-->

mais rien...