Javascript appel de fonction sur OnClick


#1

Voici un temps significatif que je suis coincé sur un problème qui parait évident:

J’ai une fonction toute bête

// Function change variable value
function SetarrVariable(Index,Valeur)
{
arrVariable[Index] = Valeur;
alert (' Val == ' + Valeur );
}

que j’appelle dans du php en 2 endroits:

echo ("<script type=\"text/javascript\"> SetarrVariable(0,\"INIT1\") ;</script>");

et

echo ("<a> <span class=\"bouton\" id=\"Page1Variable1\" onClick=\"text/javascript:SetVariable(arrVariable[0], \"OK1\");\"> Page1Variable1 </span></a>");

Dans la seconde ligne, sur le “onClick”, ça n’appelle jamais la fonction.

Le 2 lignes sont dans le même php et se suivent
J’ai même une 3ème ligne “OnClick

echo ("<a> <span class=\"bouton\" id=\"Status\" onClick=\"javascript:alert (arrVariable[0]);\"> Status </span></a>");

Qui marche.

Quelqu’un aurait il une idée ou une piste où chercher, j’ai essayé toutes les idées que j’avais. Je tourne en rond maintenant.

merci d’avance


#2

J’ai à peu près… rien compris la.
En outre dans ton code tu n’appelles jamais SetarrVariable()


#3

Bonjour,

Déjà, merci d’utiliser la balise code pour faciliter la lecture.
Sinon, je ne comprends pas ton objectif. Tu veux appeler une fonction PHP via du javascript ? Ceci n’est pas possible.

Le cas contraire, merci d’expliciter le problème.


#4

Désolé, Je suis débutant sur le forum.
Oui effectivement, en relisant ce qui ressort sur le forum, ma question est incompréhensible!
je vais reposter en utilisant la balise code. Mon problème sera plus clair


#5

Voici ma fonction qui se trouve dans un fichier fichier.js + le code php

Le premier SetarrVariable marche bien, ce qui montre que ma fonction est OK et visible
La troisième ligne qui fait une alerte JS marche bien, ce qui montre que la syntaxe du “onClick” est bonne.

Et par contre ma seconde ligne ne marche pas le “OnClick” n’appelle jamais le SetarrVariable.
J’y ai passé plusieurs heures. SI quelqu’un aune idéee d’une direction ou chercher.
Je précse que mon code est en php car dans un fichier include pour rendre l’html principal plus lisible.


#6

Je comprends mieux le problème.

Tout d’abord, saches que tu peux ne pas passer par echo et directement afficher le contenu à afficher (en sortant des balises <?php … ?>). Ça pourrait simplifier la lecture, notamment en ayant la coloration syntaxique JS et non PHP-string.

Sinon, pourquoi mets-tu onClick="text/javascript:…" et non pas onClick="javascript:…" ? Bien que j’ignore si la syntaxe est correcte, je ne l’ai jamais vue auparavant.
Si je lis bien le code, tu as une fonction SetVariable et tu appelles SetarrVariable. Dans ce cas, ça ne peut pas marcher (par contre, je ne vois pas comment ça peut marcher pour la première ligne).

Sinon, d’une manière générale, utiliser les attributs onClick est considéré comme étant une mauvaise pratique. À la place, préfère addEventListener à utiliser en javascript, plutôt qu’en PHP (à juger selon le contexte du projet, bien évidemment).


#7

Tout d’abord, un grand merci pour cette réponse.

Oui, il y a encore une erreur dans mon post, je n’ai pas montré la bonne fonction.

j’ai enlevé le “text/”

et J’ai mis mon code html direct:

Même comportement, c’est à dire que le "onClick=“javascript:SetarrVariable(0, “NOK1”);” ne marche pas.

Je pense que je vais devoir regarder le addEventListener … de toute façon, mon but est de progresser en javascript.

Mais, je prends tout autre conseil qui pourra me faire percer ce bug (comme tout bug mystérieux!)


#8

Avec la nouvelle coloration syntaxique, l’erreur est bien plus évidente :

echo "<a><span … onClick=\"text/javascript:SetarrVariable(0, \"OK1\");\">…";

Donne le code html:

<a><span … onClick="text/javascript:SetarrVariable(0, "OK1");">…

Comme tu peux voir avec la coloration, les guillemets de ta chaîne JS n’est pas échappée, provoquant l’erreur.

La correction devrait être :

echo "<a><span … onClick=\"text/javascript:SetarrVariable(0, \\\"OK1\\\");\">…";

Donnant le code html:

<a><span … onClick="text/javascript:SetarrVariable(0, \"OK1\");">…

#9

Mauvaise pratique pas dans tous les cas.
Avec jQuery et vanilla js oui, mais par exemple avec Angular c’est une bonne pratique …Et au moins on sait quel élément HTML réagit au onclick sans devoir lire les listeners dans le fichier JS associé.
'Fin bref, c’était au passage


#10

Merci pour toutes vos réponses, une lueur d’espoir … mais sur tes conseil kneelnrise, j’ai testé directement le code html suivant

Marche toujours pas … (je regrettte mon bon vieux Ada d’il y a20 ans avec le compilo qui me disait toutes les erreurs … comme dirait certains V…x … c’était mieux avant … humour!)

Bon … je continue à chercher …


#11

Au temps pour moi, j’ai oublié qu’on était en HTML…

Regarde http://stackoverflow.com/questions/2428572/how-to-escape-single-quote, il explique tout ce qu’il faut.


#12

SUPER!

J’ai remplacé les " par &#34 ->
javascript:SetarrVariable(0, &#34NOK1&#34

et ça fonctionne !!!

merci beaucoup kneellnrise!

c’est vraiment un problème de quote! tu avais raison!


#13

Bonjour Lemimile.

Il y a beaucoup de pratiques qui rendent ton code difficile à appréhender pour toi-même et pour les autres (peut-être moins pour toi car les conventions que tu t’ai données en tant que débutant te parlent peut-être car elle te viennent d’un autre langage) mais elles sont contre-productive dans du HTML.

C’est parti pour un petit tour d’horizon de ce que je te conseil de changer à l’avenir.

Conventions et spécifications

Légende :

  • Convention : à suivre pour travailler à plusieurs mais n’est pas une obligation absolue.
  • Spécification : à suivre obligatoirement.

La casse dans les attributs HTML

  • Dans les attributs HTML type id ou class (ex : id="page1P"), tu dois écrire en minuscule les valeurs en séparant tes mots par des tiret (kebab-case). Ceci n’est qu’une convention. Leur équivalence JavaScript sera elle en camelCase (HTML : class="main-body-1", JS : mainBody1 = recupClass("main-body-1")).

  • Pour le nom des attributs HTML (ex : onClick="..."), celui-ci doit intégralement être écrit en minuscule onclick. C’est la même chose pour n’importe quel nom d’attribut, peut importe son nombre de mot (onmouseover). Ceci est une convention.

Un seul id

  • Un attribut HTML id possède une unique valeur à travers toute la page, tu ne peux donc pas avoir plus de 1 id="status". Les valeurs étant sensible à la casse, Status et status ne sont pas le même id. Ceci est une spécification.
  • Tu peux utiliser les classes pour identifier par un même nom plusieurs éléments que tu souhaites être porteur du même « id ». Puisque avec PHP par nature tu va jouer avec des fragments de HTML à travers plusieurs fichier et rarement avec une page complète, il est difficile de rester à l’abrit d’un id qui ne serait pas répéter. Utiliser les class est plus sûr.

Meta

Elles servent à placer des en-tête indicative dans le corps HTTP (plutôt que dans l’en-tête HTTP). De la même manière dans ton code, les en-tête ne doivent pas se trouver dans le corps HTML (body) mais dans l’en-tête (head). Tu ne peux donc pas placer ton en-tête <meta> ici. Ceci est une spécification.

Note : En HTML5 la balise que tu as utilisés se remplace simplement par <meta charset="utf-8">, c’est tout.

nom de function, variable, paramètres

En JavaScript les nom de fonctions s’écrive en camelCase aussi devrions nous lire setArrVariable, index, valeur, etc. La seul exception (PascalCase) est pour nommer une fonction qui peut être instanciée avec le mot clé new, ce qui n’est nul par le cas pour toi. Ceci est une convention.

usage entre simple et double quote

En JavaScript, les « ’ » et « " » sont totalement interchangeable à condition que si l’un est utilisé pour l’ouverture, ce soit bien l’autre qui soit utiliser pour la fermeture. Aussi, quand tu as besoin d’un texte de type « phrase », utilise les « " » (ex: “L’appel de la “forêt”” plutôt que ‘L’appel de la “forêt”’), pour quelque chose de type « code » utilise plutôt les « ’ » (ex: ‘setArrVariable(0, “OK1”);’ plutôt que “setArrVariable(0, “OK1”);”). Ceci est une convention.

usage de javascript: dans les attributs

Tout les attributs on* (onclick, onmouseover, etc.) contiennent du JavaScript dans leur valeur. Cela signifie que préciser javascript: en début d’attribut ne sert à rien. Par contre, dans un attribut href qui doit contenir un lien, il faut, si on souhaite y mettre du JavaScript, préciser javascript:. Ceci est une spécification.

usage de href: pour les balises a

Tu dois obligatoirement préciser un attribut href si tu utilises une balise <a>. Sinon tu dois en utiliser une autre. Ceci est une spécification.

Dans ton cas, ce qui est porteur du click c’est le <span> ton <a> ne sert donc à rien. Inverssement, si tu décides d’utiliser un <a>, tu peux te servir du href="javascript:" pour remplacer le onclick, dans ce cas ton <span> ne sert à rien.

Attention : href="" ne veut pas dire « rien » mais « je fais un lien vers la page courante ». Pour simuler le rien si tu souhaites « absoluement » garder un <a> : au lieu de <a> ou <a href=""> tu dois utiliser <a href="javascript: void 0;">.

En suivant ces quelques recommandations de syntaxe, ton code devient le suivant :

<html lang="en">
	<head>
		<!-- ... -->
		<meta charset="utf-8">
		<!-- ... -->
	    <style>
      		/* on fait ressembler tout les `<span class="bouton" ...>` 
      		 * ceci à un `<a href="..." ...>` 
      		 */
      		.bouton { color: #00f; text-decoration: underline; }
	    </style>
	</head>
	<body>
		<script>
			var arrVariable = [],
          		arrBouton = [];
      
      		arrBouton[1] = "something";
      
			function display(value) {
				alert(value);
			}

			function setArrVariable(index, valeur) {
        		arrVariable[index] = valeur;
				alert('Val == ' + valeur);
			}
		</script>

		<!-- ... -->
		
		<div id="page-1p" class="main-body-1">
			main-body-1
			Message 1
			<script>setArrVariable(0, "INIT1");</script>

      		<br />
			<br />
      
			<span id="page-1-variable-1" class="bouton" onclick='setArrVariable(0, "OK1");'>page-1-variable-1</span>
			<span id="status-1"          class="bouton" onclick="alert(arrVariable[0]);">Status</span>

			<br />
			<br />

			<span id="page-1-variable-2" class="bouton" onclick='setArrVariable(0, "NOK1")'>page-1-variable-2</span>
			<span id="status-2"          class="bouton" onclick="alert(arrVariable[0]);">Status</span>

			<br />
			<br />

      		<!-- Ici la méthode se passant du onclick. -->
			<a href="javascript: display(arrBouton[1]);" id="reponse-1" class="bouton">reponse-1</a>
		</div>
  
		<!-- ... -->
	</body>
</html>

Bonnes pratiques

Le code ci-dessus respecte les conventions de nommages ainsi que les convention ECMAScript (pour le JavaScript) et W3C (pour le W3C). Cependant, il y a d’autres choses que tu peux faire pour améliorer ton code.

<script> à la fin

Quand la page est lue pour être rendue par le navigateur, il exécute le contenu dans les balises <script> et <style> et bloque l’affichage du reste du document tant qu’ils n’ont pas lu et interprété dans les balises <script> et <style>.

Par convention donc on estime que ce qui doit s’afficher aux yeux de l’utilisateur doit déjà être correctement habillé. On met donc les <style> CSS avant le body même si on sait que ça va bloquer le rendu. Le mieux étant de placer les balises <style> les moins lourdes possible avec un habillage « correcte » dans <head> et de placer la surcouche « effet waouh » à la fin du document avec <style scoped> pour ne pas bloquer l’affichage du contenu.

C’est pareil avec tes <script>. Dans ton cas tu empèches l’utilisatieur d’avoir accès au plus important (le contenu) car il ne peut pas s’afficher tant que tes scripts n’ont pas été tous lus. Pour remédier à cela, on va placer « tout » le JavaScript à la fin, après que le HTML utile de la page soit affichée. Comme pour les <style> il est également possible de mettre des <script> dans la balise <head> (en gardant à l’esprit que cela va bloquer le rendu). Cela est interessant s’il est impératif que des décisions JavaScript interviennent « avant » le rendu du contenu (modernizr, etc.).

onclick et cie dans les script

Pour éviter de « piéger » les comportements JavaScript dans les balises, il est admit qu’il faut abonner ses comportements plus tard dans les scripts et non sur les balise avec onclick. L’abonnement direct dans la balise peut avoir du sens pour des applications web ou le balisage représente majoritairement l’application en elle-même mais est à éviter quand le balisage représente « le contenu ». Cela permettant ainsi d’afficher un même contenu, mais présenter différement dans un autre contexte (avec des actions associés différentes). C’est la séparation des rôles (Separations of Concerns littéralement Séparation des préoccupations). C’est le même principe qui veut que les attributs style="" soit plutôt dans des <style> ou des liens vers des feuille CSS avec <link rel="stylesheets">.

Les br ne servent QUE le contenu

Le saut de ligne avec la balise HTML <br> ne doit servir que le saut de ligne à l’intérieur d’un contenu paragraphe et nul par ailleurs. Ceci est une convention.

Pour ce qui va être de gérer l’espacement entre des éléments HTML, on s’en remettra au CSS. Cela nécessite en contre partie de bien baliser son rendu pour pouvoir l’habiller correctement !

L’usage de alert

alert est une fonction synchrone qui bloque la boucle d’évènement JavaScript. Elle est très désagrébale pour l’utilisateur et même pour toi. Si tu souhaites « surveiller » par des messages ce que tu fais de manière « temporaire », utilise plutôt « console.log() » qui ne bloque pas la boucle d’évènement. La page se lancera normalement et tu devras surveiller le passage dans ton code non plus avec une popup blocante mais dans la console JavaScript de ton navigateur (F12 --> Onglet Console).

Cela étant dit, le code précédent deviendrait donc le code suivant :

<html lang="en">
	<head>
		<!-- ... -->
		<meta charset="utf-8">
		<!-- ... -->
   		<link rel="stylesheet" href="styles.css">
    	<!-- ... -->
	</head>
	<body>

		<!-- ... -->
		
		<div id="page-1p" class="main-body-1">
			<div class="main">
				main-body-1
				Message 1
			</div>
      		<div class="first-test">
				<span id="page-1-variable-1" class="bouton">page-1-variable-1</span>
				<span id="status-1" class="bouton">Status</span>
			</div>
			<div class="second-test">
				<span id="page-1-variable-2" class="bouton">page-1-variable-2</span>
				<span id="status-2" class="bouton">Status</span>
			</div>
			<div class="last-test">
      			<!-- Ici la méthode se passant du onclick. -->
				<a href="javascript: void 0;" id="reponse-1" class="bouton">reponse-1</a>
			</div>
		</div>
  
		<!-- ... -->
  
    	<script src="scripts.js"></script>
	</body>
</html>

avec les ressources externes :

styles.css

.bouton { 
  color: #00f; 
  text-decoration: underline;
}

et

script.js

var arrVariable = [],
    arrBouton = [];
      
arrBouton[1] = "something";
      
function display(value) {
  alert(value);
}
function setArrVariable(index, valeur) {
  arrVariable[index] = valeur;
  console.log('Val == ' + valeur);
}

setArrVariable(0, "INIT1");

document.getElementById("page-1-variable-1").addEventListener("click", function () {
  setArrVariable(0, "OK1");
});

document.getElementById("status-1").addEventListener("click", function () {
  console.log(arrVariable[0]);
});

document.getElementById("page-1-variable-2").addEventListener("click", function () {
   setArrVariable(0, "NOK1");
});

document.getElementById("status-2").addEventListener("click", function () {
   console.log(arrVariable[0]);
});

document.getElementById("reponse-1").addEventListener("click", function () {
   display(arrBouton[1]);
});

Demande d’aide

Le plus simple pour toi est de bien distinguer le HTML, CSS et JS au plus vite du PHP. Cela te permettra à l’avenir, quand tu as un problème d’affichage ou de JavaScript de ne pas parler de PHP à tes interlocuteurs pour qu’ils se concentrent sur ton problème. Ensuite, à toi de remettre cela dans un contexte PHP ou autre selon ton langage préféré pour générer des réponses HTTP ou répondre à des requêtes XHR (AJAX) ou Websocket, etc.

En espérant t’avoir aider, et excuse moi pour les fautes d’orthographe, je n’ai malheureusement plus le temps de me relire plus que cela.

Si jamais des points d’explication sont trop « perché » ou flou, ignore les pour le moment (tu débutes) ou demande des précisions ;)

Bon courage dans ton apprentissage !

PS : Voici le codepen (pour tester) de ce que j’ai fait ici : http://codepen.io/anon/pen/oBJMwq


#14

C’est clair, j’ai commencé à lire le topic merci pour le mal de tronche immédiat ^^
Déjà retiens qu’en HTML5
<script> suffit … point de <script type=""> déjà tu t’embrouilleras moins.