H2 - P2019

Développement web

Cours 05 - 2014-10-12

Rappels Javascript

À quoi sert javascript

  • Modifier la page (le DOM)
  • Créer des intéractions impossible en CSS
  • Empêcher l'utilisateur d'accomplir certaines actions
  • Animer des éléments
  • Envoyer des données analytics
  • Charger des contenus extérieurs et les rajouter dans la page
  • Intéragir avec les API HTML telles que audio, video, geolocalisation, canvas, websocket, ...
Java is to Javascript what car is to carpet

Ajouter du javascript

Le javascript se rajoute en HTML avec la balise script

Il n'est aujourd'hui plus nécessaire de préciser le type, mais ça ne fait pas de mal


<script type="text/javascript"></script>
                    

Ce code peut être placé dans l'entête, mais il est conseillé de le placer en bas de page juste avant la fermeture du body

De cette manière, nous sommes certain que le DOM est chargé et le chargement du script n'a pas bloqué le chargement du reste


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>Mon super site</h1>

    <script></script>
</body>
</html>
                    

La balise script peut contenir du JS


<script type="text/javascript">
    console.log('coucou');
</script>
                    

Elle peut aussi charger un fichier .js
L'attribut src peut-être absolu ou relatif


<script type="text/javascript" src="http://monsite.com/src/js/script.js"></script>
                    

Variables

Dans les exemples suivant, nous allons utiliser les termes foo et bar

Ces termes ne designent rien.
On peut les comparer à truc et bidule

Wiki 1

Wiki 2

Déclarer une variable

Une variable se compose d'un nom et d'une valeur (nombre, texte, booléen, etc.)

Elle se crée en utilisant le terme var


// Pas bien
foo = 'bar';

// Bien 
var foo = 'bar';
                    

Le choix du nom et la façon de l'écrire s'appelle naming convention (convention de nommage)
On parle aussi de nomenclature

Si une variable se compose de plusieurs mots (ex: foo et bar) il existe plusieurs façons de séparer ces mots

Les plus connues en JS sont :

  • camelCase pour les variables
  • PascalCase pour les classes
  • snake_case (ou underscore_case) pour les variables

// Bien 
var foo_bar = 'lorem ipsum'; //Underscore (underscore entre chaque mot, aucune majuscule)
var fooBar  = 'lorem ipsum'; //CamelCase ou LowerCamelCase (tout à la suite, majuscule à chaque mot sauf premier)
var FooBar  = 'lorem ipsum'; //PascalCase ou UpperCamelCase (tout à la suite, majuscule à chaque mot)

// Éviter
var foobar  = 'lorem ipsum';
var FOOBAR  = 'lorem ipsum'; //Utilisé pour les variables globales tout de même

// Pas bien
var foo-bar = 'lorem ipsum';
var fO_bAR  = 'lorem ipsum';
var foo bar = 'lorem ipsum';
                    
  • Choisissez bien le nom de votre variable
  • Il doit en dire suffisamment sans être trop long
  • Préférez l'anglais
  • Évitez les mots clés réservés :
    class, default, if, do, for, function, ...
  • Soyez constant

Ces variables vont nous permettre de stocker des données pour les utiliser ensuite (ex: score)

Pour afficher le contenu d'une variable nous pouvons utiliser console.log()


console.log(foo_bar)
                    

console.log() est utilisé pour aider le développeur. Il convient de les supprimer du code une fois le développement terminé.

Pour afficher les résultats de la console de Chrome, il suffit d'aller dans Outils de développement

Puis dans l'onglet console

Déclarer plusieurs variables

Minimisez le nombre d'utilisations de var en utilisant les virgules


var foo = 'foo';
var bar = 'bar';

// Devient
var foo = 'foo', bar = 'bar';

// Devient
var foo = 'foo',
    bar = 'bar';
                    

Meilleures performances, plus pro, plus aéré, mais risque d'erreur

Les types de variables

Il existe plusieurs types de variables

number


var foo = 1337,
    bar = 0.5;

console.log(foo);
                    

string


var foo = 'coucou';

console.log(foo);
                    

boolean


var foo = true,
    bar = false;

console.log(foo);
                    

array


var foo = ['toto',1337,true];

foo.push('hey');

console.log(foo);
console.log(foo[1]);
console.log(foo.length);
                    

object


var foo = {
    lorem : 'ipsum',
    toto  : 1337,
    test  : true
};

foo.hoy = 'hey';

console.log(foo);
console.log(foo.toto);
                    

Il existe d'autres types de variables plus complexe que nous aborderons plus tard

  • function
  • null
  • undefined
  • date
  • DOMElement
  • regex
  • ...

typeof permet de connaître le type d'une variable


var foo_bar = 'lorem ipsum';

console.log(typeof(foo_bar)); // "string"
console.log(typeof foo_bar);  // "string"
                    

typeof 1337;          // "number"
typeof 0.5;           // "number"
typeof 'lorem ipsum'; // "string"
typeof function(){};  // "function"
typeof true;          // "boolean"

typeof {};            // "object"
typeof [];            // "object"
typeof null;          // "object"
typeof /abcd/;        // "object"
typeof document.createElement('div'); // 'object'
                    

typeof ne renvoie pas toujours la valeur attendue

Une autre méthode est instanceof


{} instanceof Object;       // true
[] instanceof Array;        // true
new Date() instanceof Date; // true
/abcd/ instanceof RegExp;   // true
                    

Pas mal mais pas très pratique

Opérations

Javascript permet de faire des opérations simples


var foo    = 1,
    bar    = 2,
    result = foo + bar;

console.log(result);
                    

qu'il est possible d'écrire plus simplement


console.log(1 + 2);
                    

Mais aussi de faire des opération plus complexe


console.log(1 + '1');
console.log(1 - '1');
console.log(1 + 'a');
console.log('hel' + 'lo');
console.log(1 + true);
console.log(1 + false);
console.log(12 % 10);
console.log(1 * 'a');
console.log(1 / 0);
                    

Il est possible d'incrémenter (+1) ou décrémenter (-1) une variable


var i = 0;
i++;
console.log(i);
i++;
console.log(i);
i--;
console.log(i);

                    

Pour les opérations mathématiques plus complexe, javascript fourni une variable de type objet nommée Math contenant des méthodes (fonctions) et des propriétés (variables)


console.log(Math.sin(2)); // Méthode sinus
console.log(Math.PI);     // Propriété π
                    

Méthodes de l'objet Math

  • Math.random() nombre aléatoire entre 0 et 1
  • Math.min() minimum
  • Math.max() maximum
  • Math.round() arrondi
  • Math.ceil() arrondi au dessus
  • Math.floor() arrondi en dessous
  • Math.abs() valeur absolue
  • Math.log() logarithme
  • Math.pow() au carré
  • Math.sqrt() racine carré
  • Math.sin() sinus
  • Math.asin() sinus inverse

Propriétés de l'objet Math

  • Math.PI π
  • Math.E nombre d'euler
  • ...

Conditions

Les conditions permettent d'accomplir une action que lorsqu'une condition spécifiée est vrai

On utilise if et else


var foo = true;

if(foo == true)
{
    console.log('vrai !');
}
else
{
    console.log('faux !');
}
                    

S'il n'y a qu'une seule action dans le if ou dans le else, on peut retirer les accolades


var foo = true;

if(foo == true)
    console.log('vrai !');
else
    console.log('faux !');
                    

Si on test qu'une valeur est vraie, il est inutile de préciser == true


var foo = true;

if(foo)
    console.log('vrai !');
                    

Pour tester qu'une valeur est fausse, il suffit de l'inverser en la précédent par un !


var foo = true;

if(!foo)
    console.log('faux !');
                    

Il est possible de tester des nombres


var age = 20;

if(age > 18)
    console.log('Vous êtes majeur');
else
    console.log('Vous êtes mineur');
                    
  • > supérieur
  • < inférieur
  • >= supérieur ou égal
  • <= inférieur ou égal

Il est possible de combiner plusieurs tests avec &&


var foo = 12,
    bar = false;

if(foo >= 12 && bar)
    console.log('Yep');
else
    console.log('Nop');
                    

Ici, foo doit être supérieur ou égal à 12 ET bar doit être vrai

Mais aussi avec || (double pipe)


var foo = 12,
    bar = false;

if(foo >= 12 || bar)
    console.log('Yep');
else
    console.log('Nop');
                    

Ici, foo doit être supérieur ou égal à 12 OU bar doit être vrai

Boucles

Les boucles permettent par exemple d'accomplir une action un certain nombre de fois ou alors de parcourir un tableau en accomplissant une action pour chacun des éléments

La plus utilisée en JS est le for

(for in, while et do while sont des boucles que nous ne verrons pas dans ce cours)


for(var i = 0; i < 10; i++)
{
    console.log(i);
}
                    
  • var i = 0 correspond à l'initialisation
  • i < 10 correspond à la condition
  • i++ est executé à chaque boucle

Comme pour le if les accolades sont inutiles s'il n'y a qu'une seule action


for(var i = 0; i < 10; i++)
    console.log(i);
                    

En sens inverse


for(var i = 9; i >= 0; i--)
    console.log(i);
                    

Deux par deux


for(var i = 0; i < 10; i += 2)
    console.log(i);
                    

Pour boucler dans un tableau


var foo = ['toto','tata','titi','tutu'];

for(var i = 0; i < foo.length; i++)
{
    var bar = foo[i];
    console.log(bar);
}
                    

Fonctions

Une fonction peut être déclarée de plusieurs façons


// Named function
function my_function()
{
}
                    

// Anonymous function
var my_function = function()
{
};
                    

Pour nous, les deux reviennent au même

Une fonction peut renvoyer un résultat avec return

Tout ce qui se trouve après return, dans la fonction, sera ignoré


function addition(a,b)
{
    return a + b;
}

var sum = addition(1,2);
                    

Une fonction n'est pas obligée de renvoyer un résultat. Elle peut directement modifier les variables.


var sum = 0;

function addition(a,b)
{
    sum = a + b;
}

addition(1,2);
                    

La fonction peut être déclarée après son utilisation

Javascript considérera les fonctions avant le reste


function addition(a,b)
{
    return a + b;
}

addition(1,2);
                    

addition(1,2);

function addition(a,b)
{
    sum = a + b;
}

                    

Les deux fonctions ont le même effet

  • Une variable déclarée en dehors du fonction pourra être utilisée dans la fonction
  • Une variable déclarée dans la fonction ne pourra pas être utilisée en dehors de la fonction

On appelle ça le scope

Le scope

Le scope correspond à la portée d'une variable


var foo = 1;

function my_function()
{
    var bar = 2;

    console.log('in');
    console.log(foo);
    console.log(bar);
}

my_function();

console.log('out');
console.log(foo);
console.log(bar);

                    

Le résultat

Le scope est donc déterminé par l'endroit où la variable a été déclarée avec var

Le scope ne dépasse pas la fonction où la variable a été déclarée


var foobar = 'coucou';
console.log(foobar);
console.log(window.foobar);

                    

Si une variable est déclarée en dehors de toute fonction, elle est qualifiée de globale

Si une variable a le même nom qu'un des paramètres d'une fonction, le paramètre aura la priorité au sein de la fonction, mais la première variable ne sera pas modifiée


var foobar = 1;

function my_function(foobar)
{
    console.log(foobar);
}

my_function(2);

console.log(foobar);
                    

Le résultat sera 2 suivi de 1

DOM Element

En JS, il est possible de manipuler le DOM.
Celui-ci se compose d'éléments appelés DOM Element ou Node

Récupérer ces éléments

Nous allons voir dans un premier temps comment récupérer ces éléments pour les stocker dans des variables et ensuite comment les modifier

La page entière est considérée comme un DOM Element. On y accède en JS avec la variable document

getElementById


var foo = document.getElementById('hey');

console.log(foo);
                    
  • Renvoie un élément ayant l'ID hey

getElementsByClassName


var foo = document.getElementsByClassName('hey');

console.log(foo);
                    
  • Renvoie un tableau d'éléments ayant la classe hey

getElementsByTagName


var foo = document.getElementsByTagName('section');

console.log(foo);
                    
  • Renvoie un tableau d'éléments dont le tag est section

querySelector


var foo = document.querySelector('.toto');

console.log(foo);
                    
  • Renvoie le premier élément ayant la classe toto
  • Fonctionne avec un sélecteur comme en CSS
  • IE8+

querySelectorAll


var foo = document.querySelectorAll('.toto');

console.log(foo);
                    
  • Similaire à querySelector
  • Renvoie un tableau de tous les éléments ayant la classe toto

Manipuler l'élément

Une fois l'élément récupéré, il est possible de le modifier

Attributs


// Modifie l'attribut test (le créé s'il n'existe pas)
foo.setAttribute('test','coucou');

// Récupère l'attribut "test"
console.log(foo.getAttribute('test'));

// Supprime l'attribut "class"
foo.removeAttribute('class');
                    

Style


// Modifie le style
foo.style.backgroundColor    = 'green';
foo.style.width              = '200px';
foo.style.height             = '200px';
foo.style.height             = '200px';
foo.style.webkitBorderRadius = '100px';
foo.style.mozBorderRadius    = '100px';
foo.style.borderRadius       = '100px';
                    
  • Les propriétés sont en camelCase
  • Bien préciser les unités
  • Spécifier les préfixes

Classes


// Rajoute une classe
foo.classList.add('toto');

// Rajoute plusieurs classes
foo.classList.add('lorem','ipsum');

// Supprime une classe
foo.classList.remove('lorem');

// Demande si contient la classe
console.log(foo.classList.contains('ipsum'));
                    

innerText


// Remplace le contenu par "hey"
foo.innerText = 'hey';
                    

innerHTML


// Remplace le contenu par du HTML
foo.innerHTML = '<span>hey</span>';
                    

La différence avec innerText est la possibilité d'écrire du HTML

remove


// Supprime du DOM
foo.remove();
                    

appendChild


// Place bar à la fin de l'élément foo
foo.appendChild(bar);
                    

Créer un élément


// Créé un span et stock dans la variable "toto"
var toto = document.createElement('span');

// Lui ajoute la class "toto"
toto.classList.add('toto');

// Lui ajoute du texte
toto.innerText = 'Coucou, je suis toto';

// Le rajoute au DOM dans l'élément foo
foo.appendChild(toto);
                    

Événements

En JS, il est possible d'accomplir des actions quand un événement survient
Exemple : Le visiteur clique sur un bouton et un texte apparait

On appelle cela écouter un événément

Il existe des dizaines d'événements et ceux-ci dépendent de l'élément concerné

On peut écouter l'événement click sur une div, mais on ne peut pas écouter l'événement play dessus car play est reservé à un élément de type audio ou video

Pour déclencher une action lors d'un événement, il faut utiliser une fonction. Dans cette situation, cette fonction est qualifié de callback.


var foo = document.querySelector('.foo');

foo.onclick = function()
{
    console.log('click !');
};
                    

On peut écouter plusieurs événements différents sur un même élément


var foo = document.querySelector('.foo');

foo.onclick = function()
{
    console.log('click !');
};

foo.onmouseover = function()
{
    console.log('Mouse over !');
};
                    

Liste d'événements de souris

  • onclick
  • onmousedown
  • onmouseup
  • onmouseenter
  • onmouseleave
  • onmouseover
  • onmouseout
  • onmousemove

Liste d'événements de clavier

  • onkeydown
  • onkeyup
  • onkeypress

Liste d'événements de formulaire

  • onchange
  • onfocusin
  • onfocusout
  • onsubmit

Liste exhaustive des événements

Un paramètre est envoyé au callback et permet d'obtenir des informations sur l'événement.

Il suffit de rajouter un paramètre à la fonction dont on choisit le nom. On utilise en général e ou event

Ce paramètre est un objet possédant plusieurs propriétés et méthodes


var foo = document.querySelector('.foo');

foo.onclick = function(e)
{
    console.log(e.clientX);
};
                    

L'une des ces méthodes est preventDefault() et permet d'annuler le comportement de base


var foo = document.querySelector('.foo');

foo.onkeydown = function(e)
{
    e.preventDefault();
    console.log('ok');
};
                    

Le problème de cette écriture et l'impossibilité d'écouter plusieurs fois un événements.


foo.onclick = function(){
    console.log('click 1');
};
foo.onclick = function(){
    console.log('click 2');
};
                    

La solution est d'utiliser la méthode addEventListener()


foo.addEventListener('click',function(){
    console.log('click 1');
});
foo.addEventListener('click',function(){
    console.log('click 2');
});
                    

Interval / Timeout

Il peut arriver qu'on ait besoin d'attendre un certain temps avant d'éxecuter une instruction

La méthode window.setTimeout() permet de faire cela

  • Le premier paramètre est le callback. C'est une fonction qui sera déclenchée à la fin du temps
  • Le deuxième paramètre est le temps à attendre en millisecondes

window.setTimeout(function()
{
    console.log('Ding !');
},1000);
                    

window est un objet global possédant tout un tas de propriétés et méthodes

Il peut arriver qu'on ait besoin de déclencher une même action plusieurs fois à intervalle régulier

La méthode window.setInterval() permet de faire cela

Les paramètres sont les mêmes que pour le setTimeout


window.setInterval(function()
{
    console.log('Tick');
},1000);
                    

WTF JS

Javascript est loin d'être parfait


console.log(9999999999999999);
                    

console.log(0.1 + 0.2);
                    

console.log([2, 4, 7, 1, 3].sort());
console.log([40, 100, 1, 5, 25].sort());
                    

console.log(10/'coucou');
console.log(typeof NaN);
                    

WtfJS.com