Posts tagged “javascript”.

Performances des packers javascript

Les librairies et frameworks javascript sont de plus en plus nombreux et de plus en plus complets. Ca, c’est une bonne nouvelle, mais la conséquence logique est que leur taille augmente jusqu’à un point qui commence à devenir problématique. Heureusement, des outils de “compression” tels que JSMin sont apparus ; ils permettent de réduire sensiblement la taille des scripts en supprimant les commentaires, l’indentation, et autres caractères inutiles. Le principe est de conserver une version complète et documentée des scripts pour le développement, puis, au moment de la mise en production, les fichiers passent dans cette moulinette de compression qui les “amaigris”.

Depuis quelques temps, une autre technique de compression emerge. Au lieu de simplement purger le code de tous les caractères inutiles, le code est “empaqueté” (packed) dans une fonction qui contient l’agorithme permettant de décompresser le paquet. Ainsi il est possible d’utiliser des méthodes de compression plus efficaces (changement de base, remplacement de patterns, etc.) et obtenir des fichiers encore plus petits, mais totalement illisibles. Ces solutions ont été très vites adoptées par de nombreux projets et sites web, mais sont-elles vraiment si efficaces ?

More… »

Une version optimisée pour PHP de JSMin

Les Javascripts permettent de faire tout pleins de choses sur un site web, c’est cool. Mais à force d’empiler les librairies, les frameworks et autres fonctions, on peut vite se retrouver avec deux kilo-tonnes de script, ce qui n’est ni très agréable à charger et ni très léger pour la bande passante.

Heureusement, plusieurs librairies (plus ou mois efficaces) existent et permettent de compresser les scripts. JSMin est l’une d’entre elle.

More… »

Position du curseur dans un textarea

Comment détecter, en javascript, la position du curseur dans un textarea ? Comment déplacer le curseur ? Comment récuperer le texte sélectionné, ainsi que les coordonnées de la selection ? Evidemment sous Firefox tout roule, mais pour le navigateur de Microsoft c’est autre chose… Après avoir passé 5 bonnes heures sur Google à lire des solutions aussi farfelue qu’inefficaces (à base de Math.round, de boucles imbriqués, ou de soustraction d’un coeffient alétoire), j’ai fini par chercher ma propre solution. Voici quelques pistes pour soumettre Internet Explorer à votre volonté !
More… »

Une interface de formulaire à base de tableaux dynamiques

Oui, je sais, les tableaux de mise en page c’est mal. Mais quand il s’agit de présenter des données en tableau, par exemple : le prix des carottes en fonction de la vitesse du vent et de l’age du capitaine, alors ils sont indispensables. Je dirais même plus, ça serait une erreur de ne pas les utiliser. Maintenant, imaginons que nous ayons à programmer une interface pour saisir le prix des carottes : comment faire simple, léger, accessible, rapide à développer et agréable à utiliser ? L’idéal serait de se rapprocher du fonctionnement d’un tableur : pouvoir ajouter, supprimer ou éditer des lignes, et sauvegarder le document à la fin. Et bien en interface web, c’est possible grâce à Javascript et DOM (et un peu de PHP pour le traitement).

More… »

Centrer un float en CSS

Une zone – la galerie – doit être constituée de un ou plusieurs éléments – les boites – centrés à l’interieur et sur une seule ligne. En HTML « à la papy » c’est très facile à faire : la galerie est une cellule d’un tableau avec la propriété align="center", et le contenu est un tableau d’une seule ligne dont le nombre de cellules varie de 1 à 5 (le nombre maximum de boites pour tenir sur une seule ligne). Mais comment faire ça en CSS ?

Problématique

L’effet recherché ressemble à ça :

L'effet recherché

L'effet recherché

Ma première idée, pour placer les boîtes est d’utiliser le positionnement float avec un hr et la propriété clear : both; comme expliqué dans ce très bon article sur OpenWeb.

Au niveau code ça donne :

<div class="galerie">
	<div class="boîte">boîte 1</div>
	<div class="boîte">boîte 2</div>
	<div class="boîte">boîte 3</div>
	<div class="boîte">boîte 4</div>
	<div class="boîte">boîte 5</div>
	<hr class="clear" />
</div>

Appliquons le style suivant :

.galerie {
	background : #ccc;
	width : 360px; /* (50 + (5 * 2) + 10) * 5 + 10 */
}
.boîte {
	background : #69c;
	float : left;
	margin : 10px 0 10px 10px;
	padding : 5px;
	width : 50px;
	text-align : center;
}
.clear {
	clear : both;
	visibility : hidden;
}

Ça donne :

Exemple 1.1

Exemple 1.1

Avec 3 boîtes uniquement :

Exemple 1.2

Exemple 1.2

Vous pouvez tester ce premier exemple.

Le positionnement est celui recherché lorsque toutes les boîtes sont présentes, mais, malheureusement, dès qu’il manque des boîtes, celles restantes sont calées à gauche. C’est tout à fait logique puisqu’elles sont flottantes à gauche, mais ce n’est pas ce que nous voulons !

Un deuxième conteneur pour le centrage

Au départ, j’ai simplement essayé quelques techniques de centrage css appliquées sur les fiches ou sur le conteneur. Mais rien de tout ça ne fonctionne.

Le problème est qu’on ne peut pas centrer un flottant, à cause de sa conception même. Comme écrit très justement dans l’article d’Openweb : Une boîte flottante est retirée du flux normal, et placée le plus à droite (float: right) ou le plus à gauche (float: left) possible dans son conteneur. Il est donc logique que les techniques de centrage ne puisse pas s’appliquer (centrer par rapport à quoi, puisque la boîte est retirée du flux ?).

Par contre, un élément non-flottant peut, lui, être centré (par exemple avec la technique des marges auto). Imaginons que l’on crée un autre conteneur, qui soit centré par rapport au premier (la galerie), et qui contienne les fiches…

L'effet recherché

L'effet recherché

Au niveau code ça donne :

<div class="galerie">
	<div class="conteneur">
		<div class="boîte">boîte 1</div>
		<div class="boîte">boîte 2</div>
		<div class="boîte">boîte 3</div>
		<div class="boîte">boîte 4</div>
		<div class="boîte">boîte 5</div>
		<hr class="clear" />
	</div>
</div>

On applique le même style que précédemment. Mais il faut rajouter de quoi centrer le conteneur :

.galerie {
	text-align : center; /* uniquement pour IE */
}
.conteneur {
	margin : 0 auto;
}

Là se pose un problème – LE problème devrais-je dire – : pour que ça fonctionne il faut que le conteneur enveloppe parfaitement les boîtes, et donc soit exactement à la bonne taille. La formule donnant la taille est facile à trouver :

taille = nombre de boîtes * ( width + padding + margin-left ) + margin-right

Mais je n’ai strictement aucune idée de comment faire ça en CSS. C’est théoriquement possible de le fixer dans un style inline (dans la page) appliqué au moment où le script qui génére la page affiche les boîtes. Une autre solution est d’utiliser DOM pour manipuler en Javascript les styles de la page.

Implémentation en Javascript/DOM

Le script doit se charger de calculer la taille en fonction du nombre d’éléments contenus. Pour ça il faut :

  1. Trouver le conteneur à agrandir ; on utilisera la méthode getElementsById
  2. Compter le nombre de boîtes contenues :
    • Trouver les éléments div avec la méthode getElementsByTagName
    • Eliminer ceux qui ne sont pas directement fils du conteneur (si les boîtes contiennent d’autres divs par exemple
  3. Calculer la taille et agrandir le conteneur

Mon implémentation (qui n’est sûrement pas optimale) :

<script type="text/javascript">
 // <![CDATA[
function setContainerSize(truc) {
	var navroot = document.getElementById(truc);
	if ( navroot ) {
		var lis = navroot.getElementsByTagName("div");
		/* XXX : y a-t-il un moyen plus simple de ne détecter que les divs de rang 1 ?
		 *       ou, détecter selon une classe ? */
		var ok = 0; var nok = 0;
		for ( i = 0; i < lis.length; i++ ) {
			if ( lis[i].parentNode != navroot )
				nok++;
			else
				ok++;
		}
		navroot.style.width = ok * 70 + 10 + 'px';
	}
}
 // ]]>
</script>

Maintenant, pour utiliser cette fonction, on effectue les modifications suivantes :

<body onload="setContainerSize('c1');">
...
<div class="conteneur" id="c1">

Ça donne :

Exemple 3

Exemple 3

Vous pouvez consulter cet exemple.

Limites et pistes de reflexions

Cette méthode a été testée avec succès sur IE 6, Firefox 1.x, Safari 1.3 et Camino 0.9.

Une limitation principale de cette méthode est l’impossibilité de centrer sur plusieurs lignes. Par exemple, si la première ligne contient 5 boîtes et la deuxième 2, les 2 seront calées à gauche. Je n’ai pas vraiment cherché comment résoudre ce problème, car ça n’était pas mon besoin.

L’autre amélioration possible concerne l’implémentation du script, et notamment la façon de compter les éléments div qui n’est sûrement pas optimale. Il serait également intéressant de pouvoir ne pas coder en dur les tailles des div dans le script, de manière à avoir du code réutilisable. Mais là ça dépasse mes connaissance en DOM :)

Enfin, étant donné que le centrage se fait par un script, les boîtes ne sont pas centrées tant que la page n’est pas complètement chargée. Dans certains cas ça provoque un petit décalage à l’écran le temps que le chargement se termine…

Quelques liens supplémentaires

Merci à Scara, MrGecko et tout le chan #asw pour la relecture ;)