diff --git a/Doc/fonctionnement-onepage.md b/Doc/fonctionnement-onepage.md new file mode 100644 index 0000000..9735330 --- /dev/null +++ b/Doc/fonctionnement-onepage.md @@ -0,0 +1,203 @@ +# Fonctionnement du one page + +Ce projet fonctionne comme un site statique avec un seul point d'entrée HTML. Le JavaScript sert uniquement à lire l'URL, choisir la bonne route, charger le bon fichier HTML dans `p/`, puis injecter son contenu dans la zone centrale de la page. + +Le principe général est simple: + +1. `index.html` garde le header, le footer et le conteneur principal. +2. Chaque section vit dans un dossier sous `p/`. +3. Le script lit la route demandée dans l'URL. +4. Le script charge `p//index.html` avec `fetch`. +5. Le contenu de la page est injecté dans le `main`. + +## Fichiers impliqués + +- [index.html](../index.html) contient le chrome global du site. +- [p/assets/main-nav/app.js](../p/assets/main-nav/app.js) contient le routeur JavaScript. +- [p/dl/index.html](../p/dl/index.html) contient le contenu de la page DL. + +## Rôle de `index.html` + +`index.html` ne contient pas le contenu de toutes les pages. Il contient seulement: + +- le header commun, +- la navigation, +- le `main` vide, +- le footer commun, +- l'appel au script JavaScript. + +Exemple de lien de navigation: + +```html +DL +``` + +Ce lien fait deux choses: + +- il indique au navigateur une URL propre, +- il donne au script un identifiant de route via `data-route`. + +## Comment le script lit l'URL + +Le script commence par récupérer la route dans l'adresse courante. + +Il sait reconnaître plusieurs formes: + +- `/?p/dl/` +- `/?p=dl` +- `/p/dl/` + +La fonction `routeFromLocation()` nettoie ensuite la valeur pour obtenir une route simple comme `home` ou `dl`. + +## Normalisation de route + +La fonction `normalizeRoute(value)` sert à standardiser les valeurs. + +Elle transforme par exemple: + +- `HOME` en `home` +- `accueil` en `home` +- `/dl/` en `dl` + +Cette normalisation évite d'avoir plusieurs variantes pour une même page. + +## Chargement du contenu + +La fonction `loadRoute(route)` fait le vrai travail. + +### Cas de l'accueil + +Quand la route vaut `home`, le script n'a pas besoin de charger un fichier externe. Il injecte directement le bloc HTML de l'accueil dans le `main`. + +### Cas d'une page sous `p/` + +Quand la route vaut autre chose que `home`, le script construit le chemin du fichier: + +```text +p//index.html +``` + +Exemple: + +```text +p/dl/index.html +``` + +Puis il appelle `fetch` pour lire ce fichier. + +Le script ne prend pas tout le HTML de la page externe. Il récupère uniquement l'élément portant `data-page-content`: + +```html +
+ ... +
+``` + +Ensuite, il insère seulement son contenu intérieur dans le `main` du site principal. + +## Injection dans le `main` + +L'injection se fait avec: + +```javascript +main.innerHTML = injected.innerHTML.trim(); +``` + +Donc: + +- le header ne bouge pas, +- le footer ne bouge pas, +- seul le contenu central change. + +## Mise à jour de l'URL + +Après le chargement, le script met à jour l'URL avec l'API History. + +Exemple: + +- `home` devient `/` +- `dl` devient `/?p/dl/` + +Cela permet de partager une URL propre sans recharger complètement la page. + +## Navigation au clic + +Le script écoute les clics sur les liens qui possèdent `data-route`. + +Quand tu cliques sur un lien: + +1. il bloque la navigation normale avec `event.preventDefault()`; +2. il lit `data-route`; +3. il appelle `render(route)`; +4. il charge la page correspondante dans le `main`. + +Exemple: + +```html +DL +``` + +## Bouton retour du navigateur + +Le script écoute aussi l'événement `popstate`. + +Cela veut dire que: + +- si tu fais retour arrière, +- ou avance dans l'historique, +- le site recharge automatiquement la bonne route. + +## Structure attendue pour une nouvelle page + +Pour ajouter une page, il suffit de créer un nouveau dossier sous `p/`. + +Exemple pour une page contact: + +```text +p/contact/index.html +``` + +Le fichier doit contenir un bloc avec `data-page-content`: + +```html +
+
+

Contact

+
+
+``` + +Puis tu ajoutes un lien dans `index.html`: + +```html +Contact +``` + +Le JavaScript n'a pas besoin d'être modifié tant que la structure reste la même. + +## Ce que ce système n'utilise pas + +Ce projet n'utilise pas: + +- Node.js, +- un bundler, +- un framework front, +- des fichiers `.html` séparés dans la racine pour chaque page. + +Tout repose sur un site statique et un petit routeur en JavaScript. + +## Point important + +Le chargement via `fetch` fonctionne mieux quand le site est servi par un serveur statique, comme Five Server. + +Si tu ouvres le fichier en `file://`, le navigateur peut bloquer l'accès aux fichiers internes pour des raisons de sécurité. + +## Résumé rapide + +Le script fait trois choses: + +- il lit la route dans l'URL, +- il charge le bon fichier dans `p/`, +- il injecte le contenu dans le `main`. + +Le reste du site est fixe et partagé par toutes les pages. \ No newline at end of file diff --git a/README.md b/README.md index 12f7e26..f44f616 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Utilisation: Navigation: +- `/?p/index/` charge `p/index/index.html` dans le `main` - `/?p/dl/` charge `p/dl/index.html` dans le `main` - Chaque sous-dossier de `p/` peut devenir une route, par exemple `p/contact/index.html` pour `/?p/contact/` - Le header et le footer restent communs à toutes les vues diff --git a/index.html b/index.html index da5cbf5..533017b 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@
diff --git a/p/assets/main-nav/app.js b/p/assets/main-nav/app.js index 05ed466..fa91129 100644 --- a/p/assets/main-nav/app.js +++ b/p/assets/main-nav/app.js @@ -6,9 +6,9 @@ function normalizeRoute(value) { const raw = (value ?? "").toString().trim().toLowerCase(); if (!raw || raw === "/" || raw === "home" || raw === "index" || raw === "accueil") { - return "home"; + return "index"; } - return raw.replace(/^\/+|\/+$/g, "") || "home"; + return raw.replace(/^\/+|\/+$/g, "") || "index"; } function routeFromLocation() { @@ -36,7 +36,7 @@ return normalizeRoute(parts[0]); } - return "home"; + return "index"; } function setActiveRoute(route) { @@ -51,7 +51,7 @@ } function setCanonicalUrl(route, replace = false) { - const url = route === "home" ? "/" : `/?p/${route}/`; + const url = route === "index" ? "/?p/index/" : `/?p/${route}/`; if (replace) { history.replaceState({ route }, "", url); return; @@ -60,11 +60,11 @@ } function routeToSource(route) { - return route === "home" ? null : `p/${route}/index.html`; + return `p/${route}/index.html`; } function routeToTitle(route) { - if (route === "home") { + if (route === "index") { return "Fws Web"; } @@ -78,44 +78,7 @@ } async function loadRoute(route) { - if (route === "home") { - main.innerHTML = ` -
-

Navigation one-page

-

Le site change de contenu sans changer de page.

-

- Les liens du menu modifient l'URL, puis le script charge le HTML correspondant depuis - p/... et l'injecte dans le main. -

- -
- -
-
-

Header commun

-

Le bandeau du haut reste identique sur chaque vue.

-
-
-

Footer commun

-

Le pied de page reste fixe, quelle que soit la section chargée.

-
-
-

Injection réelle

-

Chaque route peut venir d'un vrai fichier index.html dans p/.

-
-
- `; - return; - } - const source = routeToSource(route); - if (!source) { - throw new Error(`Route inconnue: ${route}`); - } - const response = await fetch(source, { cache: "no-store" }); if (!response.ok) { throw new Error(`Impossible de charger ${source} (${response.status})`); @@ -128,7 +91,7 @@ } function render(route, { replaceHistory = false } = {}) { - const safeRoute = route || "home"; + const safeRoute = route || "index"; loadRoute(safeRoute) .then(() => { @@ -139,7 +102,7 @@ }) .catch((error) => { main.innerHTML = `

Erreur de chargement

${error.message}

`; - setActiveRoute("home"); + setActiveRoute("index"); }); } diff --git a/p/index/index.html b/p/index/index.html new file mode 100644 index 0000000..0fe4b72 --- /dev/null +++ b/p/index/index.html @@ -0,0 +1,39 @@ + + + + + + Accueil + + +
+
+

Navigation one-page

+

Le site change de contenu sans changer de page.

+

+ La page principale vit dans p/index/index.html et le script l'injecte dans le + main quand l'URL pointe vers /?p/index/. +

+ +
+ +
+
+

Header commun

+

Le bandeau du haut reste identique sur chaque vue.

+
+
+

Footer commun

+

Le pied de page reste fixe, quelle que soit la section chargée.

+
+
+

Injection réelle

+

Chaque route peut venir d'un vrai fichier index.html dans p/.

+
+
+
+ + \ No newline at end of file