Outils pour utilisateurs

Outils du site


informatique:js

JavaScript

Quelques points clés de mes apprentissages, notamment sur https://grafikart.fr/formations/formation-javascript

Les variables & Co

Un peu comme en Python, tout est objet en JS !
Si on déclare une simple variable : let a = 3
puis que l'on fait typeof(a), ça nous retourne number
et si on tape Number, on voit : function Number() qui contient un prototype Number … qui contient un <prototype> Object …CQFD

on n'utilise plus pour déclarer une variable le mot-clé var
on privilégie const et let
Pour les types de base (int, float, string), const définit une constante… si on essaie de modifier… invalid assignment to const…
En revanche pour les objets tableau, structure (JSON)… on peut modifier !
On peut donc privilégier const par défaut.

Définir une chaîne à partir de plusieurs variables :

ma_chaine = 'le résultat est : ' + ma_var1 + ' ' + ma_var2
// devient avec les back-ticks :
ma_chaine = `le résultat est : ${ma_var1} ${ma_var2}`

Les fonctions fléchées (arrow function)

https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Notamment lors des callbacks et retour de promesses, on écrira souvent : à la place de

input_sig.addEventListener('input', function (event) {
    //code de la fct
    })

cf. plus bas dans l'exemple sur l'écouteur d’événement

Côté navigateur

Les navigateurs intègrent un interpréteur, dans le principe, il n'y a donc rien à installer pour tester du code JS (notamment via la console du débugueur),
ceci dit, une sécurité (https://developer.mozilla.org/fr/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp) empêche d'appeler un fichier js dans un fichier html, même s'il est dans le même répertoire, donc le code :

<html>
  <head>
    <script src="./app.js"></script>

ne fonctionne pas !
On écrira donc :

<html>
  <head>
    <!-- se rendre dans le répertoire et lancer python3 -m http.server ou python3 -m http.server 8001 si on ne veut pas utiliser le port par défaut 8000 
    cf. https://developer.mozilla.org/fr/docs/Learn/Common_questions/Tools_and_setup/set_up_a_local_testing_server -->
    <script src="http://localhost:8000/app.js" type="module"></script></head>

et comme expliqué dans le commentaire dans le code ci-dessus, pour disposer d'un serveur http minimaliste, on lancera

python3 -m http.server

(port 8000 par défaut) ou

python3 -m http.server 8001

pour le lancer sur le port 8001

dans la déclaration script ci-dessus pour inclure le fichier app.js dans mon code html, est utilisé type=“module”. Cela inclue defer qui permet de charger le code mais de différer son exécution à la fin du chargement de la page html et d'éviter ainsi de mettre la ligne en fin du fichier html ! Cela permet aussi d'utiliser les import JS

DOM

Un objet window (par défaut, la variable this pointe aussi dessus) permet d'accéder à l'objet global de la fenêtre qui contient en premier lieu le sous-objet document

Convention : pour les méthodes de window, on les appellera sans préfixer avec window., exemple : au lieu de window.addEvenListener(), on écrira simplement addEventListener()
en revanche pour les variables, on garder window. devant… sauf pour document

querySelector et querySelectorAll

C'est la méthode de document qui permet de sélectionner les différents éléments que l'on souhaite manipuler. Comme illustrer dans la doc MDN, on peut écrire :

  <div class="sig-input">
    <label for="location">Site</label>
    <input type="text" class="autocomplete" name="location" placeholder="taper au moins 3 lettres du nom du lieu">
  </div>

et accéder à l'entrée (input) par le code JS :

const input_sig = document.querySelector("div.sig-input input[name='location']")

un peu verbeux mais ça a le mérite d'être clair, notamment pour un futur relecteur !
autre exemple similaire : l’input qui a pour name='sample-id' dans le formulaire qui a pour id='provenance-form' :

const sample_id = document.querySelector("#provenance-form input[name='sample-id']")

Avec querySelectorAll, on peut sélectionner un ensemble d'éléments, comme les boutons des sous-formulaires d'un formulaire complexe.

le sélecteur est une chaîne de caractère :
  • sans préfixe pour correspondre aux name,
  • précédé de # pour les id,
  • précédé de . pour les classes
si on fait dans la console un
const madiv = document.querySelector('.ma-classe')

ça retourne undefined, il faut bien taper

madiv

pour voir le contenu de la variable !

Écouteur d'événement (addEventListener)

C'est un des intérêts d'ajouter du JS à une page… écouter un ou des événements pour inter-agir avec la page, tantôt faire de l'autocomplétion, tantôt ajouter un autre formulaire, ou encore soumettre et traiter un sous-formulaire… Ce chapitre s'appuie sur le tuto (youtube) grafikart sur les écouteurs d'événements

Pour cela, il y a la méthode addEventListener
Tout d'abord, on sélectionne notre élément, cf. ci-dessus le § sur querySelector, puis on lui ajoute l'écoute :

input_sig.addEventListener('input', () => {
  // callback qui va afficher dans la console le texte tapé dans le champ
  console.log(input_sig.value)
})

Les principaux événements sont :  *

  • click, essentiellement pour les boutons (sous-formulaires)
  • input (sur text, textarea… survient à chaque nouveau caractère tapé, à la différence de change),
  • change changement de la valeur de l'input ou du basculement d'une checkbox (tuto à 22’30“), ou encore d'un select (currentTarget.selectedOptions → toutes les infos)
  • select multiple 24’30’’ :
    Array.from(event.currentTarget.selectedOptions).map(option => option.value)
  • keydown touche appuyée, intéressant pour définir des raccourcis…
    document.addEventListener('keydown', e) => { if (e.ctrlKey === true && e.key ==='k') {e.preventDefault(); console.log('raccourci')}})
  • keypress, keyup, suite de keydown
  • focus, dès qu'un élément a le focus (survol de la souris ou via tab
  • blur à la perte du focus → traiter la valeur … cf. tuto (youtube) grafikart sur les écouteurs d'événements à 14’20’’

preventDefault

Cette méthode est importante pour bloquer le comportement par défaut d'un évènement (event), comme la redirection pour un lien, la soumission du formulaire lors du clic (click) du bouton… cf. tuto ci-dessous à 6’15”

stopPropagation

Autre méthode très utile, la méthode stopPropagation qui évite de propager l'évènement aux éléments parents… (div généralement). (tuto 8’30“)

formData

cet objet permet la récupération (get) des saisies du formulaire (tuto à 16’45”), objet qui peut être modifié (set, append) avant de par exemple le transmettre au serveur.
Si on a besoin de modifier le formulaire en cours, on fera simplement un querySelector puis element.value = <valeur ou nlle valeur>

Pour récupérer le contenu du formulaire qui contient un champ input qui a pour name location :

document.querySelector('form').addEventListener('submit', e => {
	e.preventDefault()
	const form = e.currentTarget
	const datas = new FormData(form)
	console.log(datas)
	console.log(datas.get('location'))
})

Fetch

tuto grafikart : https://grafikart.fr/tutoriels/javascript-promise-2068#autoplay
Une fois l'évènement capturé, on a souvent besoin soit de récupérer des données du serveur pour alimenter la liste d'une autocomplétion, soit de soumettre un sous-formulaire (lieu, person…).
On utilise dans tous ces cas la fonction fetch
Cette fonction exécutant une requête HTTP, la réponse n'est pas immédiate même si elle peut être très rapide. Nous allons donc généralement créer une fonction qui sera asynchrone (async) pour ne pas être bloquante, fonction qui appellera fetch en précisant (préfixant) l'appel avec await pour attendre le retour.
Exemple :

async function testFetchWebService(server, params) {
	const fullUrl = server + params
	const r = await fetch(fullUrl, {
		method: 'GET',
		headers:{
			"Accept": "application/json",
		}
	});
	if (r.ok === true) {
		return r.json();
	}
	throw new Error('impossible de contacter le serveur');
}
// et on l'appelle :
const placeHolderServerUrl = 'https://jsonplaceholder.typicode.com/'
const placeHolderServerParams = 'users?username=Bret'
console.log('Test avec placeHolder :')
testFetchWebService(placeHolderServerUrl, placeHolderServerParams).then(users => console.log(users));

Sucre syntaxique

Ça donne un code plus concis, mais parfois incompréhensible. Je passe sur

 i = i + 1 qui devient i++ ou ++i

L'opérateur ternaire : à peu près commun aux différents langages donc acceptable :

// au lieu de :
if (condition)
  'valeur si vrai'
else
  'valeur si faux'
// en une ligne :
condition ? 'valeur si vrai' : 'valeur si faux'

le ?? :

// au lieu de 
if (chaine != null)
  chaine
else
  ''
// on a :
chaine ?? ''
informatique/js.txt · Dernière modification : 2023/12/07 14:06 de bertrand