11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour, je vais démarrer l'apprentissage du JS donc être plus souvent dans ce thème là que j'avais jusque là délaissé. Smiley lol

Mon premier truc : faire afficher et disparaitre un DIV quand on clique sur un lien ( thème réccurent ). J'ai trouvé et testé quelques scripts, qui ne sont pas déstructif d'information en cas d'indisponibilité de JS ( que j'ai glané dans le forum ) et donc tout va bien.
Sauf que quand j'introduit PHP la dedans , il apparait un souci que je pense deviner et qui concerne l'ordre des étapes dans lequel les différentes choses sont gérées ( mais je peux me tromper aussi , la dedans je suis novice )

voila un bout de code épuré mais représentatif


<html>
<head>

<script>
function visibilite(thingId,txtAff,txtMasque)
{
var targetElement; var targetElementLink;
targetElement = document.getElementById(thingId) ;
targetElementLink = document.getElementById(thingId+'Link');
if (targetElement.style.display == "none")
{
targetElement.style.display = "block" ;
targetElementLink.innerHTML = txtMasque ;
} else {
targetElement.style.display = "none" ;
targetElementLink.innerHTML = txtAff ;
}
}
</script>
<script>
function cache_si_JS_actif()

{
	for (var i = 1 ; i <= 4 ; i++) {
	document.getElementById('Div'+i).style.display="none";
	}
}
window.onload = cache_si_JS_actif;
	/* Si JS est actif chez le client, la fonction cache_si_JS_actif est appelée.
	Dans le cas contraire, rien ne se passe.*/
</script>

</head>
<body>

<a href="javascript:visibilite('Div1','Afficher','Masquer');" id="Div1Link">Afficher<noscript> | Ne fonctionne pas | Javascript est désactivé sur votre machine)</noscript></a>
<div id="Div1" syle="display=''">
<p>La grotte a toujours un profil horizontal, comme une galerie, et ce dernier est model&eacute; par l’eau. La caverne quant &agrave; elle, r&eacute;sulte g&eacute;n&eacute;ralement d’un mouvement de terrain et constitue une cavit&eacute; de plus grande envergure.</p>
</div>


</body>
</html>


Alors on le comprend, ce script joue sur la propriété display
: none ou block que prend l'attribut Style des balises Div "i" ou i est un chiffre.
Si est actif , le DIV est caché jusqu'a ce qu'on clique sur le lien s'ouvre et se referme a volonté
Si JS est désactivé, alors display est sur ' ' , donc le paramètre par défaut donc block , donc le DIV s'affiche.

ce script fonctionne donc parfaitement jusqu'a ce qu'on mette du php et du sql la dedans, qui " annule " l'effet de la fonction cache_si_JS_actif().

voila le bout de code différent avec PHP qui génèrer non pas un DIV mais X div dont le contenu provient de la BDD ou on recupere entre autre l'ID de la ligne poru etre sur que la base crée des id="DIVx" ou x est unique....


while ( $foo=mysql_fetch_array($bar))
{
echo '<a href="javascript:visibilite(\'Div'.$foo['DIV_ID'].'\',\'Afficher\',\'Masquer\');" id="Div'.$foo['DIV_ID'].'Link">Afficher<noscript> | Ne fonctionne pas | Javascript est désactivé sur votre machine)</noscript></a>
<div id="Div'.$foo['DIV_ID'].'" syle="display=\'\'">';}


Ce code marche très bien aussi mais la fonction cache_si_JS_actif appelée au window.onload , elle ne marche plus et donc tout apparait...

ma question ( pffff ...on y arrive !)

Qu'est ce que je fais mal ? Normalement je crois comprendre que le PHP est d'abord généré par le serveur et normalement le JS s'execute après donc tout div qui ressemble a id=" div'x' devrait donc etre affecté par la fonction et les div se cacher mais ce n'est pas le cas.....

J'ai aussi essayé d'enlever le window.onload et de mettre le script a la fin du <html> ou meme dans le php lui même mais rien n'y fait !

j'en suis la ......et ne vois plus quoi essayer d'autre mais c'est certainement ma meconnaissance du JS qui m'empeche de trouver ...
Modifié par RoseGrenouille (24 Mar 2007 - 15:38)
Le php genére du html et window.onload permet d'executer le script aprés le chargement complet du html, donc le probléme ne peut pas venir de là.
Peut-être regarde le code source et vois si le nom de tes id généré par php correspondent bien.
Une autre methode c'est de tester ton script avec des alert.
par exemple:
alert("debut script") au début de la fonction, tu sais que le script se lance.
alert(targetElement.id) tu verifie que ton id est bien presente.
etc...
Par contre ton script est super compliqué pour rien. Tu n'as pas besoin de innerHTML pour applique display:none sur un div
document.getElementById(thingId).style.display = 'none'; suffit largement.
ensuite tu drevrais eviter les a onclick="" au profil de script qui n'on pas besoin de javascript dans le html (non-intrusif Smiley cligne ).
Salut RoseGrenouille,

A première vue je dirai que document.getElementById('Div'+i) de ta fonction cache_si_JS_actif renvoi null pour une valeur de i. Si j'étais toi je créerai un Array avec toutes les valeurs que doit prendre i avec PHP, c'est à dire tous les $foo['DIV_ID']. Du genre :
<script type="text/javascript">
  var myDivsId = [];
  <?php while($foo=mysql_fetch_array($bar)): ?>
  myDivsId.push(<?php echo $foo['DIV_ID']; ?>);
  <?php endwhile ?>
  
  window.onload = cache_si_JS_actif(myDivsId);

  function cache_si_JS_actif(myDivsId) {
    for(var i=0; i<=myDivsId.length; i++)
      document.getElementById('Div'+myDivsId[ i ]).style.display="none";
  }
</script>

De sorte que chaque id crée avec cette boucle corresponde exactement à un id de div.

Dis moi si je suis complètement à côté de la plaque car là c'est la fin de la semaine et dure journée en plus Smiley cligne
Modifié par Ze Nenex (23 Mar 2007 - 18:06)
matmat a écrit :
ensuite tu drevrais eviter les a onclick="" au profil de script qui n'on pas besoin de javascript dans le html (non-intrusif Smiley cligne ).


Hello MAtmat,

Euh je ne sais pas si c'est moi ou si c'est vendredi ou les deux mais je ne vois pas de onclick dans mon code ..... Smiley murf

pour ce qui est du php , oui il écrit correctement dans le code source....sauf que ca amene une autre question...

Si ma fonction fonctionnait Smiley biggol , et remplacait effectivement display:'' par display 'none' , est ce que je suis censé le voir dans le code source de la page ? Si ce'st le cas alors ma fonction ne fonctionne pas ( re Smiley biggol )

@ze nenex: ouais ca me parait bien une possibilité d'un truc comme ca , je vais tester ca dans les heures qui viennent ( j'ai pas mon laptop avec moi ni mes identifiants a la BDD Smiley confused )
pardon <a href="javascript:visibilite()" c'est un peu la même chose que onclick c'est éviter, je me suis emmelé
ok , je pensais devenir fou...... Smiley biggol


a écrit :
matmat a écrit :
ensuite tu drevrais eviter les a onclick="" au profil de script qui n'on pas besoin de javascript dans le html (non-intrusif ).


euh....je demande pas mieux mais comment je déclenche l'evenement si je ne cliques pas sur mon lien ?

Allez tiens , exemple en ligne , ce sera plus clair ( ne fonctionne pas si JS est désactivé pour le moment Smiley confused )
Modifié par RoseGrenouille (23 Mar 2007 - 18:55)
non biens sur il est dans un fichier externe caché .....c'est pour ca que ca rend les choses plus interessantes ...... Smiley langue

je suis désolé mais j'ai pas d'acces web avec ma machine donc pas acces a mes fichiers, ce qui fait que pour copier -coller des bouts de code ici , je suis obliger de passer par une cle usb ....bref le bordel...

le JS est sur le meme domaine a js/openhide.js ( j'evites le lien complet....)
Salut,
matmat a écrit :
pardon <a href="javascript:visibilite()" c'est un peu la même chose que onclick c'est éviter, je me suis emmelé
Ce n'est pas vraiment pareil, puisque l'attribut onclick n'est pas en lui-même inacessible, si l'attribut href est correctement défini.
En fait ce que je ne vois pas c'est l'action du js (le js je l'ai vu a coté de tout un tas de librairies qu'on ce demande un peu a quoi ça sert), quel liens sont concerné et que veux tu faire apparaitres? A part ça, joli site.
Bon j'ai trouvé par moi-meme sur la base de vos indications....

En fait le script JS cherche tous les DIV ayant un ID de la forme Div'x' ou x commence a 1 et incremente de 1 a chaque fois que la boucle est executée.

Moi dans mon script PHP, j'appellais la valeur de l'ID de ma ligne contenant l'enregistrement dans ma table mysql, histoire d'etre sur de pas avoir de doublons.

Effectivement pas de doublons, mais aucune garantie que ca commence a 1 et que il n'y ait pas de 'saut' dans l'incrementation ( genre 1, 2, 5, 6, 7 ) parce que des lignes ont ete effacees de la table.

Le script JS apparament ne s'execute pas s'il y a un trou dans l'incrementation, ce qui etait le cas....

J'ai donc tout simplement dans mon script php avant la boucle defini une variable $id=1 que j'ai incrementé avec $id++ dans la boucle comme ca tous les DIV'i' se suivent et l'incrementation commence bien a 1.

Aussi bête que ca....
aussi bête que ça mais pas si simple!
Pour vérifier tes scripts, je te conseil firebug pour firefox, ça aide vraiment, il t'indique par exemple si ton script ne trouve pas une id. Par rapport au 'non-intrusif', l'idée c'est de faire une boucle qui parcour les élements sur lesquels tu rajoute ton comportement
Par exemple ce code là te permet de rajouter un evenement onclick sur toutes tes balises h3 a l'interieur d'une div avec une id 'context'.

var elTitle = getElementById('context').getElementsByTagName('a');  
    for (I = 0; I<elTitle.length; i++) {
      elTitle[I].onclick = function(){        
      }
    }


Une méthode étant de construire ton site sans js, et un fois qu'il fonctionne bien rajouter ce genre de petite subtilité.

Concernant le nom des divs, je fais comme ça:
J'appelle le bouton par exemple id="+open2" et la div sur lequel elle agit id="open2" et ensuite grâce a un replace (replace("+", "");) le click sur l'élement +openx agit sur openx, le x venant de ma base de donné, comme ça pas de probléme de suite de numéro discontinu, le x etant l'id de l'article.

Un autre avantage de cette methode c'est que tu peux selectionner toute tes id contenant "open" grâce a id.indexOf("open").

Par exemple pour ouvrir et fermer des div ça donne ça:
function hideAndShow(){

var elTitle = document.getElementById('context').getElementsByTagName('a');
  
for (var I=0; I<elTitle.length; I++) {
  if (elTitle[I].id.indexOf("open") != -1) {

    elTitle[I].onclick = function(){
      elText = document.getElementById(this.id.replace("+", ""));
        if (elText.style.display == 'none'){
          elText.style.display = 'block';
        }
        else{
          elText.style.display = 'none';
        }
      return false;
    }
  }
}

}


C'est une méthode personnelle, mais avec les même contraintes que toi de code produit par php.

<h3><a id="+open54">Title 1</a></h3>
    <div id="open54" style="display:none">
    Texte
    </div>


cela peut-être n'importe quel numéro il suffit que ce soit le même entre le div et le titre
Modifié par matmat (24 Mar 2007 - 18:31)
ha bon je savais pas...
C'est que je valide plus... Smiley confused
Ceci dit je me doutais bien que c'était un peu foireux d'utiliser ce caractére ainsi, je vais plutot opter pour "get_open" et "open" ou juste "_open" ou je sais pas il faut que je trouve un truc bien, clair, comprehensible et valide.
Si vous avez une idée...
matmat a écrit :
aussi bête que ça mais pas si simple!
Pour vérifier tes scripts, je te conseil firebug pour firefox, ça aide vraiment,

Oui je l'avais firebug mais comme je n'avais jamais cherché a l'utiliser , ca m'aidait pas vraiment et en fait ce coup la j'ai ete l'utiliser et c'est lui qui m'a mis sur la piste de resoudre mon problème....

Depuis mon dernier post, j'Ai été lire un peu sur le JS non intrusif , et en fait j'Ai bien pigé que ca consiste a externaliser les script et a les apliquer via les attributs entre autres.. dans les balises tout comme on le fait avec les styles. Bien compris ton truc avec le + a rajouter lors de chaque changement d'etat entre '' et 'block' ( meme si c'est pas valide Smiley cligne .

C'est effectivement un bon principe et comme je pars d'a peu pres zero la dedans, autant prendre le bon pli tout de suite....

J'aime bcp les noms de variable en spanglish en passant ('eltitle)' Smiley ravi

a écrit :
Une méthode étant de construire ton site sans js, et un fois qu'il fonctionne bien rajouter ce genre de petite subtilité.


Oui c'est pas mal ce que je fais....1/structure ; 2/style ; 3/donnees generees dynamiquement et maintenant 4/ comportement cote client.

a écrit :
le x venant de ma base de donné, comme ça pas de probléme de suite de numéro discontinu, le x etant l'id de l'article.

Ben la pas forcement d'Accord . ton x_ID peut bien faire 1.2,4.6,7 parce que l'enregistrement relatif la ligne 3 a ete effacée Smiley decu

Et j'ai l'impression que c'est ca qui fait planter le script....d'ou mon idée d'incrementer une variable php , independamment de la BDD.....

a écrit :
Si vous avez une idée...


Ben moi je proposerais "open" et "not_open" , je pense que ca peut pas etre plus clair ! Smiley cligne
heu... je crois qu'on c'est pas trop compris, en fait le coup du numéro ça vat justement dans ton sens.
Explications:
Le titre et le texte viennent du même article, donc ils ont la même id, peu importe justement si la précédente est 3 ou 45.
L'id du titre ressemble donc a ça id="get_open<?php echo $id_article ?>" et l'id du texte a ça id="open<?php echo $id_article ?>"
(j'ai remplacé le + par get_, du coup dans le js ça fait replace("get_", "")).
Donc le click sur le titre agit forcement sur le texte correspondant.
C'est la méthode que j'utilise tout le temps, et même si le numéro de mes id ne se suit quasiment jamais ça marche toujours.

PS: c'est vrai qu'entre les tutos en anglais, Alsa en français et mes clients Mexicain je me perd un peu les pédales dans les langues. Smiley lol
Modifié par matmat (25 Mar 2007 - 23:25)
a écrit :

heu... je crois qu'on c'est pas trop compris


Si si parfaitement.....moi non plus je n'ai aucun souci avec le fait d'avoir le meme numero entre le DIV a ouvrir et le lien qui commande ....

La ou toi tu n'a pas de problème , c'est a dire dans le fait qu'il y ait des trous dans ton incrementation, visiblement moi j'en ai , mais bon en meme temps on va pas passer des jours la dessus. Mon niveau de JS est tellement excellent que je devrais sans doute regarder si j'Ai pas une C*****lle quelque part ailleurs avant d'avoir des certitudes

Smiley lol

Je vais recoder mon script en " inobstrusivo " aujourd'hui regarder un peu comment ca marche.

Merci pour les commentaires. Sujet résolu. Next Topic Smiley ravi