Agrandissement progressif d'un div

ViPHP
AB
ViPHP | 5818 Messages

18 mars 2010, 01:02

L'accès "facile" aux données des fichiers CSS en javascript n'est pas encore implémentée dans tous les navigateurs.
Pour que la solution soit portable il faudrait donc parser la feuille de style. Je ne connais pas de solution "standard" (je veux dire "indiscutablement la meilleure") mais il y a beaucoup de scripts sur le web pour ça.

Sinon tu peux utiliser document.getElementById('lediv').offsetWidth pour trouver la largeur d'un div défini en CSS ou par un style incorporé ou par javascript, alors que document.getElementById('lediv').style.width ne peut retourner que la largeur d'un div défini par un style incorporé ou par javascript (et pas en css).
Modifié en dernier par AB le 18 mars 2010, 02:36, modifié 1 fois.

Eléphant du PHP | 447 Messages

18 mars 2010, 01:52

Génial AB, c'est exactement ce dont j'avais besoin! Du coup je pense que c'est réalisable de cette manière... De plus offsetWidth retourne un integer, non? C'est plus pratique dans ce cas qu'une chaine du style "XXpx" comme renvoie .style.width ...
Probably (only a) Human Problem?

ViPHP
AB
ViPHP | 5818 Messages

18 mars 2010, 02:31

Effectivement c'est plus pratique car en plus de récupérer la largeur définie en css, tu peux faire des comparaisons genre offsetHeight <= 305 ce qui te seras très utile si la largeur de ton tableau était par exemple de 305px car dans ce cas en testant une égalité (= 305) et des incréments de 10px, ta boucle serait infinie :wink:

Eléphant du PHP | 447 Messages

18 mars 2010, 08:01

Well, j'ai continué à bosser dessus, et ça donne ça:
<html>
<head>
	<title>Effet JS</title>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<style type="text/css">
	#lediv {
		margin: 0;
		padding: 5px;
		white-space: nowrap;
		border: 1px solid black;
		overflow: hidden;
	}
	</style>
	<script type="text/javascript">
	var x = 0;
	var y = 0;
	function ccw() {
		
		var mydiva = document.getElementById('lediv');
		var rep1 = setTimeout('ccw()', 10);
		x += 10;
		
		mydiva.style.width = x + 'px';
			
		if (mydiva.offsetWidth >= 300) {
				
			clearTimeout(rep1);

		}
		
	}
	function cch() {
		
		var mydivb = document.getElementById('lediv');
		var rep2 = setTimeout('cch()', 10);
		y += 10;
		
		mydivb.style.height = y + 'px';
			
		if (mydivb.offsetHeight >= 150) {
				
			clearTimeout(rep2);

		}
		
	}
	function progressif() {
		
		var mydiv = document.getElementById('lediv');
		
		mydiv.style.width = '0px';
		mydiv.style.height = '0px';
		mydiv.style.display = 'block';
		
		setTimeout('ccw()', 10);
		setTimeout('cch()', 10);

	}	
	</script>
</head>
<body>
	<a href="#gonoway" onclick="progressif()">Ouvrir</a>
	<div id="lediv" style="display: none;">
		<p>Contenu div contenu div<br />contenu div Contenu div contenu<br />div contenu divContenu<br />div contenu div contenu div</p>
	</div>
	<div id="testdem"></div>
</body>
</html>
Ca fontionne comme je le voulais. Enfin presque parce que je voudrais pouvoir déclarer les dimensions du div dans le CSS externe au js, mais je ne le peux pas... Sur le div en display:none offsetWidth retourne 0.
Donc j'ai été obligé de faire comme ça.

Si quelqu'un a des idées pour améliorer ce code en général, et pour apporter en particulier une solution à ma question sur le CSS, je suis preneur! : )
Probably (only a) Human Problem?

ViPHP
AB
ViPHP | 5818 Messages

18 mars 2010, 15:14

Ca fontionne comme je le voulais. Enfin presque parce que je voudrais pouvoir déclarer les dimensions du div dans le CSS externe au js, mais je ne le peux pas... Sur le div en display:none offsetWidth retourne 0.
Donc j'ai été obligé de faire comme ça.

Si quelqu'un a des idées pour améliorer ce code en général, et pour apporter en particulier une solution à ma question sur le CSS, je suis preneur! : )
1/Tu l'a sous les yeux la solution ! puisque tu l'a déjà utilisée dans ton code. Si offsetWidth retourne 0 avec un display:none en revanche il retourne la largeur sur un display:block et tu sais le faire en javascript :wink:

Sinon il n'y a aucune raison d'utiliser setTimeout dans ta fonction progressif. Lance directement les fonctions !

Tu as aussi des petits problèmes logiques dans tes fonctions cch et ccw : il ne faut incrémenter que si la condition n'est pas remplie, pas avant. Et pour arriver finalement à la hauteur exacte, il y a une petite astuce.

Bon je te laisse chercher un peu et appliquer mes premiers conseils.

Eléphant du PHP | 447 Messages

18 mars 2010, 16:34

1/Tu l'a sous les yeux la solution ! puisque tu l'a déjà utilisée dans ton code. Si offsetWidth retourne 0 avec un display:none en revanche il retourne la largeur sur un display:block et tu sais le faire en javascript :wink:
Oui mais si je le mets pas en display: none, comment je le cache avant de le faire apparaître?
Sinon il n'y a aucune raison d'utiliser setTimeout dans ta fonction progressif. Lance directement les fonctions !
Comment je déclenche les fonctions directement alors? Je ne connais pas la formule...
Tu as aussi des petits problèmes logiques dans tes fonctions cch et ccw : il ne faut incrémenter que si la condition n'est pas remplie, pas avant. Et pour arriver finalement à la hauteur exacte, il y a une petite astuce.
Oui, j'avais pas pensé à ça, faut l'incrémenter qu'après vérification de la condition... Par contre je ne trouve pas l'astuce dont tu parles... Je vais chercher comme tu dis (m'enfin, si tu peux me donner un ch'ti indice)...

Encore merci AB!!
Probably (only a) Human Problem?

ViPHP
AB
ViPHP | 5818 Messages

18 mars 2010, 17:15

Testes ça :
<!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" xml:lang="fr">
<head>
<title>Test... :S</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<script type="text/javascript">
        var hauteur_instant = 0;

        function cch(id_div,hauteur) {
               
                var mydivb = document.getElementById(id_div);               
                var increment = 7;
				
		if (hauteur_instant < hauteur) 
			{ 
				var hauteur_div = hauteur_instant + increment <=  hauteur ? hauteur_instant + increment : hauteur;
					 
                                mydivb.style.height = hauteur_div+'px';
			        hauteur_instant += increment;
						
			        setTimeout(function(){cch(id_div,hauteur)},0);
                        }
               
        }
		
        function progressif(id_div) {
               
                var mydiv = document.getElementById(id_div);
               
                mydiv.style.display = 'block';
				
		var largeur = mydiv.offsetWidth;
 		var hauteur = mydiv.offsetHeight; 
				
		mydiv.style.width = largeur+'px';				
               
		mydiv.style.height = 0+'px';
				
		hauteur_instant = 0;
		cch(id_div,hauteur);	

        }       
</script>
<style type="text/css">
#lediv {
                margin: 0;  
                white-space: nowrap;
                border:1px solid black;
                overflow: hidden;
		width:300px;
		height:150px;
		display:none;
        }
</style>
</head>
<body>
         <span onclick="progressif('lediv')" style="cursor:pointer; text-decoration:underline">Ouvrir</span>
        <div id="lediv">
                <p>Contenu div contenu div<br />contenu div Contenu div contenu<br />div contenu divContenu<br />div contenu div contenu div</p>
        </div>
        <div id="testdem">Bloc dessous qui sera poussé</div>
</body>
</html>
Et il faut que tu comprennes tout avant d'aller plus loin (y'aura une interro écrite :P)
Au passage, notes bien la syntaxe particulière de setTimeout qui permet d'envoyer des paramètres dans la fonction.

Eléphant du PHP | 447 Messages

18 mars 2010, 18:47

Yeeeehouuuuuuuuuuu :D merci AB!

J'vais tester et essayer de bien tout comprendre! Merci pour le temps que tu y as donné!!
Probably (only a) Human Problem?