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’interface
  • img/ : 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 :

  1. charger le CSS et le JavaScript,
  2. afficher un titre et un lien,
  3. proposer un formulaire avec 2 champs,
  4. 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 defer est important : il garantit que le script s’exécute après que le HTML soit présent (donc getElementById(...) trouve bien les éléments).

On a aussi :

  • meta charset="UTF-8" pour les accents
  • meta viewport pour 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 son src selon 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 :
    • :hover change la couleur au survol
    • :active simule l’enfoncement avec transform: translateY(4px)

3) Le JavaScript (script.js) : calcul + interface

Le JavaScript fait 3 grandes choses :

  1. Lire les valeurs du formulaire
  2. Calculer point de rosée et plafond nuageux
  3. 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).
  • image contient le chemin vers l’image actuellement affiché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,5 au lieu de 12.5
  • replace(",", ".") rend la valeur compréhensible par parseFloat
  • Si la valeur n’est pas un nombre, on retourne NaN

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(...)
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.

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
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é
  • alpha est une variable intermédiaire (pratique pour éviter de répéter la formule)
  • pointRosee est la température à laquelle l’air devient saturé en vapeur d’eau
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;
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.

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();
    });
  }
});

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *