11522 sujets

JavaScript, DOM et API Web HTML5

Bonjour et merci d'avance pour votre précieux temps Smiley cligne

Je cherche à redimensionner une "ul" en fonction de la longueur totale des éléments qui la compose.


<ul class="series">
    <li><img class="autoW"></li>
    <li><img class="autoW"></li>
    <li><img class="autoW"></li>
    <li><img class="autoW"></li>
</ul>


Les "li" étant en width: auto; dans mon cas, j'ai attribué ma classe aux balises img (j'ai retiré les src pour le post).

Voici ce que j'ai écris pour le moment :


window.onload = function autoWidth() {
	/*Je cible le premier élément "series" de mon html*/
	var ul = document.getElementsByClassName("series")[0];
	/*Je cible l'ensemble des éléments de la classe autoW, les img donc*/
	var li = document.getElementsByClassName("autoW");
	/*J'en récupère la longueur*/
	var liLength = li.length;
	/*J'initialise la longueur de ul*/
	ul.style.width = 360 + "px";
	/*Je crée une boucle for pour additionner la longueur de chaque img à ul*/
	for (var i = 0; i < liLength; i++) {
		ul.style.width = (parseInt(ul.offsetWidth) + parseInt(li[ i ].offsetWidth)) + "px";
	}
}


Tout ce qui concerne mes images ne fonctionne pas, aucun élément de la classe autoW n'est détecté... li.length = 0 du coup ben la boucle fonctionne pas...

Si vous voyez l'erreur dans ce cas présent c'est top, sinon je suis ouvert à d'autre propositions mais pas de jquery pour le moment svp (je sais que çà facilite beaucoup le travail mais je cherche à progresser en js pur d'abord, merci de votre compréhension).
Modifié par LuCube (18 Jun 2014 - 10:16)
Modérateur
Bonjour,

J'ai repris ton code tel quel, et il marche (au sens que liLength vaut bien 4 comme attendu). L'erreur est donc ailleurs que dans ce code.

Ci-dessous le code entier que j'ai utilisé :


<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Argh</title>
<style>
.series {background:yellow;margin:0;padding:0;font-size:0;}
.series li {display:inline-block;margin:0;padding:0;list-style-type:none;}
</style>
</head>
<body>

<ul class="series">
    <li><img src="1.png" class="autoW"></li>
    <li><img src="2.png" class="autoW"></li>
    <li><img src="3.png" class="autoW"></li>
    <li><img src="4.png" class="autoW"></li>
</ul>

<script>
window.onload = function autoWidth() {
	/*Je cible le premier élément "series" de mon html*/
	var ul = document.getElementsByClassName("series")[0];
	/*Je cible l'ensemble des éléments de la classe autoW, les img donc*/
	var li = document.getElementsByClassName("autoW");
	/*J'en récupère la longueur*/
	var liLength = li.length;
	alert(liLength+" "+li[ 0 ].offsetWidth);
	/*J'initialise la longueur de ul*/
	ul.style.width = 0 + "px";
	/*Je crée une boucle for pour additionner la longueur de chaque img à ul*/
	for (var i = 0; i < liLength; i++) {
		alert(ul.offsetWidth);
		ul.style.width = (parseInt(ul.offsetWidth) + parseInt(li[ i ].offsetWidth)) + "px";
	}
	alert(ul.offsetWidth);
}
</script>

</body>
</html>


En ce qui concerne le reste du code, plusieurs détails sont à revoir. Il faudrait déjà remplacer window.onload par window.addEventListerner("load",...). Ensuite, la méthode pour additionner les tailles des images me semble à revoir. Il vaudrait mieux d'abord calculer la somme de toutes les tailles des images, puis ajouter cette somme à la taille initiale de l'ul. La méthode dépend aussi beaucoup de ce que tu as comme css (y-a-t-il des borders, margin, padding, box-sizing, display:inline-block ...?).

Note enfin qu'il suffirait d'utiliser dans ton css .series {display:table;} ou .series {display:inline-block;} pour que ton ul vienne entourer tes li au plus près, sans avoir besoin du code js.

Amicalement,
Modifié par parsimonhi (18 Jun 2014 - 10:51)
Oo tu dis que çà fonctionne... bon j'ai du faire une faute de frappe alors... sinon je vais test pour le display, merci pour la réponse je te tiens au courant
Administrateur
Bonjour,

je confirme : display: table sur le parent et table-cell sur les li permet au navigateur d'adapter les "cellules" au contenu (tant qu'il n'y a pas table-layout: fixed parce qu'avec c'est l'inverse : le navigateur force le contenu à s'adapter à ce que la CSS dit en termes de largeur).
On parle bien entendu de mise en page CSS sur des éléments HTML dont la sémantique est et reste celle d'éléments de liste, pas d'éléments HTML td dont on se servirait pour de la mise en page (beurk)
Compatibilité : IE8+
Mise en page CSS avancée grâce à la propriété display par Benjamin D.C.
Modifié par Felipe (18 Jun 2014 - 11:43)
Alors j'ai supprimé tout mon script puis réécris, çà passe, très bien même mais j'ai vérifié le nombre de caractères et aucune faute de frappe... MAGIE xD

Donc çà ok résolu et je t'en remercie Smiley cligne mais j'ai aussi test la solution table et table-cell, c'est à 90% ce qu'il me fallait ^^ juste que la hauteur des cellules n'est pas gérée...

Comme c'est ul qui s'adapte à img et que les images sont plus grandes de base ben elles ne sont pas redimensionnées Smiley ohwell et là je coince xD une idée ? çà serait la solution idéale vraiment.

Encore merci tu m'as prouvé que je n'étais pas fou oO
Modérateur
Bonjour,

Quel est ton code actuel (HTML+css) pour cet ul et son contenu, et que veux-tu obtenir exactement ?

Amicalement,

<div>
    <ul class="series">
        <li><img src="1.png" class="autoW"></li>
        <li><img src="2.png" class="autoW"></li>
        <li><img src="3.png" class="autoW"></li>
        <li><img src="4.png" class="autoW"></li>
    </ul>
</div>



div {
    width: 100%;
    height: calc(100% - 192px);
}
ul {
    height: 100%;
}
li {
    width: auto;
    float: left;
}
img {
    max-height: 100%;
    height: 100%;
}

Modifié par LuCube (18 Jun 2014 - 14:18)
Alors en js j'ai trouvé la solution, j'ai mis mes img en display: block; et hop proportions ok, longueur ok etc... c'est parfait c'était vraiment un détail...

Donc un grand merci pour cette partie là Smiley cligne

Ensuite tu m'as dis que ma méthode windows.onload était moche alors j'ai utilisé :

document.addEventListener("onload", autoWidth, false);

Maintenant si tu as une idée de comment maintenir la hauteur des img avec table et table-cell c'est un plus mais vous m'avez déjà beaucoup aidé =D
Modérateur
Bonjour,

Ci-dessous, ça devrait suffire. Pas besoin de mettre quoi que ce soit pour le div et les img, et j'ai par ailleurs centré horizontalement l'ul (via margin:0 auto; sur l'ul), et centré verticalement les img (via vertical-align:middle; sur les li).


div {
}
ul {
    display:table;
    margin:0 auto;
    padding:0;
}
li {
    display:table-cell;
    margin:0;
    padding:0;
    list-style-type:none;
    vertical-align:middle;
}
img {
}


Amicalement,
Modifié par parsimonhi (18 Jun 2014 - 14:33)
Ok je vois l'idée, merci Smiley cligne

Pour finir mon :

window.addEventListener("resize", autoWidth, false);

ne fonctionne pas... c'est la première fois que j'utilise cette méthode, si tu as la patience je veux bien que tu m'explique sinon je vais continuer à chercher Smiley cligne
Modifié par LuCube (18 Jun 2014 - 14:40)
Modérateur
Bonjour,

C'est toujours un peu périlleux de gérer le "resize" event. Et en pratique, on a selon mon expérience que des mauvaises raisons de le faire.

Maintenant, si c'est vraiment nécessaire, window.addEventListener("resize", autoWidth, false); devrait faire le job la plupart du temps avec les navigateurs modernes. Si ça ne marche pas, c'est que les raisons sont ailleurs.

Amicalement,