11548 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour,

Je travaille actuellement sur un projet web en (x)html / CSS, avec utilisation d'un peu de php et de javascript.

Mon problème est le suivant : mon client veut que éléments de listes non ordonnées de mon bloc de contenu changent de couleur comme l'image ci-dessous :

upload/12897-listerando.jpg

Autrement dit, il s'agit d'avoir trois couleurs de puces, qui créent une succession du genre "rouge-orange-gris-rouge-orange-gris"...dans la liste.

Je cherche une façon "d'automatiser" ce changement sans avoir à spécifier une "class" à chaque <li></li>, comme cela est le cas dans l'exemple suivant:

<ul>
<li class="rouge">Banane</li>
<li class="orange">Poire</li>
<li class="gris">Prune</li>
...
</ul>


J'ai en effet affaire à des usagers-clients non expérimentés... Je préfère éviter tout ce qui impliquerait une insertion "manuelle" de code lors de modifications futures du site.

J'espère que mon premier sujet sur Alsacréations aura été clair Smiley langue . Merci pour toute suggestion éventuelle!
Modifié par nalita33 (23 Jun 2007 - 22:12)
Salut nalita33,

Tu peux faire ça en javascript, comme ça par exemple :
var lis = document.getElementById('tonUl').getElementsByTagName('li');
var lastColor = 'gris';

for (var j=0; j<lis.length; j++) {
    if (lastColor == 'gris') {
        lis[j].style.listStyleImage = 'url(puceRouge.png)';
        lastColor = 'rouge';
    } else if (lastColor == 'rouge') {
        lis[j].style.listStyleImage = 'url(puceJaune.png)';
        lastColor = 'jaune';
    } else if (lastColor == 'jaune') {
        lis[j].style.listStyleImage = 'url(puceGrise.png)';
        lastColor = 'gris';
    }
}
Il doit y avoir moyen de simplifier, mais en gros c'est ce principe.
marcv a écrit :
Il doit y avoir moyen de simplifier

Notamment pour prendre en compte les ul qui n'ont pas d'id spécifique ?
a écrit :
Notamment pour prendre en compte les ul qui n'ont pas d'id spécifique ?
Hmm, non, je ne me référais pas à l'adaptation que nalita33 aura à faire à son cas particulier. Comme tous les codes d'exemple, il n'est bien sûr pas à copier/coller tel quel. Si son ul n'a pas d'Id, si ses images ne sont pas des png, si elles ne sont pas au même niveau d'arborescence que le script, etc. il faut bien évidemment adapter Smiley rolleyes .
Je parlais plutôt d'une éventuelle simplification du code. J'ai juste donné une ligne directrice, rapidement, sans vraiment réfléchir en profondeur; peut-être que quelqu'un aurait une manière de faire tout ça en deux fois moins de lignes, je sais pas...
Modifié par marcv (21 Jun 2007 - 11:34)
Salut,

Comme je suis une bille en JS, je me serais fait un pti bout de php avec un peu de style dans le code.
  <style type="text/css">
* { margin: 0; padding: 0;}

#menu{
width: 400px;
margin: auto;
border: 1px solid black;
list-style-type: none;
}

li {
margin-bottom: 5px;
padding-left: 16px;
width: 100px;
height: 19px;
text-align: center;
background-color: lime;
background-position: 0% 50%;
background-repeat: no-repeat;

}

li a{
text-decoration: none;
}

</style>
</head>
<body>
<ul id="menu">
<?php
$item = 6;//---------- nombre d'item
$boucle = 1;
$compteur = -1;
$image = array ("puce1.gif", "puce2.gif");// tableau contenant le nom des fichiers puce
for ($boucle= 1; $boucle <= $item; $boucle++)
{
	$compteur++;
	if($compteur > 1)// contrôle changement de série de puce 
	{$compteur = 0;}
	echo '<li style="background-image: url('.$image[$compteur].');"><a href="#" >item</a></li>';		
}	
?>				
	</ul>
</body>


Je suppose que le nombre d'items et le texte des liens (j'ai décrété unilatéralement que ce sont des liens Smiley lol mais bon !) sont accessible en php.
Autant de réponses en si peu de temps, je suis choyée Smiley smile Merci!

J'avais oublié de dire que ce style de liste sera le style décrété pour toutes les listes non ordonnées figurant dans mon bloc #contenu ( #contenu ul). Donc, je ne compte pas mettre d'id spécifique à mon <ul> et j'ajusterai le code en conséquence Smiley smile .

Du premier coup d'oeil, les deux solutions proposées jusqu'à présent par Marcv et Ghost ( js et php) semblent correspondre au genre de liste qire le boulot. Je vais essayer

Pour l'instant, je crois que celle en javascript sera plus avantageuse à ma situation parce que (1) mon usager doit avoir un minimun de contact avec le code, (2) pouvoir ajouter lui-même les listes colorées avec la facilité d'un néophyte , et (3) pouvoir créer plusieurs listes de longueur différente au sein d'une même page sans avoir à rajouter du code dans cette situation..

Dans le cas de la solution php, également intéressante, j'aurais peut-être pu essayer un "php include" avec un fichier dédié où l'usager inexpérimenté entre le nombre d'éléments de liste. Toutefois, ça se complique avec deux listes listes, car si j'ai bien compris, un ajout de code php doit être prévu dans ce cas...
Comme c'est de la cosmétique :
- attribuer un style par défaut avec une puce donnée pour tous les items ;
- faire trois classes en CSS avec les différentes puces colorées ;
- utiliser Javascript pour attribuer une classe donnée à chaque item de liste.

Si JS est désactivé, on aura la même puce par défaut partout.
Autant de réponses en si peu de temps, je suis choyée Smiley smile Un gros merci à tous!

J'avais oublié de dire que ce style de liste sera le style décrété pour toutes les listes non ordonnées figurant dans mon bloc #contenu ( #contenu ul). Donc, je ne compte pas mettre d'id spécifique à mon <ul> et j'ajusterai le code en conséquence Smiley smile .

Du premier coup d'oeil, les deux solutions proposées jusqu'à présent par Marcv et Ghost ( js et php) semblent correspondre au genre de liste que je veux créer. Je vais les essayer toutes les deux.

Pour l'instant, je crois que celle en javascript sera plus avantageuse à ma situation parce que (1) mon usager doit avoir un minimun de contact avec le code, (2) pouvoir ajouter lui-même les listes colorées avec la facilité d'un néophyte et que tout s'ajuste automatiquement sans avoir à rajouter du code. Et puis, côté accessibilité (une autre de mes priorités), je crois bien que la liste demeurera accessible en cas de désactivation du javascript.

Dans le cas de la solution php, également intéressante et accessible, j'aurais peut-être pu essayer un "php include" avec un fichier dédié où l'usager entre le nombre d'éléments de liste. Toutefois, ça se complique avec deux listes, car si j'ai bien compris, un ajout de code php doit être prévu dans ce cas...

Encore merci, je vous reviens une fois mes essais js et php réalisés!
a écrit :
Comme c'est de la cosmétique :
- attribuer un style par défaut avec une puce donnée pour tous les items ;
- faire trois classes en CSS avec les différentes puces colorées ;
- utiliser Javascript pour attribuer une classe donnée à chaque item de liste.

Si JS est désactivé, on aura la même puce par défaut partout.


Merci Florent V. pour cette synthèse...
Et désolée de mon double post... Smiley confused une erreur semble avoir eu lieu... comme si mon post s'était expédié avant la fin... j'ai du toucher à qqchose.. je ferai attention dorénavant Smiley smile
Rebonjour

J'ai tenté la solution de Marcv, en ajustant bien sûr le code à mon
travail (source et nom des images, id personnalisé, etc.). Mais je
n'ai pas réussi à faire fonctionner le script. J'ai vérifié, mon
script est correctement appelé dans mon fichier html, donc le problème
n'est pas là non plus...

J'ai aussi tenté la solution de Florent V.... J'ai essayé une attribution de class (className) pour remplacer le changement d'image de puce dans l'exemple de Marcv...
sans succès non plus...

Voilà qui confirme ma "néophytude" en matière d'utilisation de javascript pour le contrôle des styles Smiley smile ...
Pourrais-je avoir un petit coup de main pour appliquer concrètement
les recommandations de Florent V.? Ou pour faire fonctionner l'exemple
de Marcv?

Merci encore!
Voici ce que j'ai fait... J'ai préféré vous présenter un exemple "en chair et en os" : http://pages.usherbrooke.ca/eviau/essai/

Vous y trouverez 2 fichiers. Le premier, "essai1", a été réalisé en tentant l'exemple de Marcv. Le second, "essai2", est une tentative d'utilisation de className pour réaliser la proposition de Florent V. Ces fichiers html sont respectivements liés à bullet1.js et à bullet2.js (situés dans le dossier js, avec les images de puces en .jpg)
Modifié par Florent V. (22 Jun 2007 - 19:05)
Je suis une bille en Javascript mais... est-ce qu'il ne faut pas charger les scripts liés dans le <head> via un attribut onload sur <body> (ou autre moyen) ?
a écrit :
est-ce qu'il ne faut pas charger les scripts liés dans le <head> via un attribut onload sur <body> (ou autre moyen) ?



À ce que je sache, je ne crois pas... Du moins, je suis parvenue à faire fonctionner un autre script lié javascript (menu) avec la même façon de procéder que ce que vous voyez dans mon fichier (c.-à-d. appelé en fichier externe).... Je ne suis pas encore très bonne en js, mais j'ai cru comprendre que ce sont les fonctions qui ne peuvent pas s'exécuter toutes seules... Il faut les appeler d'une manière ou d'une autre... Dans le fichier bullet.js, il ne semble pas y avoir de fonction (), seulement des variables et des conditions... du moins, ce que j'en comprends.

Vu le tournant Javascript de l'affaire (et vu mon utra-incompétence en js Smiley biggol ), serait-il plus approprié de migrer mon sujet dans la partie du forum dédiée aux langages php, js, etc?

Merci !
Florent V. a écrit :
est-ce qu'il ne faut pas charger les scripts liés dans le <head> via un attribut onload sur <body> (ou autre moyen) ?
nalita33 a écrit :
À ce que je sache, je ne crois pas...

Et si ! Smiley smile C'est d'ailleurs la seule chose qui empêche ton code de fonctionner.
C'est tout bête : quand ton navigateur lit ton code, il tombe sur le code javascript très tôt (dans le head). La première instruction lui dit de trouver l'élément avec l'id "pcouleur". Comme le navigateur n'est même pas encore arrivé au body, il n'a pas encore construit ta <ul>. Donc pour lui l'élément pcouleur n'existe pas. Donc erreur Javascript. Donc arrêt de l'interprétation du code. Donc rien à l'écran.
Solution : il faut dire à javascript de n'éxécuter le code qu'une fois que la page est chargée. Englobe tout ton code dans une fonction et demande à ce que cette fonction soit exécutée lorsque la page aura lâché l'événement "load" :
function maFonction() {
// mets tout ton code ici
}

window.onload = maFonction;


Quant aux deux solutions, je pensais au tout début que tu ne voulais pas du tout de classes. La solution que je t'ai proposée suivait ce principe. Mais, comme j'avais visiblement mal compris, ne réfléchis même pas, fais comme te dit Florent. L'utilisation des classes te permet ici une meilleure séparation style/comportement.
Modifié par marcv (24 Jun 2007 - 16:43)
a écrit :
Solution : il faut dire à javascript de n'éxécuter le code qu'une fois que la page est chargée. Englobe tout ton code dans une fonction et demande à ce que cette fonction soit exécutée lorsque la page aura lâché l'événement "load" :


Youppi! L'ajout d'une fonction et d'un truc pour charger la fonction (window.onload) vient régler le problème...

Le résultat (il me restera à compresser les images pour un téléchargement plus rapide...):

http://pages.usherbrooke.ca/eviau/essai/puce_fonctionnel.html


Ce qui, du point de vue du code, me donne ...

Style css

#pcouleur{list-style-type:none;
list-style-image: url(js/puceorange.jpg);
}
.prouge {list-style-image: url(js/pucerouge.jpg);}
.porange {list-style-image: url(js/puceorange.jpg);}
.pgrise {list-style-image: url(js/pucegrise.jpg);
}


Javascript (inséré dans un fichier externe appelé dans head)

function puceMulticolore() {

var lis = document.getElementById('pcouleur').getElementsByTagName('li');

var lastColor = 'gris';

for (var j=0; j<lis.length; j++) {

    if (lastColor == 'gris') {
        lis[j].className = 'prouge';
        lastColor = 'rouge';

    } else if (lastColor == 'rouge') {
        lis[j].className = 'porange';
        lastColor = 'orange';

    } else if (lastColor == 'orange') {
        lis[j].className = 'pgrise';
        lastColor = 'gris';
    }

}
}

window.onload = puceMulticolore;


Un gros merci pour l'aide et pour les explications reliées au "pourquoi" du code à insérer. Smiley biggrin
Je me permets une dernière petite question. Le script dont j'ai fait la synthèse dans mon dernier post prévoit le changement dynamique des puces en images d'une liste dont l'id est "pcouleur". (voir extrait ci-dessous).

function puceMulticolore() {

var lis = document.getElementById('pcouleur').getElementsByTagName('li');

... 



Or, depuis le dernier post, j'ai fait quelques ajustements pour que toutes les listes non ordonnées de mon bloc #contenu aient le même comportement. J'ai donc ajusté en conséquence le code :

var lis = document.getElementById('contenu').getElementsByTagName('li');


Bien entendu, cette nouvelle façon de faire exclut l'emploi de l'ID "pcouleur" dans mon code HTML.

Cela fonctionne... même un peu trop Smiley rolleyes ! Vous devinerez que les listes numérotées se transforment elles aussi en listes à puces colorées, puisque tous les <li> sont détectés.

Pour régler le problème, j'ai essayé de me documenter sur getElement, puis j'ai bidouillé ce qui suit, sans succès toutefois... Suivant le principe orienté objet, j'ai voulu restituer l'ordre de parcours (la "hiérarchie") du code html --> "id - ul - li" . Probablement une erreur de syntaxe dans ce qui suit, mais trop peu expérimentée pour corriger... Smiley biggol

var lis = document.getElementById('contenu').getElementsByTagName('ul').getElementsByTagName('li');


ou encore ceci

var lis = document.getElementById('contenu').getElementsByTagName('ul','li');


J'imagine qu'il y a certainement un moyen de spécifier qu'on cible uniquement les <li> des listes <ul> du bloc dont l'ID est "contenu"... j'aurais juste besoin d'un dernier petit coup de pouce du côté de la syntaxe pour en arriver là.

Merci!
Hello,

nalita33 a écrit :
var lis = document.getElementById('contenu').getElementsByTagName('ul').getElementsByTagName('li');

Quand tu cibles un élément en restituant, comme tu dis, "l'ordre de parcours (la "hiérarchie") du code html", seul le dernier élément peut être multiple. Tous les parents doivent être des éléments uniques bien ciblés. Donc, décomposons :
- document : ok, il ne peut y en avoir qu'un
- getElementById('contenu') : pareil, étant donné qu'en html les id sont uniques
- getElementsByTagName('ul') : là par contre ça va pas. tu remarqueras d'ailleurs le "s" pluriel a "elements" dans le nom de la fonction. Cette fonction renvoie toujours une liste d'éléments (lorsqu'il n'y en a qu'un, elle renvoie une liste avec un élément). Donc ça bloque ici.

Solution(s) :
En gardant le code qui fonctionnait, tu peux simplement rajouter un test sur chaque li pour savoir si son parent est une <ul> :
...
for (var j=0; j<lis.length; j++) {
    if (lis[j].parentNode.tagName == 'ul') {
        //code
...
Ça a l'inconvénient que, comme le compteur lastColor n'est pas remis à zéro (en fait à "gris") à chaque début de <ul>, tu n'auras pas la même couleur de puce au début de chaque <ul>. Si cela a une importance pour toi, il vaut mieux une autre solution : passer en revue chaque <ul>, l'une après l'autre, et effectuer sur chacune le reste du code (recherche de <li> et application des puces) :
function puceMulticolore() {
    var uls = document.getElementById('contenu').getElementsByTagName('ul');

    for (var a=0; a<uls.length; a++) {
        var lis = uls[a].getElementsByTagName('li');
        var lastColor = 'gris';
        for (var j=0; j<lis.length; j++) {
            if (lastColor == 'gris') {
                lis[j].className = 'pgrise';
                lastColor = 'rouge';
            } else if (lastColor == 'rouge') {
                lis[j].className = 'prouge';
                lastColor = 'orange';
            } else if (lastColor == 'orange') {
                lis[j].className = 'porange';
                lastColor = 'gris';
            }
        }
    }
}

window.onload = puceMulticolore;

Modifié par marcv (23 Jun 2007 - 08:01)
Bonjour Marcv,

La première solution (le test pour les <ul> depuis parentNode.tagName) me convient parfaitement, même si les puces ne débuteront pas toujours par la même couleur. Je suis quand même très contente du second exemple, ça me permet d'approfondir ma compréhension de javascript. Et en plus, ça risque d'être utile à d'autres qui veulent créer cet effet.

Encore une fois,merci pour le code et pour les explications très pédagogiques! Smiley biggrin Un autre sujet de résolu!
Désolée de vous déranger encore... Un nouveau problème vient de survenir dans l'exécution de mon script sous firefox 1.0.7 (en Windows), alors que tout est ok dans Internet Explorer 6 et dans Opera 9.

Lorsqu'on atteint la page contenant mes puces multicolores, ça fait ça sous firefox :

upload/12897-prob.png

Alors que sous Opera et IE, ça donne :

upload/12897-noprob.png

Dans le cas de Firefox, je tiens à préciser que le script se met à fonctionner si on rafraîchit la page (F5), mais que lors du téléchargement initial, on ne voit que les puces oranges. Cela demeure ainsi tant et aussi longtemps que la page n'a pas été rafraîchie...

Voici l'adresse où est logé le fichier html et le js (dans le répertoire js).
http://pages.usherbrooke.ca/eviau/essai/puce_fonctionnel.html

Vraiment aucune idée du problème, ni de la façon la plus élégante pour s'en sortir... Bien entendu, je n'ai pas désactivé js de ce navigateur Smiley smile .

Merci à l'avance!
Nalita33
Pages :