11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,
Je suis en plein apprentissage de Javascript, je reproduis les exemples des livres que j'ai et j'expérimente, et je me retrouve nez à nez avec une erreur bizarre...
C'est tout simple à mon avis, mais bon Smiley sweatdrop

Alors voilà, je cherche à executer une fonction lors d'un click sur un <a> de cette manière :


var aFonction = document.getElementById("id1");
aFonction.onclick = fonction();


Et donc le xHTML :


<a href="#" id="id1">Lien</a>


Malheureusement rien ne se passe lors du clic sur le lien, et le gestionnaires d'erreur firefox me dit :

Erreur : document.getElementById("open") has no properties
Fichier source :  http://localhost/testjs/deroule.html
 
Ligne : 15


Quelqu'un pourrait il m'aider s'il vous plait ? Je n'y comprends rien Smiley confus
Merci !
Plus de précisions :

Il se trouve que même si je copie colle des codes qui marchent sur d'autres sites, j'ai le droit à des "object has no properties"...
Peut être que le problème n'est pas dans mon code du coup... Quelqu'un a t-il déjà rencontré ce type de problème ?

Exemple avec un code provenant de Zone HTML/XHTML :


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"  xml:lang="fr" lang="fr">
	<head>
		<title>Tests javascript</title>
	</head>
	<body>
		<script type="text/javascript">
			//<![CDATA[	
			
		function action(){
  		alert("mon action")
		}
		var momoElement = document.getElementById("idevement");
		momoElement.onclick = action;
			
			//]]>
		</script>
		<div id="idevement">Mon événement javascript</div>
	</body>
</html>


Résultat :


Erreur : momoElement has no properties
Fichier source :  http://localhost/testjs/deroule.html#
 
Ligne : 15


Smiley sweatdrop
Modifié par Isdead (07 Mar 2008 - 01:41)
Bon, je vais finir par écrire un roman Smiley ravi , j'ai trouvé une solution, provisoire je l'espère.
En mettant le script après les éléments <a>, <div>, ou autres concernés, ça marche.
Evidemment, pas top si je veux faire des appels de *.js ...
Bonjour,

C'est normal. Pour que la méthode getElementById marche, il faut que l'objet qu'elle vise ait déjà été créé dans la représentation du navigateur, que le DOM ait été chargé au moins jusqu'à ce point. Or un navigateur analyse le code source au fur et à mesure qu'il le rencontre -javascript inclus.

Quand tu places ton script dans le body avant de créer ton élément, il n'existe pas encore et donc "has no properties"... Il faut donc charger l'ensemble de tes scripts après le chargement complet de ton DOM.

Il y a deux solutions:
- soit tu lances tes scripts par un événement load sur ton body
- soit tu places tous tes éléments script à la fin de ton code source, juste avant le </body>.
Bonjour Gilles et merci.
J'aimerais à terme placer toutes mes définitions JS dans un fichier *.js appelé dans le head.
La plupart des scripts d'exemple que je vois fonctionnent de cette manière...
Alors ma question est la suivante : pourquoi ne puis-je pas faire comme tout le monde, définir mes fonctions au chargement de la page...?
Je suis désepéré Smiley decu
lut,

je pense qu'il faut reprendre courage et surtout être rigoureux.

ce prendre des has no properties dans la poire ça arrive a tous le monde.

99% des fois cela signifie que même si on croyais bien faire on a surement fais une faute d'orthographe ou de nom a un niveau ou un autre.

sinon comme le dis gilles c'est peut-être que ton code js est appelé avant la construction du html. donc ton code ne se refere a rien dans ce cas là.

1: quand je lis ton premier post tu nous montres du code travaillant juste avec un id= id1 et une erreur disant
document.getElementById("open") has no properties.

ce n'est pas le message d'erreur associé au code que tu montres impossible.

as tu bien renomer toutes les occurences de id1 en open?

2:quand je lis le second:

a écrit :
Il se trouve que même si je copie colle des codes qui marchent sur d'autres sites


c'est la meileure façon d'avoir des petites erreurs . si tu ne fais pas attention tu oublies un morceau quelquepart ou tu ne réinitialises pas une ( ou plus ) variable avec la bonne valeur.

en tout cas les messages d'erreur sont clairs.

momoElement has no properties => recherche tous les endroits ou momoElement a une definition regardes s'il n'en manque pas. regarde si tu n'apelles pas l'element trop tôt

3: enfin dans le dernier

a écrit :
J'aimerais à terme placer toutes mes définitions JS dans un fichier *.js appelé dans le head.
La plupart des scripts d'exemple que je vois fonctionnent de cette manière...
Alors ma question est la suivante : pourquoi ne puis-je pas faire comme tout le monde, définir mes fonctions au chargement de la page...?


fausse question, en fait tous le monde fais comme gilles a dit. et cela n'est en rien contraire a l'habitude de rassembler tous son code en haut dans un fichier *.js appelé dans le head. tu remarqueras par contre que le code dans le fichier *.js ne contient que des definitions de fonctions.

definitions et non pas appel de la fonction dans la grosse majorité des cas.

plus quelques definitions de variables, voir quelques operations arithmetiques et des appels de fonctions qui peuvent être appelées de suite sans risque.

par contre un appel a document.getElementById("id1") dans le header hors d'une definition de fonction va echoué. c'est trop tot on ne peux pas manipuler ce qui n'existe pas encore.
Modifié par CPascal (07 Mar 2008 - 13:03)
Hello CPascal, et merci beaucoup pour ton aide.
Je comprends mieux à présent à quoi servent les appels en head !

Pour le premier exemple, c'était pour montrer le type d'erreur que j'ai copié
document.getElementById("open") has no properties.

Dans mon script l'élement avait bien l'id "open".

En tout cas, je te remercie énormément, je m'en vais de ce pas tester cette façon de procéder, en espérant perdre un peu moins de cheveux...
Je vous tiens au courant !
Bon, après application de vos conseils, je me retrouve de nouveau coincé.
Voici mon code exact, je veux juste faire apparaitre/disparaitre un div au clic sur un autre div.

xHTML :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"  xml:lang="fr" lang="fr">
	<head>
		<title>Tests javascript</title>
		<script type="text/javascript" src="js.js"></script>
	</head>
	<body>
		<div id="cliqueur">Mon événement javascript</div>
		<div style="visibility: hidden;" id="ouvrir">BOUH!</div>
		<script type="text/javascript" src="js2.js"></script>
	</body>
</html>

Fichier js.js :
function deroule(elmnt) {
			var derouleur = document.getElementById(elmnt);
				switch (derouleur.style.visibility) {
					case "visible" :
					derouleur.style.visibility = "hidden";
					break;
					case "hidden" :
					derouleur.style.visibility = "visible";
					break;
				}
			}


Fichier js2.js :
document.getElementById("cliqueur").onclick = deroule("ouvrir");


Lors du chargement de la page, le div qui est normalement caché est visible, et le clic sur le div déclencheur d'évenement ne produit aucune action.
Néamoins si j'utilise les évenements DOM niveau 0, comme ceci :

<div id="cliqueur" onclick="deroule('ouvrir');">

... là ça marche. Smiley confus
Pour la gestion d'évènement essais plutôt comme ça :
document.getElementById("cliqueur").setAttribute("onClick", "deroule('ouvrir');");


Et je ne pense pas que le code dans le body soit nécessaire, rajoute un évènement onload a ton body comme ceci :
<body onload="start()">

Ensuite tu pourra placer ta fonction start() (ou init ou que sais-je) dans ton fichier js.js
Ta fonction start() sera donc :
function start() {
	document.getElementById("cliqueur").setAttribute("onClick", "deroule('ouvrir');");
}


Bon courage pour la suite Smiley cligne
KalNex
oui mais le js2.js est bien executé et le pb ne viens pas du fct de getElementById ici.

intuitivement j'ai ecris dedans


 div = document.getElementById("cliqueur").onclick =  
function () { deroule("ouvrir"); }


<edit>tu peux enlever le div = au debut qui servait a rien...c'est pk j'avais testé en 2 ligne au debut</edit>

et là ça a marché.

ne me demandes pas pourquoi dans le detail je ne suis pas non plus un tenor en js. je me debrouille c'est tous.

ce que j'avais deja remarqué c'est que quand tu regardes la syntaxe de addEventListener tu peux passer une fonction sans argument a un onclick, mais pas de fonction avec argument.

donc j'ai supposé que là c'etait pareil. et j'ai donc "emballer" ta fonction avec argument dans une fonction anonyme qui elle n'en avait pas.

c'est une astuce possible.
Modifié par CPascal (07 Mar 2008 - 14:28)
Merci à tous,
Je n'ai pas encore testé avec ta méthode KalNex, mais ça me parait super.
J'ai eu le temps de tester celle de CPascal, et c'est parfait, je te remercie énormément !
Merci pour cet esprit d'entraide, je viens d'arriver mais je ne repartirais pas de sitôt Smiley cligne