Cliquez sur l’image pour accéder au convertisseur puis inspecter la page pour analyser les codes
Structure des fichiers
index.html: la page web (structure + formulaire)styles.css: l’apparence (mise en page, bouton, champs)script.js: le calcul + mise à jour de l’interfaceimg/: les images (nuage par défaut, nuages bas/moyen/supérieur, favicon)
1) Le fichier HTML (index.html)
Le rôle de index.html est de :
- charger le CSS et le JavaScript,
- afficher un titre et un lien,
- proposer un formulaire avec 2 champs,
- afficher l’image et le résultat.
En-tête <head> : métadonnées + ressources
<link rel="stylesheet" href="styles.css" /> <script src="./script.js" defer></script>
- Le CSS est chargé via
styles.css - Le JS est chargé via
script.js - L’attribut
deferest important : il garantit que le script s’exécute après que le HTML soit présent (doncgetElementById(...)trouve bien les éléments).
On a aussi :
meta charset="UTF-8"pour les accentsmeta viewportpour un affichage correct sur mobile- un favicon :
ico-nuage.png
Le formulaire
<form id="meteoForm" autocomplete="off"> ... <input id="temperature" ... required> ... <input id="humidite" ... required> <button class="button" type="submit">Calculer</button> </form>
Points clés :
id="meteoForm": on s’en sert en JavaScript pour “écouter” l’envoi du formulaire.required: empêche l’envoi si le champ est vide.inputmode="decimal": sur mobile, ça affiche un clavier adapté aux nombres.placeholder="ex : 12,5": aide l’utilisateur (et on supporte la virgule côté JS).
Zone d’affichage : image + résultat
<img id="nuage" src="./img/nuage.png" alt="Illustration de nuage" style="width:700px"> <h4 id="test"></h4>
- L’image a
id="nuage": le JS change sonsrcselon le résultat. - Le texte de sortie est dans
<h4 id="test">: le JS y écrit le message final.
2) Le CSS (styles.css) : rendre la page propre et lisible
Le CSS sert à :
- centrer la page,
- donner une mise en forme simple,
- rendre le formulaire agréable,
- styliser le bouton (effets hover / active).
Mise en page générale
body {
background-color: #ccc;
text-align: center;
font-family: Arial, sans-serif;
}
- fond gris clair
- tout est centré par défaut
- police lisible
Champs du formulaire
.field {
margin: 10px auto;
max-width: 420px;
text-align: left;
}
- le formulaire reste centré, mais le texte des labels et champs est aligné à gauche (plus lisible)
- largeur max : évite d’avoir des champs trop larges sur écran PC
Bouton
.button {
display: block;
margin: 14px auto 0;
padding: 15px 25px;
font-size: 24px;
...
}
- bouton large, centré, “cliquable”
- effets :
:hoverchange la couleur au survol:activesimule l’enfoncement avectransform: translateY(4px)
3) Le JavaScript (script.js) : calcul + interface
Le JavaScript fait 3 grandes choses :
- Lire les valeurs du formulaire
- Calculer point de rosée et plafond nuageux
- Mettre à jour le texte + l’image
On commence par :
"use strict"; let image = "./img/nuage.png";
"use strict"active un mode plus strict (évite des erreurs silencieuses).imagecontient le chemin vers l’image actuellement affichée.
3.1 Convertir une saisie utilisateur en nombre (virgule acceptée)
function toNumber(input) {
const normalized = String(input ?? "").trim().replace(",", ".");
const n = Number.parseFloat(normalized);
return Number.isFinite(n) ? n : NaN;
}
Pourquoi cette fonction ?
- En France, beaucoup écrivent
12,5au lieu de12.5 replace(",", ".")rend la valeur compréhensible parparseFloat- Si la valeur n’est pas un nombre, on retourne
NaN
3.2 La fonction principale affiche() (calcul + affichage)
1) Lecture des champs
const temperature = toNumber(document.getElementById("temperature")?.value);
const humiditeR = toNumber(document.getElementById("humidite")?.value);
- On récupère les valeurs tapées dans le formulaire
- On convertit proprement via
toNumber(...)
2) Validation
if (!Number.isFinite(temperature) || !Number.isFinite(humiditeR)) {
document.getElementById("test").innerHTML =
"<b>Valeur invalide : saisissez des nombres (ex : 12,5).</b>";
return;
}
Si l’utilisateur tape du texte (ou un format bizarre), on affiche un message d’erreur et on stoppe.
3) Protéger le calcul : éviter log(0)
const humiditeClamped = Math.min(100, Math.max(0.1, humiditeR));
- Humidité relative théorique entre 0 et 100%
- On “borne” la valeur :
- minimum 0.1 (au lieu de 0) pour éviter
Math.log(0)qui serait impossible - maximum 100
- minimum 0.1 (au lieu de 0) pour éviter
4) Calcul du point de rosée (formule de Magnus)
const a = 17.27; const b = 237.7; const alpha = (a * temperature) / (b + temperature) + Math.log(humiditeClamped * 0.01); const pointRosee = (b * alpha) / (a - alpha);
Idée pédagogique :
- le point de rosée dépend de la température et de l’humidité
alphaest une variable intermédiaire (pratique pour éviter de répéter la formule)pointRoseeest la température à laquelle l’air devient saturé en vapeur d’eau
5) Estimation de la base des nuages
const plafondNuage = 125 * (temperature - pointRosee);
temperature - pointRosee: l’écart entre température et point de rosée (appelé souvent “spread”)- Multiplication par 125 : règle de calcul rapide donnant une estimation en mètres
Conversion en pieds :
const plafondNuageFt = plafondNuage / 0.3048;
6) Afficher le résultat
let meteo =
"Le point de rosée est égal à " +
pointRosee.toFixed(0) +
"°C et la base des nuages est à " +
plafondNuage.toFixed(0) +
" m.";
meteo += "<br><b>Soit " + plafondNuageFt.toFixed(0) + " ft.</b>";
document.getElementById("test").innerHTML = "<b>" + meteo + "</b>";
toFixed(0)arrondit à l’unité (plus clair pour un affichage “grand public”).- On utilise
<br>pour mettre la conversion en pieds sur une nouvelle ligne.
3.3 Changer l’image selon la hauteur du plafond
if (plafondNuage < 2000) {
image = "./img/bas.png";
} else if (plafondNuage < 4000) {
image = "./img/moyen.png";
} else {
image = "./img/superieur.png";
}
const img = document.getElementById("nuage");
if (img) img.src = image;
- < 2000 m → nuages bas
- 2000–4000 m → nuages moyens
- 4000 m → nuages élevés
Puis on met à jour l’image affichée en modifiant src.
4) L’événement DOMContentLoaded : rendre le formulaire “actif”
document.addEventListener("DOMContentLoaded", () => {
const form = document.getElementById("meteoForm");
if (form) {
form.addEventListener("submit", (e) => {
e.preventDefault();
affiche();
});
}
});
