Mini-cours de JavaScript

Jour 9

Vous savez sélectionner facilement toute zone ayant un attribut id et récupérer la valeur d'un champ.

Maintenant, nous allons apprendre à utiliser la balise dédiée à l'affichage d'un résultat, comment changer l'apparence de zones d'une page web et comment exercer un contrôle pour chaque caractère tapé.

Enfin, après avoir résumé les nouvelles balises HTML apprises, nous apprendrons des choses qui ne sont pas indispensables, mais qui facilitent grandement la vie du programmeur.

<output>

La balise <output> est la dernière balise HTML que nous étudierons.

La balise <output>, comme la balise <button> peuvent être utilisées en l'absence de formulaire.

Cette balise <output> ( de type in-line ) est dédiée à l'affichage d'un résultat.

Bien que ce rôle puisse être attribué à toute balise, en dehors de <output>, les balises les plus utilisées pour afficher un résultat sont : <div> ( type block ),<p> ( type block ) et <span> ( de type in-line )

Pour afficher un résultat, on place une zone d'affichage là où on souhaite afficher le résultat sur la page. Mais, lorsque le résultat n'est pas connu lors de la création du fichier HTML, le contenu de cette zone est généralement vide.

Toutefois, pour que le résultat soit affiché dans la bonne zone, la balise représentant cette zone doit être identifiée. Ainsi, dans le code source d'un fichier HTML, on peut trouver des balises sans contenu, mais identifiées. Par exemple :

<div id="resultat1"></div>
<p id="resultat2"></p>

<p><span id="resultat3"></span></p>
<p><output id="resultat4"></output></p>

Un exemple d'utilisation de la balise <output> sera donné dans le prochain code-source

attribut : style

Depuis votre étude du CSS, vous savez qu'il est ( heureusement ! ) possible de changer l'apparence de toutes les zones de la page web.

Vous savez que les instructions CSS sont souvent regroupées dans un seul fichier lié au fichier HTML via la balise <link />. Vous savez également que les instructions CSS écrites dans la balise <style> sont prioritaires par rapport à celle écrites dans le fichier CSS, si dans la zone <head>, la balise <style> est bien la dernière à fournir des instructions CSS, c-à-d si <style> n'est pas suivie de <link rel="stylesheet" href="..." />.

Vous savez qu'il est également possible de spécifier un style particulier à une balise via son attribut style, auquel cas ces instructions sont, à leur tour, prioritaires sur celles contenues dans la balise <style>

Pour des raisons de sécurité, JavaScript ne modifie aucun fichier, pas même le fichier HTML, mais uniquement ce qui se trouve dans la mémoire utilisée par le navigateur après la lecture du fichier HTML. Bien qu'il soit possible d'accéder, via JavaScript, au contenu de la balise <style>, l'usage le plus fréquent de changement d'apparence d'une zone ne requiert qu'un accès à l'attribut "style" d'une balise.

Quelle est la capitale de la Belgique ?

<form id="form1" onsubmit="testerCapitale();return false;" name="form1">
    <p>
        Quelle est la capitale de la Belgique ?
        <select id="capitales" onclick="effacer();">
            <option>
                Athènes
            </option>
            <option>
                Bruxelles
            </option>
            <option>
                Londres
            </option>
            <option>
                Madrid
            </option>
            <option>
                Paris
            </option>
        </select>
        <input type="submit" value="Sélectionner">
    </p>
    <p>
        <output id="result"></output>
    </p>
</form>

<script>
function testerCapitale(){

    if (document.getElementById("capitales").selectedIndex==1) {

        document.getElementById("result").value="Bonne réponse !";
        document.getElementById("result").style.backgroundColor="green";
        document.getElementById("form1").style.color="black";
    }
    else{
        document.getElementById("result").innerHTML="Réponse fausse !";
        document.getElementById("result").style.backgroundColor="red";
        document.getElementById("form1").style.color="white";
    }
}

function effacer(){
    document.getElementById("result").innerHTML="";
    document.getElementById("form1").style.color="black";
}
</script>

L'événement clic peut être capté pour toute balise HTML - via l'attribut onclick - et pas seulement une balise-bouton. Ici, le code <select id="capitales" onclick="effacer();"> dit au navigateur d'appeler la fonction effacer() lorsqu'on clique sur la liste déroulante.

Le code HTML <output id="result"></output> affiche une zone vide. Il n'y a rien entre les balises. Toutefois, le navigateur y placera un résultat après un clic sur le bouton.

document.getElementById("result").value
= document.getElementById("result").innerHTML

Particularité. .style est une propriété de l'objet element ( représentant une balise ), mais qui ne reçoit pas comme valeur une chaîne de caractères, mais un objet style.

Particularité. .style est une propriété qui reçoit un objet style.

Code HTML :

<p id="xxx" style="color:red;background-color:white;">
    Particularité. .style est une propriété qui reçoit un objet style.
</p>

Code JavaScript :

function modifierStyle(){

    document.getElementById("xxx").style.color="white";
    document.getElementById("xxx").style.backgroundColor="red";

    /*La ligne de code suivante ne fonctionne pas
    document.getElementById("xxx").style="color:white;background-color:red;"; */

}
function restaurerStyle(){
    document.getElementById("xxx").style.color="red";
    document.getElementById("xxx").style.backgroundColor="white";
}

En JavaScript, les tirets sont interdits dans les noms des propriétés.
Or, certaines propriétés CSS sont des noms composés.
La solution = supprimer les tirets et remplacer la première lettre du mot suivant par sa majuscule.

Ainsi, la propriété CSS background-color correspond à la propriété JavaScript backgroundColor.

Contrôlons aussi les frappes du clavier ...

Événement : keyup

Outre le clic, vous savez qu'il existe de nombreux événements qui peuvent survenir sur une page web. Voyons le plus important qui concerne le clavier.

L'événement keyup se produit lorsque l'utilisateur relâche une touche. Il est utilisé lorsqu'on souhaite contrôler les frappes de l'utilisateur dans un champ.

L'attribut onkeyup n'est donc utilisé que dans une balise <input />

Code UTF-8 du caractère :

<form id="form4" name="form4">
    <p>
        Tapez un caractère :
        <input type="text" id="phrase4" onkeyup="toUTF8();" maxlength="1" autocomplete="off" />
        <button onclick="effacer4();return false;">Effacer</button>
    </p>
    <p>
        Code UTF-8 : <output id="codeUTF8"></output>
    </p>
</form>
function toUTF8() {

    var phrase = document.getElementById("phrase4").value;
    var caractere = phrase.substr(phrase.length-1,1); /* caractere = le dernier caractère de la phrase */
    var codeUTF8 = phrase.charCodeAt(phrase.length-1);

    document.getElementById("codeUTF8").value = codeUTF8;
    document.getElementById("phrase4").value = caractere; /* la phrase vaut le dernier caractère tapé */
}

function effacer4(){
    document.getElementById("phrase4").value = "";
    document.getElementById("codeUTF8").value = "";
}

.charCodeAt() est une méthode d'un objet String qui retourne le code du caractère dont la position est passé à cette méthode

Le code HTML <output id="codeUTF8"></output> affiche une zone vide. Il n'y a rien entre les balises. Toutefois, le code JavaScript y placera un résultat. La balise <output> est dédiée à l'affichage du résultat d'une opération.

Résumé HTML

En étudiant le CSS, nous avons découvert 1 nouvelle balise HTML : style ( placée dans le <head> )

En étudiant le JavaScript, nous avons découvert 11 nouvelles balises HTML. Par ordre alphabétique :

  1. button : Bouton qui peut être utilisé hors formulaire
  2. fieldset : Liséré autour des champs
  3. form : Formulaire qui regroupe les champs et les boutons
  4. input : Champ ( ou bouton de formulaire )
  5. label : Balise liée à un champ ( NB : La valeur de son attribut for doit être celle de l'attribut id du champ )
  6. legend : Titre d'un liseré
  7. option : Élément d'une liste déroulante ( balise placée dans la balise <select> )
  8. output : Zone de résultat ( balise de type in-line )
  9. script : Zone pour le code JavaScript
  10. select : Liste déroulante
  11. textarea : Zone de texte ( sur plusieurs lignes )

Nous connaissons maintenant 41 balises sur 110.

Pour faciliter le travail du programmeur

Avec tout ce que vous avez pris, vous pourriez vous arrêter ici ! Il y a déjà de quoi faire. En fait, vous devriez déjà pouvoir créer des interfaces web pour résoudre, en un clic, tous les types de problèmes rencontrés dans le secondaire et même après ...

Tous les problèmes de géométrie, trigonométrie, algèbre, physique, chimie, ...

Toutefois, il serait dommage de vous priver de connaissances qui vont faciliter votre travail ...

Allez, encore un petit effort.

!

Certaines fonctions retournent que vrai ou faux (en anglais, true or false). Elles sont donc idéales dans une condition. Toutefois, parfois, par commodité, on préfère n'exécuter des instructions que lorsque la condition est fausse.

Voici comment vous pourriez le faire :

var nombre1=document.getElementById("nombre1").value;

if (isNaN(nombre1)){

}
else{
    alert("Bravo, vous avez tapé un nombre.");
}

Le code n'est pas très élégant. Voici comment font les bons programmeurs :

var nombre1=document.getElementById("nombre1").value;

if (!isNaN(nombre1)){
    alert("Bravo, vous avez tapé un nombre.");
}

! inverse la valeur. Vrai devient faux et faux devient vrai !

Si nombre1 est bien un nombre (américain), alors la fonction isNaN() va retourner false ... Et, comme on a tapé !, false devient true et une boîte de dialogue s'affiche.

&&

&& signifie, entre deux conditions, "et"

/* soit x une variable de type chaîne de caractères
qui représente la quantité souhaitée d'un produit tapée par un client
dans un formulaire de commande. On souhaite savoir si le champ n'est pas vide
et ne retenir que le champ ne contient pas plus de 2 caractères
=> quantité maximale autorisée = "99" */

if(x.length>0){
    if(x.length<3){
        ...
    }
}
if(x.length>0 && x.length<3){...}

Si la longueur de la chaîne de caractères, x, est supérieure à 0 et inférieure à 3 alors ...

Cela évite des cascades de if.

||

|| signifie, entre deux conditions, "ou"

if(age<18){
    /* instructions */
}

if(age>67){
    /* mêmes instructions que si age<18 */
}

Si les instructions sont identiques, il est plus simple d'écrire :

if(age<18 || age>67){ ... }

Si la valeur de la variable age est inférieure à 18 ou supérieur à 67 alors ...

Cela évite de multiplier les if.

Avec un clavier belge, la barre verticale se trouve la touche 1 (qui n'est pas celle du pavé numérique). Pour la taper, on tape Alt Gr + 1

Le tableau

Le tableau est le dernier type de variable que nous n'avions pas encore étudié. Il faut un peu s'accrocher, mais après vous ne pourrez plus vous en passer. Notez que cette notion se retrouve dans tous les langages de programmation.

Un tableau est un ensemble de variables ( généralement du même type ). C'est une variable qui contient des variables !

Dans certains langages "typés", un tableau représente des variables d'un même type.

Un tableau est donc une variable un peu spéciale. Pour comprendre, revenons un instant à la mémoire de l'ordinateur.

Si la mémoire est représentée comme une armoire de bureau, on peut considérer une variable comme un tiroir et un tableau comme un ensemble de tiroirs. On se souvient que chaque tiroir a nom et qu'on utilise le mot-clé var pour déclarer une variable.

Mais, contrairement à une armoire de bureau, ici, la taille du tiroir s'adapte à son contenu ... Ainsi, par exemple, plus la chaîne de caractères sera grande, plus le tiroir sera grand.

Le mot-clé var permet simplement de donner un nom ( une étiquette )
Le code var maVariable; crée une variable dont le nom est maVariable ayant un contenu indéfini - undefined - autant dire un "on-ne-sait-pas-quoi" (un tiroir vide). On ne sait même pas dire si c'est un tiroir ou un ensemble de tiroirs.

Pour créer une variable de type chaîne de caractères, on utilise des guillemets.
Pour créer un tableau, on utilise des crochets entre lesquels chaque élément est séparé par une virgule

Exemples

var tableau1=[12,53.7]; /* tableau contenant deux nombres */
var tableau2=["bon","gentil","joli"]; /* tableau contenant 3 chaînes de caractères */
var tableau3=['B','o','n','j','o','u','r']; /* tableau contenant 7 caractères */
var tableau4=["Marc",12,"Benoît",16.3]]; /* tableau avec du contenu de différents types */
var tableau5=[]; /* tableau vide */

Bien qu'il soit possible, en JavaScript, de créer des tableaux ayant du contenu de différents types, l'usage de tels tableaux est rare, car les tableaux sont souvent utilisés avec des boucles. Dans le tableau 4, ci-dessus, les cellules ayant un indice impair contient des valeurs de type string. Les cellules ayant un indice pair contient des valeurs de type number. Un tel tableau est donc exploitable via une boucle.

Pour identifier un élément d'un tableau, il suffit d'indiquer le nom du tableau suivi immédiatement de crochets dans lesquels sa position est indiquée, en sachant que le premier élément se trouve à la position zéro. Ce qui est entre crochets s'appelle un indice ( un nombre entier positif ). Le premier élément a comme indice : 0.

alert(tableau1[1]); /* affiche 53.7 */
alert(tableau2[0]); /* affiche bon */
alert(tableau3[3]); /* affiche j */
alert(tableau1[0]+tableau1[1]); /* affiche 65.7 */
tableau3[3]='s'; /* remplace j par s */
tableau3[5]='i'; /* remplace u par i */
alert(tableau3); /* affiche B,o,n,s,o,i,r */
alert(tableau2[2][1]); /* affiche o */
/* tableau2[2]="joli" et le caractère ayant la position 1 = o */

Un tableau peut contenir des tableaux ! C'est logique ! Puisqu'un tableau est une variable et qu'un tableau peut contenir des variables, un tableau peut contenir des tableaux ... Les tableaux de tableaux est une matière qui sort du cadre d'un mini-cours.
Retenez simplement qu'une chaîne de caractères est un tableau "spécial" qui ne contient que des caractères.
Un tableau peut non seulement contenir d'autres tableaux, des objets, mais aussi des fonctions anonymes qui sont appelées lorsqu'on parcourt le tableau ! ...

Sachez qu'un tableau est un objet Array.

array (en anglais) signifie tableau (en français)

Vous savez qu'une fenêtre est un objet window, qu'une page web est un objet document, qu'une balise est un objet element, qu'un style est un objet style, qu'une chaîne de caractères est un objet String et maintenant qu'un tableau est objet Array qui peut contenir des objets. Maintenant, vous devriez comprendre pourquoi on parle de programmation "orientée objet". En fait, quasiment tout est objet ! Dans le code, le programmeur ne fait pratiquement que manipuler des objets.

Ainsi, un tableau peut contenir un ensemble d'objets, comme des objets element ( des balises ) ... Nous y reviendrons avec la méthode .querySelectorAll()

.length

La propriété .length de l'objet Array permet de déterminer le nombre d'éléments que contient le tableau.

Un élément d'un tableau - appelé item (en anglais) - est une variable qui a une position dans un tableau.
Un objet element représente une balise HTML
Or, une variable peut représenter un objet element, donc un élément d'un tableau peut être un objet element ... Attention, il y a élément et element

var taille = tableau3.length; /* taille vaut 7 */

var phrase="Je vais à l'école.";
var longueur=phrase.length;

.push()

La méthode .push() de l'objet Array permet d'ajouter un élément à la fin du tableau. L'élément à ajouter est passé en paramètre.

var tableau1=[12,53.7];
tableau1.push(10);
tableau1.push(35);
alert(tableau1);/* affiche 12,53.7,10,35 */

var tableau2=["bon","gentil","joli"];
tableau2.push("courageux");
alert(tableau2); /* affiche bon,gentil,joli,courageux */

var tableau3=['B','o','n','j','o','u','r'];
tableau.push('');
tableau.push('!');
alert(tableau3);/* affiche B,o,n,j,o,u,r,,! */

new

Le mot-clé new permet de créer un nouvel objet du type voulu. Le nom du type est immédiatement suivi de parenthèses.

var nouvelleChaine = new String();
alert(nouvelleChaine.length); /* affiche 0 (=> 0 caractère = chaine vide) */
/* nouvelleChaine.push("JavaScript");
push() n'est pas une méthode de l'objet String */
nouvelleChaine = nouvelleChaine + "JavaScript";
alert(nouvelleChaine.length); /* affiche 10 (=> 10 caractères) */
alert(nouvelleChaine); /* affiche JavaScript */

var nouveauTableau = new Array();
alert(nouveauTableau.length); affiche 0 (=> 0 élément = tableau vide)
nouveauTableau.push(nouvelleChaine);
alert(nouveauTableau.length); affiche 1 (=> 1 élément)
alert(nouveauTableau[0]); /* affiche JavaScript */

+= et ++

nouvelleChaine = nouvelleChaine + "JavaScript"; peut être remplacé par :
nouvelleChaine += "JavaScript";

i = i + 1;          /* peut être codé : i+=1; */
x = x - 12;         /* peut être codé : x-=12; */
y = y * 17;         /* peut être codé : y*=17; */
z = z / 5;          /* peut être codé : z/=5; */
reste = reste % 97; /* peut être codé : reste%=97; */

Le cas le plus fréquent est avec le signe + ( addition ou concaténation ).
Rappel : concaténation = collage de deux chaînes de caractères

Et, lorsque ce qui est ajouté ou retiré vaut 1, on peut mettre après le nom de la variable ++ ou -- :
i++ est équivalent à i+=1; qui est équivalent à i = i + 1;
nombre-- est équivalent à nombre-=1; qui est équivalent à nombre = nombre - 1;

Si on ajoute 1 à la variable, on parle d'incrémentation ( cas le plus fréquent )
Si on lui retire 1, on parle de décrémentation.

La boucle : for

Nous savons que, dans une boucle, nous utilisons :

  1. généralement une variable - appelée compteur - dont le nom traditionnel est i
  2. une condition ( si elle est vraie, les instructions entre accolades seront exécutées )
  3. une incrémentation du compteur ( à ne pas oublier de faire ! )

Ainsi, on commence par initialiser le compteur : i = 0;
Puis, on teste une condition : si i est inférieur à ...
Enfin, on n'oublie pas d'incrémenter le compteur : i++

Nous ne sommes pas obligés d'initialiser à zéro. ( Initialiser = donner une valeur initiale à une variable )
La condition peut aussi être d'égalité ( == ), de supériorité ( > ), ... ( comme avec les if )
On peut aussi décrémenter ( i-- ). Par exemple, pour parcourir une tableau du dernier élément au premier. Ou ajouter 2 au compteur ( i=i+2 ). Par exemple, pour parcourir un tableau et ne sélectionner qu'un élément sur deux ( cas des nombres pairs ou impairs )

Cette méthode est valable pour toutes les boucles.

Mais, si, avant d'entrer dans la boucle, on sait combien de fois les instructions doivent être répétées - par exemple x fois -, on utilise alors généralement la boucle for.

Pour définir une boucle for, il faut :

  1. taper le mot-clé for,
  2. faire suivre de parenthèses ( () ),
  3. entre ces parenthèses, 3 zones séparées par un point-virgule existent :
    1. zone d'initialisation
    2. zone pour exprimer une condition ( ou plusieurs conditions via && ou || )
    3. zone d'incrémentation
    une condition ( comme avec un if )
  4. ouvrir une accolade ( { ),
  5. placer des instructions,
  6. fermer l'accolade ( } ).
for ( i=0 ; i<x ; i++ ) {
    instruction1;
    instruction2;
    ...
}

Le programme passe une seule fois dans la zone d'initialisation, puis il teste la condition, exécute (si la condition est vrai), incrémente
puis il teste la condition, exécute (si la condition est vrai), incrémente
puis il teste la condition, exécute (si la condition est vrai), incrémente
puis ...

Dans la zone d'initialisation, il est autorisé d'initialiser plusieurs variables. Dans ce cas, ces initialisations sont séparées par une virgule.

De même que les "if" peuvent être imbriqués, les boucles peuvent l'être aussi ...

Supposons que nous souhaitons connaître le nombre de fois que la lettre 'e' se trouve dans une phrase. Il va falloir vérifier pour chaque lettre de la phrase si elle correspond au 'e'. "Pour chaque" => nous allons utiliser une boucle. Et, en plus, il est possible de connaître le nombre de caractères d'une chaîne de caractères. La boucle idéale est donc la boucle for

Comme il est toujours possible de connaître la taille d'un tableau ( .length ), la boucle utilisée pour parcourir un tableau est pratiquement toujours la for.

function determinerNombreDeE(){

    var phrase=document.getElementById("phrase1").value;
    var nombreDeE=0;

    for (i=0,x=phrase.length;i<x;i++){
        if (phrase.charAt(i)=='e') {
            nombreDeE++;
        }
    }

    alert("Cette phase contient " + nombreDeE + " 'e'.");
    alert("Elle contient "+x+" caractères");
    /* x est déclaré dans le bloc d'initialisation */
}

Analysons ce qui est entre parenthèses :

i=0,x=phrase.length;i<x;i++

Nous retrouvons deux points-virgules séparant les trois zones.

Dans la zone d'initialisation, sont initialisés deux variables : i et x
La variable i représente la position du caractère dans la chaîne. C'est notre compteur. Puisque nous allons commencer par tester le premier caractère, i = 0
La variable x indique la taille de la phrase, donc le nombre de caractères.
N'oublions pas que la première position est 0 et donc la position du dernier caractère est x-1

Nous aurions pu écrire entre les parenthèses :

i=0;i<phrase.length;i++

Mais comme le programme passe de nombreuses fois dans la zone où est écrit la condition, le programme aurait calculé le nombre de caractères dans la phrase de nombreuses fois ...
Or, ce nombre de caractère ne doit être déterminée qu'une seule fois. Si la phrase fait 80 caractères, il est inutile de demander 80 fois : quelle est la longueur de la chaîne ? ( phrase.length ? )

La condition est si i est inférieur à x alors exécuter les instructions entre accolades.

Dans la zone d'incrémentation, notre compteur i est incrémenté.

C'est la première fois que vous voyez une boucle for. Croyez-moi sur parole, ce n'est pas la dernière fois !

De la fin au début
for (var i = x.length-1; i > -1 ; i--) {...}

break;

Le mot-clé break permet de sortir immédiatement d'une boucle ( ou d'un switch ).

S'il s'agit d'une boucle for, le programme ne passera pas dans la zone d'incrémentation avant de sortir de la boucle. Immédiatement, c'est ... immédiatement !

Supposons que nous souhaitons connaître la position de seconde lettre 'e' dans une phrase. Il va falloir vérifier pour chaque lettre de la phrase si elle correspond au 'e'. "Pour chaque" => nous allons utiliser une boucle. Et, en plus, il est possible de connaître le nombre de caractères d'une chaîne de caractères. La boucle idéale est donc la boucle for. Toutefois, il faudra interrompre la recherche dès que la seconde lettre 'e' a été trouvée.

function determinerSecondE(){

    var phrase = document.getElementById("phrase2").value;
    var nombreDeE = 0;
    var estTrouve = false;

    for (i=0,x=phrase.length;i<x;i++){

        if (phrase.charAt(i)=='e') {
                nombreDeE++;
        }

        if (nombreDeE==2){
            alert("Le second 'e' se trouve à la position : " + i);
            estTrouve=true;
            break;
        }

    }

    if (!estTrouve) {
        alert("Cette phase ne contient pas de 'e'.");
    }
}

Le mot-clé continue permet de re-boucler immédiatement, de re-tester la condition. C'est l'inverse du break. Comme pour le break, continue est suivi d'un point-virgule.

Dans le cadre de ce mini-cours, nous n'étudierons pas le switch, il est rarement utilisé par les débutants.

Dernier jour ! Place à la pratique, nous allons valider un formulaire.