Académique Documents
Professionnel Documents
Culture Documents
© Dunod, 2019
11 rue Paul Bert, 92240 Malakoff
www.dunod.com
ISBN : 97-8-21-007920-3
Couverture
Page de titre
Page de Copyright
2 Hello(s) World(s)
5 Les mathématiques
6 Manipulation de dates
7 Les tableaux
11 La programmation événementielle
12 Manipuler le document
13 Les formulaires
13.1 l'objet Form
17 La géolocalisation
20 Monétisation et publicité
20.1 la monétisation
20.2 la publicité
21 Introduction à Node.js
22.1 typeScript
22.2 babel
22.3 JSX
23 Bibliothèques et frameworks
23.1 frameworks
23.2 jQuery
23.3 prototype.js
23.4 react
23.5 angular
23.6 vanilla.js
Annexe CSS
Utilisation de FontAwesome
La pseudo-classe :hover
Index
A. Cazes, J. Delacroix
288 pages
2016
F. Lemainque
128 pages
2018
C. Aubry
384 pages
2018
AVANT-PROPOS
Dix ans après mon premier ouvrage sur le JavaScript, paru chez
Micro-Application, une totale réécriture était nécessaire.
J’ai écrit ce livre avec une vision plus large que le simple
apprentissage du JavaScript. J’ai voulu apporter au lecteur des
principes qui seront utiles dans la programmation sur tous les
langages. J’ai aussi ajouté des conseils sur les facteurs de succès
d’un projet web. Après une expérience de plus de douze ans en tant
que créateur et éditeur d’un site web leader dans sa thématique, j’ai
voulu partager mes acquis en abordant les optimisations de
performances, d’ergonomie et de référencement, jusqu’au modèle
économique.
◆ Erratum
◆ Remerciements
Je tiens à remercier les lecteurs de mon premier livre, sans qui cette
version entièrement nouvelle n’aurait pas existé.
Je remercie également mon éditeur, Jean-Luc Blanc, chez Dunod,
pour son professionnalisme. Il a réussi à me comprendre et à me
motiver.
Sans la patience et les encouragements de Stephy, je n’aurai jamais
été au bout de ce long travail.
Merci à ma mère pour la relecture attentive du manuscrit.
Mon chien, qui a supporté les longs mois d’écriture des deux livres,
ne verra hélas pas l’aboutissement de cette version.
Je profite également de cet espace un peu plus personnel pour
exprimer ma gratitude en tant qu’entrepreneur du web à trois
sociétés incontournables. Elles ont énormément participé à la
démocratisation d’Internet et donc à la réussite d’entreprises telles
que la mienne :
Google, pour avoir rendu l’accès à l’information bien plus facile
aux utilisateurs ;
Free et son patron emblématique, Xavier Niel, pour avoir créé
les forfaits illimités ADSL et Mobile à tarifs imbattables ;
OVH et son créateur, Octave Klaba, pour avoir offert des
solutions d’hébergement fiables et très abordables à tous les
diffuseurs de contenus.
PREMIÈRE PARTIE
Réflexions
autour du JavaScript
Objectif
Dans ce chapitre, nous allons définir les grands principes du
JavaScript dans l’appel et le rendu d’une page web et, au
travers de ses 25 ans d’histoire, ses possibilités, ses limites et
son avenir.
Hello(s) World(s)
Objectif
Dans ce chapitre, nous allons immédiatement démarrer la
programmation JavaScript via quelques exemples simples et
progressifs. Nous mettrons en place en parallèle
l’environnement de développement complet avec tous les
outils nécessaires pour bien coder et prendre de bonnes
habitudes.
Ici, le code HTML du fichier initial ne contient aucune balise h1. Il n’y
a que la balise body avec un identifiant qui nous permettra de la
trouver facilement. Le script crée une variable monH1 avec
l’instruction var et lui affecte un nouvel élément HTML de type H1
grâce à la fonction createElement(). La propriété innerHTML est
ensuite renseignée. Puis la fonction appendChild() sur la balise body
est appelée pour ajouter dans le document l’objet HTML monH1.
Finalement, le document HTML contient grâce à nos trois petites
lignes de JS un nouvel élément h1.
Rassurez-vous, nous verrons toutes les manipulations des éléments
HTML dans le chapitre 12.
Attention, les scripts publiés sur ces outils sont visibles par tous
les utilisateurs ayant le lien et risquent d’être référencés dans les
moteurs de recherche. Ne publiez pas de code comportant des
données confidentielles comme des clés API, des mots de
passe…
2.9.1 Indentation
2.9.2 Programmation
Il existe de nombreuses manières de présenter un bloc
d’instructions, même basique. Imaginons par exemple le test de
condition déterminant s’il faut annoncer « Bonjour » ou « Bonsoir »
au visiteur.
Les trois écritures suivantes sont toutes opérationnelles et
produisent strictement le même résultat.
L’écriture totalement compacte sur une seule ligne est vraiment peu
lisible :
if (heure<18){msg="Bonjour"}else{msg="Bonsoir"}
À son opposé, l’écriture très aérée l’est sans doute trop et occupe
beaucoup de place à l’écran pour un traitement très simple :
if (heure < 18)
{
msg = "Bonjour";
}
else
{
msg = "Bonsoir";
}
ou
var jour="Bonjour"
var soir="Bonsoir"
2.9.4 Commentaires
L’habitude veut que chaque fichier d’un projet débute par une courte
introduction sous forme de commentaires indiquant le but du fichier,
sa version, l’auteur, les travaux en cours…
Il peut aussi être judicieux d’utiliser les commentaires pour signaler
les grandes parties d’un traitement ou d’un fichier.
Pour rappel, les commentaires sont aussi pertinents en dehors du
JavaScript. En CSS, ils sont encadrés par /* et */, obligatoires
même sur une seule ligne. En HTML, ils sont à placer entre <!-- et
-->.
2.9.5 Réutilisabilité
2.9.6 Cohérence
Objectif
Dans ce chapitre, nous allons apprendre à intégrer du
JavaScript dans une page web, en tenant compte de son
impact sur le référencement dans les moteurs de recherche.
Nous allons aussi découvrir l’ensemble des structures de
script pour réaliser des traitements conditionnés ou répétitifs.
Les variables et les fonctions n’auront plus de secrets pour
vous. Notez que ces grandes notions de base du JavaScript
sont tout à fait réutilisables dans les autres langages de
programmation.
Commentaires
Pensez à commencer votre fichier .js par quelques lignes de
commentaires rappelant les grandes fonctionnalités du fichier
et dans quels cas il est utilisé.
◆ L’appel au fichier.js
Le code de notre page Hello World qui fait appel au fichier hello.js
devient :
<html>
<body>
<script type="text/javascript" src="hello.js"></script>
</body>
</html>
◆ L’appel asynchrone
Sensibilité à la casse
La casse est la distinction entre majuscule et minuscule. Le
JavaScript est sensible à la casse, c’est-à-dire que les
variables nom, Nom et NOM sont trois variables différentes,
contenant des données différentes. Cette sensibilité est
source d’erreur à l’exécution à partir d’une simple erreur de
frappe. De bonnes règles de nommage sont un bon moyen
de les limiter.
Contenant et contenu
Ne confondez pas le nom de la variable et son contenu.
console.log("compteur") affichera la chaîne de caractères
"compteur". Tandis que console.log(compteur) affichera le
contenu de la variable compteur.
La coloration syntaxique de l’éditeur de texte distingue les
chaînes de caractères des variables.
◆ L’opérateur typeof
◆ Le type undefined
◆ Le type number
◆ Le type object
◆ Le type boolean
Une constante est comparable à une variable qui ne peut pas être
modifiée une fois créée. Une constante est déclarée par const avec
une valeur d’initialisation obligatoire. Si le script tente de changer la
valeur de la constante, une erreur du type TypeError: Assignment to
constant variable est déclenchée.
Une constante dans un script peut être, par exemple, le taux de
conversion entre le franc et l’euro.
Il y a un double intérêt à utiliser une constante à la place d’une
variable qui ne sera jamais modifiée à l’exécution :
Le développeur indique directement dans le code que la
constante est destinée à être fixe.
Le navigateur s’assure à l’exécution qu’une erreur de
programmation ne viendra pas modifier cette valeur.
Quand on déclare une variable avec let au lieu de var, sa portée est
limitée au bloc où la déclaration est faite. Voici quelques exemples
de portées de variables créées avec let :
let a=1, b=1; // Déclaration dans le bloc de plus haut niveau
console.log(a); // affiche 1
if (a==1) {
let b=0; // Déclaration de b dans un bloc inférieur
console.log(a); // affiche 1
console.log(b); // affiche 0
}
console.log(b); // affiche 1
Une variable déclarée avec let est visible dans les blocs de plus bas
niveau. Dans le bloc de condition if, une nouvelle variable b est
créée et initialisée à 0. La variable b du bloc supérieur n’est pas
affectée à la fin du bloc if et vaut toujours 1.
Même si cette écriture n’est pas très lisible, elle est régulièrement
utilisée pour sa compacité et l’économie de quelques octets réalisée.
Le JavaScript ne possède pas de condition elseif comme d’autres
langages. Il est cependant possible de faire un enchaînement de
conditions en ajoutant un espace entre else et if pour obtenir else if.
Imaginons que notre calcul de frais de port nécessite finalement
deux paliers. Un premier à 6,90 pour moins de 50 euros d’achat et
un second à 3,90 pour moins de 100 euros et toujours le port offert
au-delà. Le calcul de port pourrait s’écrire :
if (montant>1=00) {
var port=0;
} else if (montant>=50) {
var port=3.9;
} else {
var port=6.9;
}
Il existe une autre manière de traiter des tests multiples, cette fois-ci
sur des conditions d’égalité. L’écriture est particulière et présente
cette structure :
switch (expression) {
case valeur1:
blocInsctructions1
break;
…
case valeurN:
blocInsctructionsN
break;
default:
blocInsctructionsDefault
}
L’opérateur ternaire doit son nom aux trois parties qui composent
son écriture. Il permet de tester une condition et de retourner une
valeur si la condition est remplie et une autre si la condition est
fausse. Sa syntaxe utilise le point d’interrogation ? pour signaler la
fin de la condition et le caractère deux-points : pour séparer les deux
valeurs de retour possibles :
Condition ? valeurSiVrai : valeurSiFaux
◆ Opérateur d’égalité
L’opérateur d’égalité dans une condition est le signe égal doublé ==.
Il est doublé pour matérialiser la comparaison et non l’affectation
d’une valeur à une variable. Voici quelques exemples de
comparaisons d’égalité :
var nb=5;
nb==5; // true
nb==6; // false
nb=="5"; // true
nb==10/2; // true
◆ Opérateurs de différence
◆ Autres opérateurs
◆ La valeur null
/* Egalités faibles */
console.log(null == false); // false
console.log(null == undefined); // true
/* Egalités strictes */
console.log(null === false); // false
console.log(null === undefined); // false
/* Affectations et types */
var monNull=null, monNullBis=null;
console.log(typeof monNull); // object
console.log(typeof inconnu); // undefined
console.log(monNull === monNullBis); // true
Il est à noter que, dans le cas d’une égalité faible, null et undefined
sont équivalents. Pourtant, il est possible d’affecter une variable
avec la valeur null.
La boucle for est idéale pour traiter les éléments d’un ensemble dont
on connaît à l’avance le nombre d’occurrences. Elle est très utilisée
avec les tableaux de données pour effectuer une action sur chacun
de ses éléments.
Il est possible d’arrêter une boucle for avant la fin prévue par le test
de condition en utilisant l’instruction break. La boucle s’interrompt et
le script se poursuit après le bloc d’instructions for { … }.
Même si cet usage est peu fréquent, il peut se révéler utile pour
accélérer des traitements en arrêtant une boucle, si le résultat est
déjà trouvé par exemple. Nous verrons d’autres exemples de
boucles for dans le chapitre sur les tableaux de données à partir
d’ici.
Les boucles sans fin sont bien gérées par les navigateurs, qui
permettent à l’utilisateur de reprendre la main en quelques
secondes. Mais elles représentent un vrai danger dans d’autres
langages. Sur un serveur avec un disque dur SSD, une boucle
sans fin qui ajoute une entrée dans une base de données ou dans
un fichier texte peut remplir complètement un disque dur en
quelques secondes seulement. Dans ce cas, le serveur ne
répondra plus et il faudra probablement passer par un
administrateur ou l’infogérance pour purger le disque.
3.6.3 Les boucles conditionnées
Une boucle while (« tant que ») est exécutée tant que sa condition
est vraie. Elle est définie par cette structure :
while (condition) {
// Traitements de la boucle
}
Si, dès le départ, la condition n’est pas vraie, le script n’entre pas du
tout dans la boucle.
Écrivons notre script de recherche de la valeur de n telle que la
somme de 1 à n vaille plus de 1 000 :
<h1 id="monH1"></h1>
<script type="text/javascript">
var n=0, somme=0; // Déclaration de la variable qui stocke la somme
while (somme<1000) {
n++; // n est incrémenté de 1
somme+=n; // A chaque passage de la boucle, la somme est complétée
}
document.getElementById("monH1").innerHTML="Somme = "+somme+" pour n =
"+n;
</script>
Dans les deux cas, nomFonction() est une fonction qui peut être
appelée dans le reste du script.
Une fonction qui ne possède pas de paramètre est déclarée avec les
parenthèses vides.
◆ Retourner un résultat
function getMessage() {
var msg="Bonjour dans la fonction";
nb++;
console.log("nb dans la fonction = " + nb)
console.log("msg dans la fonction = " + msg);
}
// Appel de la fonction
getMessage();
console.log("nb après appel de la fonction = " + nb);
console.log("msg après appel de la fonction = " + msg);
Il n’est pas utile de nommer une fonction qui ne sera pas appelée et
réutilisée ailleurs dans le code JavaScript. On peut donc déclarer
des fonctions anonymes, littéralement « qui n’ont pas de nom ».
◆ Le minuteur setInterval()
Objectif
Nous avons déjà utilisé à de nombreuses reprises quelques
manipulations de chaînes de caractères au cours des
exemples des chapitres précédents.
Le JavaScript est parfaitement adapté pour réaliser des
traitements puissants afin d’optimiser l’affichage
d’informations et de contrôler des données et des saisies des
utilisateurs.
Pour définir une chaîne, il faut utiliser les séparateurs prévus dans le
langage. En JavaScript, comme dans de nombreux autres langages,
deux séparateurs sont à notre disposition :
Le guillemet " est le plus courant.
L’apostrophe ' est aussi utilisée.
Voici quelques utilisations correctes de chaînes :
var msg="Hello World";
var txt='Hello World';
var str="";
console.log("Bonne lecture");
Attention, les bons séparateurs sont bien les " et ' et non pas les
caractères d’imprimerie que les logiciels comme Word utilisent.
Les séparateurs « et ‘ ne fonctionneront pas et déclencheront une
erreur. Word n’est pas un bon éditeur de texte pour coder.
Début de la chaîne
qui se poursuit sur la ligne 2
puis la ligne 3
Une chaîne de caractères peut aussi être créée à partir de tout objet
JavaScript et de sa méthode de conversion vers une chaîne
toString(). Créons quelques variables JavaScript pour observer le
fonctionnement de la conversion :
Ainsi, l’appel à :
" mon texte ! ".trim()
Dans tous les langages, les caractères spéciaux présents dans les
chaînes posent des difficultés d’interprétation et des risques de perte
de données. Le JavaScript propose un couple de fonctions
d’encodage et de décodage des caractères spéciaux, et des
caractères à risque comme l’espace, les caractères accentués, les
signes + =, etc.
La fonction d’encodage encodeURIComponent() retourne la chaîne
passée en paramètre encodée. Elle remplace la fonction dépréciée
escape() :
String encodeURIComponent(String chaine)
Fonctionnalité dépréciée
Une fonctionnalité dépréciée dans un langage signifie qu’elle
n’est plus maintenue et devient obsolète. Le risque de
continuer à utiliser une fonction dépréciée est de la voir
disparaître complètement et d’aboutir après quelques années
à un script en erreur. Un suivi des actualités du langage est
indispensable pour garantir un code durable.
Ce motif est séparé en trois parties. Le jour est un chiffre sur deux
caractères suivi d’un séparateur – ou / présent obligatoirement. La
partie du motif concernant le mois est identique. L’année est sur
quatre chiffres.
Nous pourrions être encore plus précis sur le motif. Le jour ne peut
pas commencer autrement que par 0, 1, 2 ou 3. Le mois ne peut
commencer que par 0 ou 1. Le nouveau motif s’écrit donc :
[0123][0-9]{1}[-/]{1}[01][0-9]{1}[-/]{1}[0-9]{4}
Les mathématiques
Objectif
Le JavaScript est à l’aise avec les traitements mathématiques
de calculs classiques de type monétaire ou statistique. Il est
aussi capable de réaliser des traitements avec des fonctions
trigonométriques.
Dans ce chapitre, nous allons parcourir l’ensemble des
possibilités mathématiques du langage.
◆ Not a Number
◆ Infinity
console.log(getHumanSize(1050)); // 1.0 ko
console.log(getHumanSize(400000)); // 390.6 ko
console.log(getHumanSize(5000000)); // 4.8 Mo
8 560,154
123 456 789,154
5 000,00 €
14,99 €
$50,000.00
$1,400.99
Manipulation de dates
Objectif
Sur les sites Internet, les dates sont omniprésentes, du simple
affichage de la date de publication d’un article à la saisie
précise d’un horaire de réservation d’un moyen de transport.
Le JavaScript propose nativement de nombreuses
fonctionnalités de manipulation des dates ou des heures et
des fonctions de formatage de leur affichage.
L’objet Date est intelligent. Il est capable de transformer une date qui
n’existe pas en date réelle. Ainsi, la création d’une date fixée au
29 février 2019 crée en fait une date au 1er mars 2019. Voici
quelques exemples de création de dates :
var jour1=new Date(2019, 11, 25, 23, 59, 59);
var jour2=new Date(2019, 1, 29);
var jour3=new Date(2019, 1, 28, 28, 0, 0);
var jour4=new Date(1234567890000);
console.log(jour1);
console.log(jour2);
console.log(jour3);
console.log(jour4);
Notez que les indices des mois sont systématiquement réduits d’une
unité. Le mois de février a comme indice 1.
L’affichage brut des objets Date utilise un format ISO. Il a l’avantage
d’être universellement reconnu par tous les langages. Mais il n’est
pas franchement intuitif pour un humain.
La date du 1er janvier 1970 est importante pour la gestion des dates.
Elle est considérée comme l’an zéro de l’informatique. Toutes les
dates sont ainsi exprimées par le nombre de secondes les séparant
de l’an zéro. Heureusement, le JavaScript peut aussi manipuler des
dates plus anciennes.
Attention au format anglo-saxon des dates
Les dates en JavaScript sont pensées dans le format anglo-
saxon. La semaine commence le dimanche et les dates sont
exprimées avec le mois placé avant le jour. De plus, le
décalage d’une unité sur l’indice du mois est systématique.
Ces particularités peuvent être déroutantes et génératrices de
bug sur les déclarations de vos dates.
Les tableaux
Objectif
Nous avons déjà utilisé à plusieurs reprises les tableaux de
données dans des exemples des chapitres précédents. En
programmation, les tableaux sont des structures de données
incontournables et très souvent utilisées. Nous allons dans ce
chapitre comprendre pourquoi les tableaux sont si utiles,
apprendre à les créer et à les utiliser, explorer toutes les
possibilités de manipulations des tableaux en JavaScript, et
enfin créer quelques fonctions qui manquent au langage.
[]
(7) ["Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim"]
(5) [empty × 5]
(4) [2, 4, 6, 8]
Lun,Mar,Mer,Jeu,Ven,Sam,Dim
La console contient :
Avec ce mode de copie, une action sur le tableau days n’a aucun
impact sur le tableau jours. La console affiche donc deux tableaux
différents :
EUR : Euro
USD : Dollar américain
BTC : Bitcoin
◆ concat()
La méthode concat() retourne un nouveau tableau, constitué de la
fusion entre le tableau sur lequel elle s’applique et les tableaux
passés en paramètres :
Array tableau.concat(Array tableau1 [, … Array tableauN])
◆ every()
Pour tester qu’un tableau ne contient que des nombres pairs, il suffit
d’appeler every() avec une fonction anonyme en paramètre :
var nombres=[4,8,1000,1500];
console.log(nombres.every(function(valeur) {
return (valeur%2==0);
})); // Retourne true
◆ filter()
Pour filtrer tous les éléments pairs d’un tableau, il faut écrire :
var nombres=[4,3,8,11,12,15];
var pairs=nombres.filter(function(valeur) {
return (valeur%2==0);
});
console.log(pairs.toString()); // Affiche 4,8,12
◆ forEach()
◆ indexOf() et lastIndexOf()
◆ join()
◆ map()
◆ pop()
◆ push()
◆ reduceRight()
◆ reverse()
◆ shift()
◆ slice()
La méthode slice() (« trancher » en français) retourne un nouveau
tableau composé de l’extrait du tableau initial entre l’indice de début
inclus et l’indice de fin exclu.
Array tableau.slice(Integer indiceDebut, Integer indiceFin)
◆ some()
◆ sort()
◆ splice()
◆ unshift()
◆ Mélanger un tableau
Nov,Jan,Mar,Jui,Aou,Fév,Sep,Déc,Oct,Mai,Avr,Jul
Jan
Nov,Jan,Jui
◆ Dédoublonner un tableau
Jean,Gérard,Pierre,Paul,Jean,Paul,Jacques
Jean,Gérard,Pierre,Paul,Jacques
Objectif
Le JavaScript est un langage objet et nous avons déjà utilisé
dans les chapitres précédents quelques notions de la POO,
programmation orientée objet (OOP en anglais pour Object-
Oriented Programmation). Il est maintenant temps de rentrer
dans le détail de ce concept et des particularités du
JavaScript.
Avec les crochets, nous pouvons utiliser une boucle sur un indice
variant de 1 à N et construire le nom de la propriété montantI. La
somme devient donc :
var somme=0;
for (var i=1 ; i<=N ; i++) {
somme+=obj["montant"+i];
}
8.1.5 Le constructeur
8.1.6 L’héritage
Le mot clé extends permet d’indiquer qu’une classe fille hérite d’une
classe mère. La fonction super() appelle constructor() de la classe
mère :
class Chat extends Animal {
constructor(nom, sexe, age, photo) {
super(nom, sexe, age, photo);
this.cri="Miaulement";
this.male="Chat",
this.femelle="Chatte";
}
}
La console affiche :
Les objets créés par classe ou par constructeur sont de type Object
pour le JavaScript, car ils dérivent du constructeur Object() de plus
bas niveau dans la hiérarchie objet du langage.
Pour obtenir le constructeur précis d’un objet, il faut utiliser sa
propriété constructor, qui retourne une référence vers sa fonction
constructeur. La propriété constructor.name donne le nom de la
fonction constructeur ou de la classe :
console.log(garfield.constructor.name); // Affiche creerChat
console.log(kitty.constructor.name); // Affiche Chat
◆ Le principe de polyfill
La console affiche :
Object.prototype.toConsoleStrings = function(prefix="") {
return [prefix+this.toString()];
}
Un tableau JSON est une suite de valeurs séparées par des virgules
et placée entre crochets. La structure générique d’un tableau JSON
est donc :
[ valeur1, …, valeurN ]
◆ La syntaxe générale
Nous allons créer l’objet truiteFario par JSON, qui définit quelques
caractéristiques d’une truite fario :
var truiteFario={
nom: "Fario",
noms: ["Truite sauvage","Truite commune"],
latin: "salmo truta fario",
image: "fario.jpg",
particularite: "Présence de points rouges et noirs auréolés",
tailleMoyenne: 30,
tailleMaxi: 70,
maille: 25,
};
Comme pour les objets créés par leur constructeur natif, l’accès aux
propriétés peut se faire aussi par les crochets. Ainsi, le second nom
alternatif est trouvé indifféremment par :
truiteFario["noms"][1]
ou par :
truiteFario.noms[1]
Le JSON est très utilisé pour passer des paramètres à une fonction.
L’avantage principal est de ne pas avoir à respecter l’ordre des
paramètres de la déclaration de la fonction. L’autre avantage est que
la définition de nouveaux paramètres est facilitée. Imaginons une
fonction qui attende dix paramètres nommés param1 à param10. La
déclaration classique serait :
function maFonction(param1, …, param10) { /* Traitements */ }
◆ Échange de données
Notez que les propriétés sont bien des chaînes entourées des " et
qu’il n’y a pas de virgule après la dernière propriété. La méthode
display() a été ignorée car elle n’est pas compatible avec le format
JSON officiel.
La méthode stringify() retourne toujours la chaîne la plus courte
possible en supprimant tous les espaces inutiles.
Le JSON ne supporte pas directement les tableaux associatifs. La
linéarisation d’un tableau indicé de monnaies retourne un tableau
vide :
var monnaies=[];
monnaies["EUR"]="Euro";
monnaies["USD"]="Dollar américain";
monnaies["BTC"]="Bitcoin";
console.log(JSON.stringify(monnaies)); // Affiche un tableau vide []
{"EUR":"Euro","USD":"Dollar américain","BTC":"Bitcoin"}
_ 8. 4 RÉSUMÉ DE LA POO JAVASCRIPT
Terminons ce chapitre par un résumé des particularités de la
programmation orientée objet en JavaScript.
◆ La solution brute
◆ Le format JSON
Réintroduction au JavaScript
Objectif
Ce chapitre présente toutes les nouveautés du JavaScript
depuis sa révision ECMAScript 6 de 2015 et quelques usages
du JavaScript largement utilisés. Sa lecture sera
particulièrement instructive pour les développeurs ayant une
connaissance plus ancienne du langage. Notez que
l’ensemble du livre utilise le JavaScript dans sa version ES6.
Ce chapitre est une synthèse rapide des évolutions, avec des
renvois vers d’autres chapitres.
Une fonction anonyme est une fonction qui a été créée sans être
nommée. Le plus souvent, les fonctions anonymes sont créées
lorsqu’elles ne sont appelées qu’une seule fois, à l’endroit de leur
création. Par exemple, dans la méthode map() d’un tableau :
var textes=["Bonjour","tout","le","monde"];
console.log(textes.map(function(v) {return v.length;})); // (4) [7, 4, 2, 5]
Une fonction peut contenir dans son code des déclarations d’autres
fonctions intermédiaires nécessaires au traitement principal. Ces
fonctions internes (inner functions) ne sont pas visibles, ni
utilisables, dans le reste du code en dehors de la fonction mère.
La syntaxe générique est :
function principale(v1, v2, v3) {
function interne(p1, p2) {
/* return expression */
}
/* Instructions */
}
Objectif
L’objet window étant l’objet de plus haut niveau dans la
hiérarchie des objets JavaScript, il est le support de
nombreux autres objets et de quelques fonctionnalités que
nous allons étudier dans ce chapitre.
◆ Boîte d’information
◆ Boîte de confirmation
◆ Boîte de saisie
hash:"#res"
host:"www.toutjavascript.com"
hostname:"www.toutjavascript.com"
href:"http://www.toutjavascript.com/reference/chercher.php?
mot=location#res"
origin:"http://www.toutjavascript.com"
pathname:"/reference/chercher.php"
port:""
protocol:"http:"
search:"?mot=location"
10.1.7 L’impression
◆ L’en-tête X-Frame-Options
Cette option permet de maîtriser la façon dont votre site peut être
embarqué dans d’autres sites.
DEUXIÈME PARTIE
L’interactivité
La programmation
événementielle
Objectif
Dans ce premier chapitre de cette seconde partie, nous allons
aborder la programmation événementielle, qui est au cœur de
l’interactivité du web. Nous verrons comment détecter les
événements de la page et comment déclencher des actions
associées.
_ 11.1 PROGRAMMATION
ÉVÉNEMENTIELLE
Le JavaScript est un langage événementiel, c’est-à-dire qu’il détecte
les événements qui surviennent sur la page, y réagit et déclenche de
nouveaux traitements. Un événement en programmation est un
changement d’état qui survient sur la page. Les types d’événements
sont très variés :
Le mouvement de souris.
Le clic sur un élément.
L’appui d’une touche du clavier.
Le chargement d’un élément de la page.
La rotation du smartphone en mode paysage.
Le redimensionnement de la fenêtre.
La perte de connexion Internet.
Si la programmation par événements est indispensable pour créer
de l’interactivité, elle implique également d’observer une rigueur
dans la conception. Les événements sont susceptibles de survenir à
tout moment, ou de ne pas se produire du tout. L’ordre des
événements et des actions prévu par le développeur a aussi toutes
les chances de ne pas être respecté par l’utilisateur. Des
événements parasites peuvent aussi se déclencher, comme un
chargement d’élément critique ralenti ou une coupure de connexion.
Il faut donc s’assurer que la fonctionnalité d’une page est cohérente,
même si l’utilisateur oublie ou inverse des étapes ou si la page subit
des lenteurs de chargement.
La programmation événementielle s’oppose dans le principe à la
programmation séquentielle :
Programmation
Programmation événementielle
séquentielle
Traitements
Ordre des événements inconnu
parfaitement séquencés
Traitements
Survenue d’un événement non garantie parfaitement
prédictibles
Traitements parasites
Événement parasite possible
impossibles
function clickDiv1(e) {
console.log("Click1 : bubbles="+e.bubbles+" cancelBubble="+e.cancelBubble);
}
function clickDiv2(e) {
e.stopPropagation();
console.log("Click2 : bubbles="+e.bubbles+" cancelBubble="+e.cancelBubble);
}
Manipuler le document
Objectif
Dans ce chapitre, nous étudierons toutes les manipulations
du document. Nous verrons comment trouver les éléments
HTML par leur balise, leur nom ou leur classe CSS, comment
modifier leur style, leur position et leur apparence. Nous
verrons aussi comment ajouter dynamiquement du contenu
dans la page.
L’accès par sélecteur CSS utilise la notation CSS pour atteindre les
éléments du document.
La méthode querySelectorAll() retourne tous les éléments répondant
au sélecteur CSS passé en paramètre :
NodeList document.querSelectorAll(String selecteurCSS)
La console affiche :
NodeList(3) [p.para, p.para, p.para.paraBold]
NodeList [div#bloc]
Notez que les méthodes de recherche d’éléments HTML sont
aussi disponibles depuis d’autres éléments HTML. Dans ce cas,
la recherche ne se déclenche pas sur l’ensemble du document,
mais seulement dans les nœuds internes à l’élément. Ainsi,
l’appel à
document.getElementById("bloc").getElementsByTagName("p")
ne retourne que les trois paragraphes du bloc d’identifiant bloc
HTMLCollection(3) [p.para, p.para, p.para.paraBold]
◆ Accès directs
La console contient :
<h1 id="monH1" class="titre">Manipulation des
<strong>éléments</strong></h1>
La propriété innerText contient le texte du contenu débarrassé du
code HTML :
console.log(document.getElementById("monH1").innerText);
◆ Manipuler le style
L’usage direct des propriétés de style n’est pas une approche idéale.
L’utilisation de classes CSS est préférable et facilite les évolutions :
pour modifier l’apparence à l’issue d’un événement, aucune mise à
jour de code JavaScript n’est nécessaire, seule la classe CSS sera à
corriger.
La propriété className d’un élément contient la chaîne de
caractères de l’attribut class :
console.log(getComputedStyle(document.getElementById("monH1")));
La console contient :
para paraBold
La propriété classList d’un élément contient une sorte de tableau
DOMTokenList des classes CSS. Cette structure est plus simple à
manipuler, en particulier lorsque plusieurs classes sont utilisées
simultanément :
console.log(document.querySelector("p.para.paraBold").classList);
Notez que les animations ne sont pas une fin en soi. Elles doivent
amener de la valeur ajoutée pour l’utilisateur et ne pas le gêner.
Par exemple, des animations trop lentes, qui ralentissent les
actions des utilisateurs, sont à proscrire.
12.6.4 Le copier-coller
Le clic sur le bouton déclenche une fonction qui repère dans data-
copy l’identifiant du div à copier dans le presse-papiers :
function btnCopy(evt) {
var btn=evt.currentTarget;
/* Recherche de l'identifiant du contenu à copier */
var id=btn.dataset.copy;
var elt=document.getElementById(id);
elt.parentNode.className="container";
console.log("ID de l'élément à copier = "+id);
/* Création de la sélection par programmation de Range */
var sel=window.getSelection();
var range=document.createRange();
range.selectNodeContents(elt);
console.log(range.toString());
sel.removeAllRanges();
sel.addRange(range);
/* Copy in the clipboard */
document.execCommand("copy");
/* Animation css flash sur l'élément container parent */
elt.parentNode.className="container flash";
/* Effacement de la sélection */
range.collapse();
}
Pour signaler à l’utilisateur que son adresse Bitcoin est bien dans le
presse-papiers, une animation CSS via @keyframes lance un flash
sur la zone div.container. La sélection est supprimée avec collapse().
Le script complet est disponible à l’adresse http://tjs.ovh/copy.
Le presse-papiers contient potentiellement des données
sensibles, issues d’autres applications, comme des mots de
passe ou des clés privées. L’accès en lecture au contenu du
presse-papiers est donc restreint par les navigateurs.
Les formulaires
Objectif
Dans ce chapitre, nous allons étudier les formulaires et leurs
différents éléments. Ils permettent aux utilisateurs de saisir
facilement des informations. Même si les interactions sur les
sites web se font de plus en plus de façon plus fluide et
ludique, les formulaires restent indispensables pour envoyer
des données vers le serveur.
◆ La détection de la soumission
Ici, pour empêcher le formulaire d’être soumis si une saisie n’est pas
correcte, nous utilisons la méthode preventDefault().
◆ Les événements
◆ Les méthodes
◆ L’accès JavaScript
Les navigateurs ont mis en place des interfaces plus intuitives pour
la saisie de données structurées. Par exemple, pour la saisie de
date, il suffit de définir l’élément input avec le type date :
<input type="date" name="birthday" />
L’usage du protocole https:// sur des pages avec des mots de passe
est fortement recommandé. Le navigateur affiche dans la barre
d’URL un message inquiétant pour un utilisateur non informé :
Les boutons sont aussi des éléments input. Il existe trois types de
boutons associés à un formulaire :
Le bouton d’action de type button, associé à un événement
onclick :
<input type="button" value="Cliquez le bouton" />
Le bouton de soumission de type submit, qui déclenche la
soumission du formulaire :
<input type="submit" value="Soumettre" />
Le bouton de type image est peu employé. Ce bouton se
comporte comme un bouton submit mais est remplacé par une
image :
<input type="image" src="imagebouton.jpg" />
Par défaut, les boutons, ainsi que tous les autres éléments du
formulaire, sont mis en forme par le style natif du navigateur et du
système d’exploitation. Avec quelques propriétés CSS, il est
possible d’obtenir un rendu équivalent sur tous les navigateurs.
◆ La balise button
◆ Les checkbox
Une checkbox est idéale pour poser une question fermée, qui attend
comme réponse Oui ou Non :
<input type="checkbox" name="reglement" value="1" />
J'accepte le règlement du site Internet
Les cases à cocher sont très petites et donc difficiles à cliquer. Pour
faciliter l’interaction, le bon réflexe est de lier le libellé avec la case
concernée. Ainsi, un clic sur le libellé cochera ou décochera sa case.
La liaison se réalise entièrement en HTML avec la balise <label> qui
reçoit dans son attribut for l’identifiant de la case associée.
Pour associer le texte d’acceptation à la case à cocher cgv, il suffit
d’écrire :
<input type="checkbox" name="cgv" id="cgv" value="1" />
<label for="cgv">J'accepte les conditions de vente</label>
◆ L’accès en JavaScript
Le champ file est caché et il est relié avec l’événement onclick sur le
div#depose :
var depose=document.getElementById("depose");
depose.addEventListener("click", function(evt) {
evt.preventDefault();
document.getElementById("file").click();
});
◆ Le format Markdown
Une zone textarea est donc idéale pour faire saisir du texte formaté
en Markdown à un utilisateur. Le texte saisi est ensuite envoyé au
serveur à la soumission du formulaire, sauvegardé dans une base
de données et affiché en HTML grâce à une bibliothèque de
conversion Markdown vers HTML.
Objectif
Dans ce chapitre, avec les appels AJAX (Asynchronous
JAvascript & Xml), nous allons étudier une fonctionnalité
fondamentale de la programmation web aujourd’hui. Le mot le
plus important dans l’acronyme est bien « Asynchronous ».
Ces appels permettent de communiquer entre le client et le
serveur de manière transparente, sans rechargement de page
et sans interruption dans la navigation.
◆ Les méthodes
◆ Les propriétés
◆ Les événements
L’appel précédent a été conçu sans tenir compte du fait que des
événements perturbateurs peuvent se produire. L’API du site
cryptocompare.com peut être en panne et ne pas répondre ou
retourner du contenu non valide.
Pour garantir un fonctionnement cohérent dans toutes les situations,
il est nécessaire de détecter :
Une erreur dans l’appel, en utilisant l’événement onerror sur
l’objet XMLHttp Request.
Un mauvais contenu JSON retourné par l’appel, en utilisant le
bloc try catch.
Vous trouverez plus de détails sur la gestion de ces erreurs dans le
chapitre suivant, à partir d’ici.
14.3.1 La sécurité
La sécurité est l’élément essentiel des appels AJAX. Les navigateurs
ont introduit par défaut des processus de blocage d’appel assez
stricts, pour empêcher les attaques par XSS (Cross-Site Scripting).
Ces attaques utilisent une faille de sécurité permettant d’injecter du
contenu ou du code non légitime. L’utilisateur est alors soumis à de
fausses informations ou plus souvent à du code JavaScript
dangereux, destiné à lui dérober des données de connexion, à lui
afficher des publicités ou à le rediriger vers un site pirate.
Ainsi, par défaut, un appel AJAX vers un domaine différent du
domaine d’origine est interdit.
14.3.5 Référencement
14.3.6 Ergonomie
Nous verrons ici comment réaliser des appels AJAX avec jQuery.
15
Objectif
Dans ce chapitre, nous allons étudier comment repérer et
traiter les erreurs JavaScript. La gestion des erreurs peut
paraître inutile à première vue, car un bon développeur ne
laisse pas de bug ni de code susceptible de produire des
erreurs. Ce chapitre ne traite pas des erreurs issues d’une
programmation bancale mais des erreurs qui surviennent
inévitablement dans l’environnement complexe et imprévisible
de l’Internet.
La console n’a remonté aucune erreur et notre bloc catch s’est bien
exécuté :
Début de maFonctionAvecErreur()
Entrée dans le bloc catch(err)
(3) ["ReferenceError", "Error", "Object"]
Event onerror
(3) ["ErrorEvent", "Event", "Object"]
ReferenceError: fonctionInconnue is not defined at error.html:82
Objectif
Dans ce chapitre, nous allons étudier comment stocker des
informations sur le poste de l’utilisateur. La méthode la plus
connue utilise naturellement les cookies. Il existe cependant
une autre solution permettant de stocker de grandes quantités
d’informations.
16.1.2 La réglementation
Les cookies tiers sont des cookies enregistrés par des services
externes au site consulté. Ils sont à la base de l’agacement des
utilisateurs et des risques sur la vie privée. Les services externes qui
déposent des cookies tiers sont le plus souvent des régies
publicitaires ou des réseaux sociaux (qui ne sont en fait que des
régies publicitaires pour leur propre compte). La force de frappe de
ces services, qui touchent des centaines de millions d’utilisateurs,
leur permet de cibler tout le monde, tout le temps.
C’est ainsi que nous voyons des publicités de retargeting
(« reciblage publicitaire » en français) pour nous vendre une paire de
chaussures.
◆ Enregistrer un cookie
◆ Lire un cookie
nom=Jean-Claude; firstVisite=1531048355876;
IDuser=user544572
◆ Effacer un cookie
Tous les cookies d’un domaine sont transmis vers le serveur dans la
rubrique Request Headers de l’en-tête HTTP. Pour nos trois cookies
en cours, la console du navigateur affiche bien :
Les cookies sont bien reçus par le serveur et peuvent être manipulés
pour personnaliser l’affichage de la page.
Le serveur peut aussi écrire des cookies avec la fonction setcookie()
en PHP par exemple. Un cookie créé par le serveur est envoyé à
son tour dans l’en-tête HTTP et écrit par le navigateur sur le disque
dur de l’utilisateur.
_ 16. 2 LE STOCKAGE DE DONNÉES
LOCALES
16.2.1 L’objet Storage
L’effacement de tous les couples clé : valeur est réalisé avec clear().
Le nombre de clés enregistrées est retourné par la propriété au nom
classique length. Cette propriété permet de parcourir toutes les clés
enregistrées avec key() :
String localStorage.key(Integer numCle)
La géolocalisation
Objectif
Dans ce court chapitre, nous allons étudier comment obtenir
la géolocalisation précise d’un internaute, qu’il utilise une
connexion Internet fixe ou le réseau mobile, que son
navigateur soit équipé d’un GPS ou non.
Cette fonctionnalité est utilisée sur des appareils mobiles, dans des
applications de guidage GPS ou de suivi d’activités physiques. Elle
entraîne une plus grosse consommation d’énergie.
Les notifications
Objectif
Dans ce chapitre, nous allons étudier comment utiliser le
système de notifications du système d’exploitation pour
envoyer des informations aux utilisateurs.
18.2.4 L’affichage
18.2.5 À retenir
Objectif
Dans ce chapitre, nous allons apprendre à dessiner sur une
page du navigateur. Le dessin avec HTML5 et JavaScript est
extrêmement puissant : il est possible de réaliser des
graphiques interactifs et même des jeux en 3D. Nous nous
contenterons ici d’étudier les différentes formes de dessins en
2D et leur animation.
myContext.lineWidth=5;
myContext.strokeStyle="#FFA500";
myContext.setLineDash([8, 3]); /* Pointillé 8px plein, 3px vide */
myContext.beginPath();
myContext.moveTo(150,0); /* Placer le curseur au début */
myContext.lineTo(150,300); /* Ligne verticale */
/* Dessine le path (ici une seule
myContext.stroke();
ligne) */
Il existe bien sûr d’autres fonctionnalités pour tracer des formes plus
complexes.
Une courbe de Bézier est une ligne courbe entre un point de départ
et un point d’arrivée. La forme de la courbe est définie par deux
points de contrôle, qui attirent et déforment la ligne initiale. La
méthode bezierCurveTo() crée une courbe entre la position du
pointeur courant et la position (x2, y2), avec les points de contrôle
(xc1, yc1) et (xc2, yc2) :
myContext.bezierCurveTo(xc1, yc1, xc2, yc2, x2, y2)
Pour afficher l’image du logo JS, on crée un objet Image. Une fois
l’image chargée, l’événement onload est déclenché et drawImage()
est appelée :
var logo=new Image();
logo.src="media/logo-js.png";
logo.onload=function() {
console.log(logo.src+" chargée");
myContext.drawImage(logo, 2, 2, 250, 250);
};
Ainsi, l’appel à :
console.log(myCanvas.toDataURL().substr(0,100)+"…");
Notez que l’ensemble des fonctions vues ici sont de bas niveau. Il
existe de très nombreuses bibliothèques de dessin en JavaScript
qui accélèrent et simplifient la création graphique. Les plus
connues sont détaillées dans la troisième partie de ce livre, à
partir d’ici.
Monétisation et publicité
Objectif
Dans ce chapitre, nous allons découvrir la place centrale du
JavaScript dans toutes les possibilités de monétisation de
contenu et d’audience sur Internet, l’impact des bloqueurs de
publicité et les moyens pour les détecter.
_ 20.1 LA MONÉTISATION
La monétisation des sites éditoriaux, c’est-à-dire ceux proposant du
contenu (article, reportage, test, avis, photo, vidéo…) et non ceux
qui ont pour objet la vente en ligne, est depuis l’origine d’Internet un
véritable enjeu pour leurs créateurs. Qu’il s’agisse d’un site amateur
ou d’un site professionnel avec des salariés, la recherche de
l’équilibre financier est souvent un objectif de survie à moyen terme.
Les modes de monétisation sont déjà innombrables et il en apparaît
de nouveaux régulièrement, créés par des développeurs à
l’imagination débordante. Certains modèles économiques abusent
des utilisateurs et sont à la limite ou même en dehors de la légalité :
Installation de logiciels malveillants destinés à diffuser
massivement de la publicité ou à récolter des données privées
ou bancaires.
Installation de rançongiciels (ransomware).
Proposition d’achat douteux sur des offres trop alléchantes (par
exemple un produit gratuit qui entraîne un abonnement
mensuel).
Proposition d’achat inutile ou dangereux basé sur la peur (par
exemple une fausse alerte de virus pour vendre un logiciel de
sécurité).
Détournement de trafic vers des sites contrefaits (phishing)
pour s’introduire dans des comptes privés de messagerie, de
banques ou d’administration.
Détournement de l’ensemble des capacités matérielles des
appareils des utilisateurs pour fabriquer de la crypto-monnaie
(avec du JavaScript !) sans avertir l’utilisateur.
Placement de produits non signalés dans des vidéos, des posts
de réseaux sociaux ou de blogs.
Rédaction d’articles sponsorisés ou de complaisance, non
signalés dans les blogs.
Parmi les autres méthodes de monétisation, légales cette fois-ci,
notons :
La publicité sous toutes ses formes (détaillées au paragraphe
suivant).
La vente de liens sortants pour optimiser le référencement.
La résolution d’un problème nécessitant l’intervention humaine
sous forme de captcha.
La création de crypto-monnaie, sans saturation du processeur,
avec demande d’autorisation à l’utilisateur (voir
http://tjs.ovh/coin).
Enfin, il faut noter les tentatives de monétisation sous forme de
rémunérations offertes directement par les internautes :
Les dons simples (via PayPal par exemple) sans prestation en
échange.
Les abonnements payants pour obtenir un accès à des articles
exclusifs.
La navigation via le navigateur Brave, communautaire et
redistributif (voir http://tjs.ovh/brave).
Le JavaScript est très souvent utilisé dans l’ensemble de ces
procédés de monétisation, depuis leur mise en place jusqu’à la
mesure de l’audience générée et l’efficacité des dispositifs.
_ 20.2 LA PUBLICITÉ
20.2.2 Le marché
Introduction à Node.js
Objectif
Dans ce chapitre, nous allons apprendre à utiliser JavaScript
comme langage de programmation côté serveur, comme s’il
s’agissait de PHP ou de Python. Nous verrons aussi que
Node.js a changé la manière de gérer un projet web, grâce à
son système avancé d’installation de paquets.
https://www.toutjavascript.com/reference/ref-navigator@.php
Protocole = https:
Domain = www.toutjavascript.com
Chemin = /reference/ref-navigator.php
N’oubliez pas que ni l’objet window ni l’objet document, habituels
en programmation client JavaScript, n’existent en programmation
serveur.
Dans une fenêtre de terminal, tapez npm --version pour vérifier que
l’assistant est bien installé. La commande npm doctor vérifie les
fonctionnalités et affiche des recommandations éventuelles.
Pour forcer la mise à jour de npm avec la dernière version
recommandée, tapez :
npm install -g npm@latest
Notez qu’il est tout à fait possible d’utiliser npm sans Node.js, en
tant que simple assistant à la gestion des ressources de votre
projet.
◆ Le générateur d’application
Pour créer notre application searchjs, qui utilise le moteur Twig (voir
ici de ce chapitre), nous lançons la commande dans le répertoire
racine :
express --view=twig searchjs
ou sous Windows :
set DEBUG=searchjs:* npm start
◆ Programmation de l’application
◆ L’appel au moteur
◆ Le langage Twig
Le but n’est pas d’apprendre dans ce livre toutes les subtilités des
moteurs de templates. Ce chapitre est l’occasion de rappeler que
le JavaScript n’est qu’une petite partie des techniques à connaître
dans le développement d’un projet.
◆ Le cache applicatif
Pour illustrer une application temps réel, la création d’un chat est
particulièrement adaptée : un message posté par un utilisateur doit
être envoyé immédiatement à tous les participants. Voici quelques
informations sur le fonctionnement :
L’utilisateur commence par choisir un pseudo.
Une fois le pseudo choisi, la fenêtre de messagerie apparaît
avec une zone de saisie de message.
Un message est un objet JSON composé d’une propriété
auteur et d’une propriété message.
Pour sécuriser l’application et empêcher tout affichage de code
HTML non autorisé, toutes les données transmises dans les
messages sont encodées.
Une zone de console de contrôle affiche les interactions avec le
serveur.
Voici une capture d’écran de l’application après quelques échanges :
L’exemple est en démonstration et téléchargeable sur
http://tjs.ovh/websock.
Objectif
Dans ce chapitre, nous allons découvrir les langages enrichis
dérivés du JavaScript et leur puissance.
_ 22.1 TYPESCRIPT
TypeScript (site officiel https://www.typescriptlang.org) a été
développé en 2012 par Microsoft afin de faciliter la production de
code JavaScript. TypeScript est une surcouche du JavaScript qui est
ensuite compilée en JavaScript natif, compatible avec l’ensemble
des navigateurs. Il ajoute le typage des variables, la création de
classes, d’interfaces et l’import de modules, tout en gardant la
souplesse du JavaScript.
Avec de bonnes connaissances en JavaScript, l’apprentissage de
TypeScript est relativement aisé. Comme TypeScript est utilisé par la
plupart des frameworks actuels (voir React et Angular aux pages et
), sa maîtrise est un vrai atout pour un développeur.
Par convention, un fichier de type TypeScript possède l’extension
.ts.
22.1.1 Installation
Une interface peut être étendue depuis une autre interface avec le
mot clé extends. Par exemple, pour créer l’interface parallélépipède
rectangle à partir de Rectangle, on écrit :
interface Brique extends Rectangle {
hauteur: number;
}
Rayon=10 (précision=2)
CERCLE : Périmètre=62.83 Surface=314.16
SPHERE : Surface=1256.64 Volume=4188.79
_ 22.2 BABEL
Babel (site officiel https://babeljs.io/) est un autre sur -ensemble de
JavaScript qui est compilé en JavaScript natif. Babel ajoute la
possibilité de choisir une version plus ancienne que ES2015 et
même une liste de navigateurs précis afin d’assurer une meilleure
compatibilité avec les navigateurs plus anciens.
22.2.1 Installation
Babel est utilisé uniquement pendant la phase de développement de
votre projet, afin de transformer votre code Babel en code JavaScript
exécutable. Ainsi, après avoir initialisé votre projet avec la syntaxe
npm init (voir ici), vous installez l’outil en mode développement :
npm install --save-dev @babel/core @babel/cli @babel/preset-env
22.2.3 Minification
Babel est capable de compacter au maximum un fichier .js pour en
faire une version minifiée, souvent nommée .min.js. Le module
minify doit être installé :
npm install babel-preset-minify --save-dev
Tous les retours à la ligne sont supprimés. Tous les espaces inutiles
sont éliminés. Les déclarations de PI et de notre fonction sont
regroupées. Chaque caractère du fichier minifié est indispensable et
il n’est pas possible de créer un fichier plus compact.
La commande de compilation
./node_modules/.bin/babel source.jsx
_ 22.3 JSX
Le format JSX, créé par Facebook (site officiel
https://facebook.github.io/jsx), est une extension du JavaScript
utilisant la syntaxe XML pour représenter de manière compacte et
lisible des éléments HTML à partir de leur balise.
Le format JSX est ensuite compilé en JavaScript natif pour être
correctement interprété par les navigateurs. Les compilateurs
TypeScript et Babel supportent le format JSX. Le langage JSX est
utilisé essentiellement par le framework React.js (voir chapitre
suivant).
Un attribut peut être une chaîne de caractères délimitée par " ou une
expression JavaScript délimitée par { et }.
La commande Babel (voir installation et utilisation) de compilation :
./node_modules/.bin/babel source.jsx
Bibliothèques et frameworks
Objectif
Dans ce chapitre, nous allons apprendre à choisir et à utiliser
les frameworks et bibliothèques externes JavaScript.
_ 23.1 FRAMEWORKS
23.1.1 Définition
Le choix d’un framework est crucial à toutes les étapes de la vie d’un
projet, depuis sa conception jusqu’à sa mise au rebut plus ou moins
prématurée, en passant naturellement par sa réalisation, sans
oublier sa maintenance au quotidien.
La plupart du temps, le framework est déjà imposé dans l’entreprise.
Les habitudes, les projets existants, les compétences disponibles en
interne ont abouti à un choix qu’il faut accepter.
Pour un projet personnel, ou entièrement nouveau, une étude des
frameworks disponibles évitera de mauvaises surprises. Le choix
définitif n’est finalement que le résultat d’un compromis entre
qualités, défauts, identification des réels besoins et prise de risque.
Voici quelques éléments à analyser afin de faire un choix éclairé :
Ancienneté du framework. Un projet professionnel ne peut
pas s’appuyer sur un framework tout neuf, aussi séduisant soit-
il. Un projet personnel ou modeste peut être l’occasion d’une
première utilisation pour en faire une analyse plus poussée.
Historique du framework. Les grandes étapes de la vie du
framework en disent beaucoup sur sa qualité. Quand l’équipe
en charge du développement est impliquée, de nouvelles
versions sont publiées régulièrement, les inévitables failles de
sécurité sont annoncées et corrigées.
Diffusion du framework. La communauté utilisatrice du
framework est primordiale à sa survie. Une communauté active
offre des ressources en ligne pour se dépanner et se former.
Courbe d’apprentissage. Cette courbe représente le temps et
l’effort nécessaires pour arriver à différents niveaux d’expertise.
Certains frameworks imposent une courbe d’apprentissage
assez plate, indiquant qu’il faut du temps, qui se compte en
semaines, pour arriver à produire de maigres résultats.
D’autres ont une courbe plus pentue, qui permet en quelques
jours d’avoir un niveau suffisant pour produire.
Espérance de vie du framework. Il s’agit sans doute du
paramètre le plus difficile à estimer. Un framework qui n’est
plus maintenu met en danger tous les projets qui l’utilisent. Un
bon historique et une large base d’utilisateurs sont deux
indicateurs favorables.
Niveau de complexité du projet. En dehors de toutes
considérations techniques externes, le type de projet est
central. Plus le projet est simple et rapide à mettre en
production, plus le framework doit être accessible. À moins
d’avoir des envies de formation, il ne faut pas passer plus de
temps à maîtriser le framework qu’à travailler sur son cœur de
métier.
Préférences personnelles. Les préférences personnelles du
développeur entrent aussi en compte. Certains apprécient la
compacité et la fluidité du jQuery. D’autres ne sont pas gênés
par le style verbeux des langages comme Objective-C.
Très prosaïquement, un chef de projet se posera aussi la question
de la difficulté et du coût de recrutement de développeurs
spécialisés. Les développeurs maîtrisant les frameworks à la mode
ont des prétentions salariales supérieures.
Google Trends est un outil d’analyse des tendances qui s’appuie sur
le nombre de requêtes dans son moteur de recherche. Il donne une
bonne estimation de la popularité de thèmes de recherche et de leur
évolution au cours du temps.
Le graphique montre que la thématique JavaScript est très stable.
Les recherches sur jQuery baissent et rejoignent maintenant les
frameworks Angular et React, que nous étudierons dans ce chapitre.
Le framework Vue.js semble très en retrait.
_ 23.2 JQUERY
23.2.1 Pourquoi choisir jQuery ?
23.2.2 Installation
23.2.4 L’objet $
Ici, le clic sur les éléments div affiche dans la console la valeur de
leur attribut data-jour. Notez que, dans le corps de la fonction, this
est l’élément concerné par l’événement.
Le chaînage est aussi possible :
$("div[data-jour]").on("click", function(evt) {
console.log("data-jour="+this.dataset.jour);
}).on("mouseover", function(evt) {
$(this).addClass("shadow");
}).on("mouseout", function(evt) {
$(this).removeClass("shadow");
});
_ 23. 3 PROTOTYPE.JS
Le framework Prototype.js (http://prototypejs.org) a connu une
assez bonne visibilité il y a quelques années. Il a été utilisé par
d’autres bibliothèques assez connues, comme ScriptAcoulUs
(https://script.aculo.us), destinée à réaliser des interfaces utilisateurs
et des animations « spectaculaires ». Mais, comme la dernière
version de Prototype.js date déjà de 2015, on peut parier sur un
abandon définitif de son développement.
_ 23.4 REACT
React (site officiel https://reactjs.org) est une bibliothèque
JavaScript, développée et rendue publique par Facebook à partir de
2013, facilitant la création d’interfaces utilisateurs. Elle permet de
créer des interfaces riches, sur une seule page, à partir de petits
modules indépendants appelés components (« composants » en
français) qui se chargent de modifier le contenu de la portion de
page nécessaire.
23.4.2 Installation
Avec Node.js, vous pouvez utiliser le module create-react-app, qui
facilite la création d’un projet global.
Créez un nouveau répertoire pour votre application. Lancez le
terminal et exécutez la commande d’installation du module
(éventuellement avec sudo) :
npm install -g create-react-app
L’outil React Developer Tools sur Chrome compte plus d’un million
d’utilisateurs. On peut donc imaginer que l’écosystème React,
soutenu par Facebook, est riche de millions de développeurs.
Le graphe Google Trends montre que la popularité est encore en
hausse.
Le module React-native permet en plus de créer des applications
(voir le chapitre dédié).
Cette puissance garantit un avenir favorable à ce framework.
_ 23.5 ANGULAR
Angular (site officiel https://angular.io), créé par Google en 2010, est
un autre framework dédié à la création d’applications Internet. Il a
été conçu pour développer facilement et simultanément sur mobile
et poste fixe, tout en assurant de bonnes performances à
l’exécution.
23.5.2 Installation
_ 23.6 VANILLA.JS
23.6.1 Le mouvement Vanilla JS
◆ vis.js
◆ Chart.js
◆ Dygraphs
◆ gmaps.js
gmaps.js (https://hpneo.github.io/gmaps) simplifie l’usage de
Google Maps pour la création de cartes basiques, d’itinéraires ou de
surcouches personnalisées.
◆ D3.js
Les éditeurs de texte enrichi (Rich Text Editors) sont des interfaces
dédiées à la saisie de texte au format enrichi. Leur but est de faciliter
la mise en forme d’un document directement sur la page web. Ils
remplacent ainsi les éléments de formulaire de type textarea par des
interfaces complètes proches des traitements de texte. En raison de
leur complexité, ils sont souvent proposés en version payante.
◆ TinyMCE
◆ CKEditor
23.7.3 Animations
◆ three.js
◆ Velocity.js
◆ Anime.js
◆ jQueryUI
◆ Bootstrap
Objectif
Dans ce chapitre, nous allons apprendre à utiliser les Web
Workers, qui sont un système d’exécution de scripts en
arrière-plan, sans impact sur la réactivité de l’interface
utilisateur.
Fn = Fn–1 + Fn–2
1, 1, 2, 3, 5, 8, 13, 21…
var fibonacci={
"type": "fibonacci",
"longueur": "30",
}
/* Envoyer un message avec la consigne de calcul de la suite */
myWorker.postMessage(fibonacci);
/* Réception du résultat */
myWorker.onmessage=function(evenement) {
/* Mise à jour du nombre d'éléments de la liste */
document.querySelector("span#longueur").innerText=evenement.data.longueur;
/* Construction de div#suite avec les lignes de résultats */
var suite=document.querySelector("div#suite");
var suiteTitre=document.querySelector("div#suiteTitre");
suite.innerText="";
suite.appendChild(suiteTitre);
for (var i=0; i<evenement.data.longueur; i++) {
/* Contenu de la boucle non reporté dans le livre */
}
}
}
100 + 25 = 125
125 + 9 = 134
134, 8, 10, 2
Pour ce tirage d’exemple, notre script affiche les résultats, avec les
plaques d’origine sur fond noir et les plaques des calculs
intermédiaires sur fond blanc :
◆ Le manifeste
◆ Quelques contraintes
chrome://extensions/
Objectif
Dans ce chapitre, nous allons aborder la création d’une
application native, au sens d’un exécutable, sur les systèmes
d’exploitation de bureau Windows et macOS et sur les
environnements mobiles Android et iOS.
Le but de ce chapitre n’est pas de créer une application de
bout en bout mais de montrer toutes les possibilités du
langage JavaScript.
_ UTILISATION DE FONTAWESOME
La bibliothèque FontAwesome (littéralement « police de caractères
extraordinaire ») est un outil gratuit et très puissant d’affichage de
centaines d’icônes de grande qualité sur vos pages.
L’installation se fait en copiant une seule ligne d’un appel d’une
feuille de style externe, hébergé sur un CDN (voir définition) :
<link rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.0.13/css/all.css
crossorigin="anonymous">
Si vous préférez héberger les fichiers sur votre serveur pour éviter
d’éventuelles pannes du CDN, c’est possible également.
Ensuite, l’affichage d’une icône se fait avec la syntaxe suivante :
<i class="fas fa-trophy"></i>
_ LA PSEUDO-CLASSE :HOVER
L’ajout de la pseudo-classe :hover sur un bloc de propriétés CSS
permet de détecter le survol de la souris et de modifier l’apparence
de l’élément. Ce bloc CSS change la couleur de police et de fond
lors du survol de l’élément div#survol :
div#survol:hover {
background-color:#000;
color:#fff;
}
Les transitions
-- 1
-= 1
!1
!= 1
!== 1
? 1, 2
/* */ 1
// 1
\1
+1
++ 1
+= 1, 2
<> 1
== 1
=== 1
=> 1
2FA 1
3G 1
$1
$1 1
$_FILES 1
$_GET 1
$_POST 1
$_REQUEST 1
::after 1
::before 1
:first-child 1
:hover 1
@keyframes 1
:last-child 1
@media 1
\n 1
accept 1
Access-Control-Allow-Origin 1
action 1
Adblock 1
addColorStop() 1
addEventListener() 1
addRange() 1
adresse IP 1, 2, 3
en JavaScript 1
AJAX 1, 2
ajax() 1
aléatoire 1
alert() 1, 2
amCharts 1
Angular 1
animate() 1
animation 1
animation CSS 1
AnimationEvent 1
antislash 1
API 1
appendChild() 1
append() 1
application native 1
apply() 1
arc() 1
arguments 1, 2
array_rand() 1
array_unique() 1
Array() 1
ASCII 1, 2
async 1, 2
asynchrone 1
attr() 1
Authentification à 2 Facteurs 1
availHeight 1
availWidth 1
Babel 1
back() 1
bande passante 1
barre
de favoris 1
de statut 1
beginPath() 1
Bézier (courbe de)
1
bezierCurveTo() 1
Bitcoin 1
blur()
window 1
boîte de dialogue 1
bookmarklet 1
Boole 1
boolean 1, 2
bot 1
boucle 1
sans fin 1
break 1, 2
Brendan Eich 1
browser 1
button 1
cache 1
cache applicatif 1
callback 1, 2
call() 1
cancelAnimationFrame() 1
Canvas 1
CanvasGradient 1
Captcha 1
caractères
de substitution 1
table ASCII 1
case 1
casse 1, 2
catch 1
CDN 1, 2
chaîne
casse 1
concaténation 1
de caractères 1
longueur 1
sur plusieurs lignes 1
vide 1
champ
caché 1
texte 1
charAt() 1
charCodeAt() 1
charset 1
checkbox 1
checked 1
childNodes 1
chrome 1
classe 1, 2, 3
classList 1
className 1
clavier 1
clearInterval() 1, 2
clearRect() 1
clearTimeout() 1
clearWatch() 1
client/serveur 1
clipboard 1
ClipboardEvent 1
closed 1
close() 1
closePath() 1
code mort 1
collapsed 1
collapse() 1, 2
coloration syntaxique 1
colorDepth 1
commentaires 1
commonAncestorContainer 1
complétion automatique 1
componentDidMount() 1
componentDidUpdate() 1
compression 1
concaténation 1, 2
concat() 1
concurrente
modification 1
condition 1
console 1, 2
.table() 1
css 1
const 1
constante 1
constructeur 1
constructor() 1, 2
content-security-policy 1
content: 1
contentWindow 1
conversion 1
cookie 1
cookieEnabled 1
cookies 1
tiers 1
coords 1
Cordova 1
cos() 1
courbe
d’apprentissage 1
de Bézier 1
createElement() 1
createLinearGradient() 1
create() 1
createObjectURL() 1
createPattern() 1
createRadialGradient() 1
createRange() 1
Cross-Site Scripting 1
crypto-monnaie 1, 2
CSS 1
animations 1
sélecteur 1
transformations 1
transitions 1
css() 1
CSSStyleDeclaration 1
currentTarget 1
D3.js 1
dataset 1
dataTransfer 1, 2
Date 1, 2
Date() 1
DateTimeFormat() 1
Déclaration 1
decodeURIComponent() 1
default 1
defer 1
défilement 1
defineProperty() 1
dégradé de couleurs 1
delete 1
deleteContents() 1
déprécié 1
dessin 1
DHTML 1
différence 1
Disable JavaScript 1
disabled 1
dispatchEvent() 1
doctor
npm 1
document 1
DOM 1
DOMContentLoaded 1
DOMRect 1
DOMStringMap 1
DOMTokenList 1
Douglas Crockford 1
download 1, 2
drag and drop 1, 2
DragEvent 1
draggable 1
drawImage() 1
drop 1
Dygraphs 1
échappement 1
ECMA 1
ECMAScript 1, 2
écran 1
éditeur de texte 1
égalité 1
Electron 1
elements 1
else 1
else if 1, 2
enableHighAccuracy 1
encodeURIComponent() 1, 2
enctype 1
endContainer 1, 2
endOffset 1
enumerable 1
environnement 1
Error 1
ErrorEvent 1
escape() 1
eval() 1
événement 1
Event
UIEvent 1
every() 1
exception 1
execCommand() 1
exec() 1
Express 1
expression 1
parenthésée 1
rationnelle 1
régulière 1
extends 1, 2
extension 1, 2
false 1
favoris 1
feuilles de styles 1
Fibonacci 1
fichier 1
file 1, 2, 3
file\:// 1
FileList 1
fill() 1
fillRect() 1
fillText() 1
filter() 1
firstChild 1
focus()
window 1
fonction 1
anonyme 1
auto-exécutée 1
callback 1, 2
description 1
fléchée 1, 2
native 1
personnalisée 1
font 1
FontAwesome 1, 2
for … in 1
forEach() 1, 2
format()
date 1
nombre 1
FormData 1, 2
forward() 1
frames 1
framework 1
Free 1
fromCharCode() 1
function 1
géolocalisation 1
geolocation 1
get 1
getAllResponseHeaders() 1
getAttribute() 1
getBoundingClientRect() 1
getComputedStyle() 1
getContext() 1
getCookie() 1
getDate() 1
getDay() 1
getElementById() 1
getElementsByClassName() 1
getElementsByName() 1
getElementsByTagName() 1
getFullYear() 1
getHours() 1
getItem() 1
getManifest() 1
getMessage() 1
getMilliseconds() 1
getMinutes() 1
getMonth() 1
getOwnPropertyNames() 1
getPrototypeOf() 1
getRangeAt() 1
getSeconds() 1
getSelection() 1
getTime() 1
getTimezoneOffset() 1
getUTC 1
Git 1
GitHub 1
glisser-déposer 1, 2
gmaps.js 1
go() 1
Google
Authenticator 1
Maps JS API 1
PageSpeed 1
reCAPTCHA 1
gradient de couleurs 1
hardwareConcurrency 1
hasAttribute() 1
hashage 1
height
HTMLElement 1
screen 1
Hello World 1
help
npm 1
héritage 1
hidden 1
history 1
hostname 1
href
location 1
HTMLCanvasElement 1
HTMLCollection 1
HTMLElement 1
attributs 1
HTMLFormElement 1
htm() 1
HTTP 1
https 1
HTTP/2 1
i18n 1
if 1
iframe 1
IIFE 1
Image 1
impression 1
incrémentation 1
Indentation 1
indexOf()
tableau 1
indexOf() 1
Infinity 1
info-bulle 1, 2
init
npm 1
innerHTML 1
innerText 1
input 1
insertBefore() 1
insertNode() 1
inspecteur 1
install
npm 1, 2
instance 1
internationalisation 1
Intl 1, 2
iPhone 1, 2
iso-8859-1 1
itération 1
Java 1, 2
JavaScript 1
jBox 1
jQuery 1
JScript 1
JSON 1
tableau 1
JSX
pour React 1
KeyboardEvent 1
keyframes 1
key() 1
keys() 1
label 1
landscape 1
lastChild 1
lastIndexOf()
tableau 1
lastIndexOf() 1
length
tableau 1
lengthComputable 1
let 1
linéarisation 1
lineTo() 1
lineWidth 1
liste déroulante 1
livraison 1
local 1
localStorage 1
location 1
log() 1, 2
logo officiel 1
ls
npm 1
majuscule 1
manifest.json 1
map() 1
Maps 1
Markdown 1
match() 1
Math 1, 2
mesureText() 1
method 1, 2
méthode 1
middleware 1
MIME 1
minage 1
minification 1, 2
minuscule 1
minuteur 1
modale 1
mot de passe 1
robustesse 1
mot réservé 1
motif 1
MouseEvent 1
moveBy() 1
moveTo() 1, 2
NaN 1, 2
Native Advertising 1
navigateur 1
navigator 1
Netscape 1
Network 1
new 1
nextSibling 1
Node.js 1
NodeList 1
nombre
aléatoire 1
formatage 1
infini 1
scientifique 1
noscript 1
notation pointée 1, 2
notification 1, 2
npm 1
null 1
number 1, 2
NumberFormat 1
obfuscation 1
onblur 1
onchange 1, 2
onclick 1, 2, 3
oncopy 1
oncut 1
onDOMContentLoaded 1
onerror 1
onfocus 1
onLine 1
onload 1, 2
AJAX 1
onmessage 1
on() 1
onmouse 1
onmousemove 1
onpaste 1
onprogress 1
onreadystatechange 1, 2
onresize 1
onselect 1
onsubmit 1
ontimeout 1
ontransition 1
OOP 1
open()
AJAX 1
opener 1
open() 1
option 1
options 1
orientation 1
origin 1
outerHTML 1
PageSpeed 1, 2
parentElement 1
parseFloat() 1
parseInt() 1, 2
parse() 1
password 1
performance
mesure 1
permission 1
phishing 1
placeholder 1
platform 1
point-virgule 1
polyfill 1
POO 1
pop-up 1
pop() 1
portée 1, 2
portrait 1
Position 1
postMessage() 1
posX 1
posY 1
pratiques
bonnes 1
préchargement 1
preload 1
presse-papiers 1
preventDefault() 1, 2, 3
previousSibling 1
print() 1
private 1
production 1
programmation
événementielle 1
séquentielle 1
prompt() 1
propriété 1
protocol 1
Prototype.js 1
pseudo-classe 1
pseudo-élément 1
public 1
push() 1
querySelectorAll() 1
querySelector() 1
random() 1
Range 1
rangeCount 1
ransomware 1
React 1
React Developer Tools 1
React.js 1
ReactJS 1
ready 1
readyState 1, 2
reCAPTCHA 1
recette 1
rect() 1
récursive
fonction 1
reduce() 1
reduceRight() 1
référencement 1, 2, 3, 4
RegExp() 1
reload() 1
removeAllRanges() 1
removeChild() 1
removeEventListener() 1
removeItem() 1
render()
node.js 1
replace()
location 1
replace() 1
requestAnimationFrame() 1
requestPermission() 1
required 1
require() 1
resizeBy() 1
resizeTo() 1
response 1
responsive 1
responsive design
canvas 1
restore() 1
retargeting 1, 2
retour à la ligne 1
return 1
reverse() 1
RGPD 1, 2
rotate() 1
runtime 1
same-origin policy 1
save() 1
screen 1
screenLeft 1
screenTop 1
screenX 1
screenY 1
scrollBy() 1
scrollTo() 1
search 1, 2
search() 1
sécurité 1
select 1
selected 1
selectedIndex 1
Selection 1
select() 1
selectNodeContents() 1
sendMessage(). 1
send() 1
séparateur 1
'1
Serveur DNS 1
sessionStorage 1
setAttribute() 1
setCookie() 1, 2
setEnd() 1
setInterval() 1, 2
setItem() 1
setLineDash() 1
setRequestHeader() 1
setStart() 1
setTime() 1
setTimeout() 1
setTransform() 1
shift() 1
shuffle() 1
sin() 1
site-under 1
slice() 1
smartphone 1
some() 1
sort() 1
souris 1
spellcheck 1
splice() 1
split() 1
src 1
startContainer 1
startOffset 1
static
node.js 1
status 1, 2
stopPropagation() 1
Storage 1
strict 1
string 1
stringify() 1
stroke() 1
strokeStyle 1
strokeText() 1
substring() 1
substr() 1
super() 1
supportedLocalesOf() 1
surroundContents() 1
SVN 1
switch 1
synchrone 1
tableau 1
associatif 1
conversion 1
multidimensionnel 1
table() 1
target 1
taux de rebond 1
taux de transformation 1
télécharger 1
template 1
terminate() 1
test unitaire 1
test() 1
textarea 1, 2
textBaseline 1
this 1, 2, 3
three.js 1
throw 1
timeEnd() 1
time() 1
timeout 1
timestamp 1
toDataURL() 1
toFixed() 1
toLowerCase() 1
toString() 1
toUpperCase() 1
tracking 1
traduction 1
transform-origin: 1
transform: 1
transition 1
transition- 1
Trends
Google 1
trigonométrique 1
trim() 1
true 1
try 1
tsc 1
Twig 1
typeof 1, 2
TypeScript 1
undefined 1
underscore 1
unescape() 1
upload 1, 2
use strict 1
use
npm 1
userAgent 1
UTF-8 1
V8 1
value 1
Vanilla JS 1
var 1
variable 1
globale 1
locale 1
portée 1
vie privée 1
view
npm 1
vis.js 1
void 1
watchPosition() 1
Web Developer 1, 2
Web Worker 1
WebSocket 1, 2
WheelEvent 1
which 1
width
HTMLElement 1
screen 1
window 1
Worker 1
X-Frame-Options 1
XML 1
XMLHttpRequest 1
XSS 1
1. Estimations d’Internet World Stats.
1. Source : https://www.publicisregicom.fr/investissements-publicitaires-2017-internet-
tete/
1. Source : http://gs.statcounter.com/#browser-ww-daily-20120509-20120517-bar
This le was downloaded from Z-Library project
Z-Access
https://wikipedia.org/wiki/Z-Library
ffi
fi