Files
2026-09-28 09:09:04 +02:00

303 lines
15 KiB
JavaScript

/* =====================================================================
atelier-m3-m4.js
Interactions des modules 3 et 4. À charger APRÈS atelier-texte.js.
Chaque bloc ne s'exécute que si son conteneur existe dans la page,
donc le fichier peut être chargé par les deux modules indifféremment.
===================================================================== */
(function(){
"use strict";
/* Réutilise le quiz d'atelier-texte.js s'il est disponible.
Sinon, produit le même balisage, pour que la page reste utilisable. */
const poserQuiz = (typeof window.quiz === 'function') ? window.quiz : function(el, questions){
if(!el) return;
el.innerHTML = questions.map(function(q,i){
return '<div class="q" data-i="'+i+'"><p>'+(i+1)+'. '+q.q+'</p>'
+ q.r.map(function(r,j){
return '<label><input type="radio" name="'+el.id+'-'+i+'" value="'+j+'">'+r+'</label>';
}).join('')
+ '<div class="verdict"></div></div>';
}).join('');
el.addEventListener('change', function(e){
const bloc = e.target.closest('.q');
const i = +bloc.dataset.i, q = questions[i];
bloc.querySelectorAll('label').forEach(function(l,j){
l.className = (j === q.b) ? 'bon' : (l.querySelector('input').checked ? 'mauvais' : '');
});
bloc.querySelector('.verdict').textContent = (+e.target.value === q.b ? 'Exact. ' : 'Non. ') + q.e;
});
};
/* =====================================================================
MODULE 3
===================================================================== */
/* ---------- tri caractère ou paragraphe ---------- */
/* Le retour visuel ne dépend pas de la feuille de style : les couleurs et le
verdict sont écrits directement dans le DOM, pour que l'exercice fonctionne
même si atelier-m3-m4.css n'est pas chargé. */
(function(){
const triEl = document.getElementById('at-tri');
if(!triEl) return;
const CP = [
["Mettre un mot en gras","c"],
["Centrer un titre","p"],
["Changer la police","c"],
["Justifier le texte","p"],
["Mettre en italique","c"],
["Ajouter un retrait de première ligne","p"],
["Changer la couleur du texte","c"],
["Encadrer d'une bordure","p"],
["Régler l'interligne","p"],
["Mettre en exposant","c"],
["Espacer deux paragraphes","p"],
["Changer la taille en points","c"]
];
const NOM = {c:'Caractère', p:'Paragraphe'};
const VERT = '#1E7A4C', ROUGE = '#B03A2E';
const scoreEl = document.getElementById('at-tri-score');
const lignes = [];
CP.forEach(function(r, i){
const lib = document.createElement('div');
lib.className = 'at-tri__lib';
lib.textContent = r[0];
const bc = document.createElement('button');
bc.type = 'button'; bc.textContent = 'C'; bc.dataset.v = 'c';
const bp = document.createElement('button');
bp.type = 'button'; bp.textContent = 'P'; bp.dataset.v = 'p';
const verdict = document.createElement('div');
verdict.className = 'at-tri__verdict';
verdict.style.gridColumn = '1 / -1';
verdict.style.fontSize = '.88rem';
verdict.style.margin = '0 0 .35rem';
verdict.style.minHeight = '0';
triEl.appendChild(lib); triEl.appendChild(bc); triEl.appendChild(bp);
triEl.appendChild(verdict);
lignes.push({lib:lib, bc:bc, bp:bp, verdict:verdict, juste:null});
[bc, bp].forEach(function(b){
b.addEventListener('click', function(){
const choix = b.dataset.v;
const ok = (choix === r[1]);
const L = lignes[i];
L.juste = ok;
L.lib.style.color = ok ? VERT : ROUGE;
L.lib.style.fontWeight = ok ? '600' : '400';
L.bc.setAttribute('aria-pressed', String(choix === 'c'));
L.bp.setAttribute('aria-pressed', String(choix === 'p'));
L.verdict.style.color = ok ? VERT : ROUGE;
L.verdict.textContent = ok
? NOM[choix] + ', exact.'
: NOM[choix] + ', non. C\u2019est un réglage de ' + NOM[r[1]].toLowerCase() + '.';
majScore();
});
});
});
function majScore(){
if(!scoreEl) return;
const faits = lignes.filter(function(L){ return L.juste !== null; });
const bons = faits.filter(function(L){ return L.juste; }).length;
if(!faits.length){ scoreEl.textContent = ''; return; }
scoreEl.textContent = bons + ' sur ' + faits.length + ' classés correctement'
+ (faits.length === CP.length
? (bons === CP.length ? '. Tout juste.' : '. Reprends ceux en rouge.')
: '');
}
const reset = document.getElementById('at-tri-reset');
if(reset){
reset.addEventListener('click', function(){
lignes.forEach(function(L){
L.juste = null;
L.lib.style.color = ''; L.lib.style.fontWeight = '';
L.verdict.textContent = '';
L.bc.setAttribute('aria-pressed','false');
L.bp.setAttribute('aria-pressed','false');
});
majScore();
});
}
})();
/* ---------- atelier de mise en forme ---------- */
const apercu = document.getElementById('at-apercu');
if(apercu){
const paras = Array.prototype.slice.call(apercu.querySelectorAll('p'));
const val = function(id){ return document.getElementById(id).value; };
const coche = function(id){ return document.getElementById(id).checked; };
function maj(){
const taille = val('at-taille'), retrait = val('at-retrait'), espace = val('at-espace');
document.getElementById('at-taille-v').textContent = taille;
document.getElementById('at-retrait-v').textContent = (+retrait).toFixed(2).replace('.',',');
document.getElementById('at-espace-v').textContent = (+espace).toFixed(1).replace('.',',');
const align = document.querySelector('#at-align button[aria-pressed="true"]').dataset.v;
const bord = coche('at-bordure');
apercu.style.fontFamily = val('at-police');
apercu.style.fontSize = taille + 'pt';
apercu.style.fontWeight = coche('at-gras') ? '700' : '400';
apercu.style.fontStyle = coche('at-italique') ? 'italic' : 'normal';
paras.forEach(function(p){
p.style.textAlign = align;
p.style.textIndent = retrait + 'cm';
p.style.marginBottom = espace + 'cm';
p.style.lineHeight = val('at-interligne');
p.style.border = bord ? '1px solid #B8912A' : 'none';
p.style.background = bord ? '#FEFAEC' : 'transparent';
p.style.padding = bord ? '.4rem .6rem' : '0';
});
}
['at-police','at-taille','at-retrait','at-espace','at-interligne','at-bordure','at-gras','at-italique']
.forEach(function(id){ document.getElementById(id).addEventListener('input', maj); });
const alignEl = document.getElementById('at-align');
if(alignEl) alignEl.addEventListener('click', function(e){
const b = e.target.closest('button'); if(!b) return;
document.querySelectorAll('#at-align button').forEach(function(x){ x.setAttribute('aria-pressed','false'); });
b.setAttribute('aria-pressed','true');
maj();
});
maj();
}
/* ---------- quiz module 3 ---------- */
poserQuiz(document.getElementById('quiz3'), [
{q:"Tu poses le curseur dans un mot, sans rien sélectionner, et tu cliques sur Centrer. Que se passe-t-il&nbsp;?",
r:["Seul le mot se centre","Tout le paragraphe se centre","Rien ne se passe"],
b:1, e:"L'alignement est une mise en forme de paragraphe : elle s'applique au paragraphe entier, sans sélection."},
{q:"Comment sépares-tu deux paragraphes&nbsp;?",
r:["Par une ligne vide, avec la touche Entrée","Par un espacement après le paragraphe","Par plusieurs touches Entrée"],
b:1, e:"Le réglage d'espacement se modifie d'un seul geste sur tout le document. Une ligne vide, non."},
{q:"Quelle taille convient à un texte courant&nbsp;?",
r:["8 points","10 à 12 points","16 points"],
b:1, e:"En dessous on ne lit plus. Au-dessus, le document semble destiné aux malvoyants, ce qui est parfois exactement le but."},
{q:"À quoi sert le pinceau de la barre d'outils&nbsp;?",
r:["À colorier le texte","À reproduire une mise en forme ailleurs","À effacer le texte"],
b:1, e:"Cloner le formatage. Un clic pour une seule application, un double-clic pour en enchaîner plusieurs."},
{q:"Tu colles un texte venu d'un site et il arrive avec sa mise en forme. Le plus simple&nbsp;?",
r:["Le coller avec Ctrl+Maj+V en texte non formaté","Le retaper","Changer la police à la main"],
b:0, e:"Et si c'est déjà collé, Ctrl+M efface le formatage direct."},
{q:"Où trouve-t-on la couleur de fond d'un paragraphe&nbsp;?",
r:["Format, Caractère","Format, Paragraphe, onglet Zone","Format, Style de page"],
b:1, e:"L'onglet Zone, appelé Arrière-plan dans les versions plus anciennes. Un fond clair, sinon le texte devient illisible."}
]);
/* =====================================================================
MODULE 4
===================================================================== */
/* ---------- feuille A4 et marges ---------- */
const page = document.getElementById('at-page');
if(page){
const zone = document.getElementById('at-page-zone');
const note = document.getElementById('at-page-note');
function majPage(){
const paysage = document.querySelector('#at-orient button[aria-pressed="true"]').dataset.v === 'paysage';
page.classList.toggle('at-page--paysage', paysage);
const L = paysage ? 29.7 : 21, H = paysage ? 21 : 29.7;
const m = {};
['haut','bas','gauche','droite'].forEach(function(k){
m[k] = +document.getElementById('at-m-'+k).value;
document.getElementById('at-m-'+k+'-v').textContent = String(m[k]).replace('.',',');
});
zone.style.top = (m.haut/H*100)+'%';
zone.style.bottom = (m.bas/H*100)+'%';
zone.style.left = (m.gauche/L*100)+'%';
zone.style.right = (m.droite/L*100)+'%';
zone.innerHTML = '';
if(document.getElementById('at-entete').checked){
zone.insertAdjacentHTML('beforeend','<div class="at-page__bande" style="top:0">en-tête</div>');
}
if(document.getElementById('at-pied').checked){
zone.insertAdjacentHTML('beforeend','<div class="at-page__bande" style="bottom:0">pied de page</div>');
}
let t = 'Zone de texte : '
+ (L - m.gauche - m.droite).toFixed(1).replace('.',',') + ' cm sur '
+ (H - m.haut - m.bas).toFixed(1).replace('.',',') + ' cm.';
if(m.gauche < 1.5 || m.droite < 1.5 || m.haut < 1.5 || m.bas < 1.5){
t += ' Attention, en dessous de 1,5 cm certaines imprimantes coupent le texte.';
}
note.textContent = t;
}
['at-m-haut','at-m-bas','at-m-gauche','at-m-droite','at-entete','at-pied']
.forEach(function(id){ document.getElementById(id).addEventListener('input', majPage); });
const orientEl = document.getElementById('at-orient');
if(orientEl) orientEl.addEventListener('click', function(e){
const b = e.target.closest('button'); if(!b) return;
document.querySelectorAll('#at-orient button').forEach(function(x){ x.setAttribute('aria-pressed','false'); });
b.setAttribute('aria-pressed','true');
majPage();
});
majPage();
}
/* ---------- lignes vides contre saut de page ---------- */
const fluxA = document.getElementById('at-flux-vides');
if(fluxA){
const fluxB = document.getElementById('at-flux-saut');
const CORPS = "La crèche Les Petits Pas accueille les enfants de deux mois et demi à trois ans. Elle dispose de trente-six places réparties en trois sections. Les inscriptions se prennent à partir du quatrième mois de grossesse. Une visite des locaux est organisée avant toute inscription.";
const SUITE = "L'accueil du matin se fait de sept heures à neuf heures. Chaque enfant est remis à une puéricultrice de sa section.";
const AJOUT = "Une réunion de parents est organisée chaque année en septembre.";
let ajouts = 0;
function rendreFlux(){
let tete = '';
for(let i = 0; i < ajouts; i++){ tete += '<p>'+AJOUT+'</p>'; }
const vides = new Array(7).join('<p>&nbsp;</p>');
fluxA.innerHTML = "<h5>Fiche d'information</h5>" + tete + '<p>'+CORPS+'</p>' + vides
+ "<h5>Le déroulement d'une journée</h5><p>"+SUITE+"</p>";
fluxB.innerHTML = "<h5>Fiche d'information</h5>" + tete + '<p>'+CORPS+'</p>'
+ "<h5 class=\"at-saut\">Le déroulement d'une journée</h5><p>"+SUITE+"</p>";
}
document.getElementById('at-flux-plus').addEventListener('click', function(){ if(ajouts < 4){ ajouts++; rendreFlux(); } });
document.getElementById('at-flux-reset').addEventListener('click', function(){ ajouts = 0; rendreFlux(); });
rendreFlux();
}
/* ---------- numéro tapé contre champ inséré ---------- */
const piedMain = document.getElementById('at-pied-main');
if(piedMain){
const piedChamp = document.getElementById('at-pied-champ');
const noteChamp = document.getElementById('at-champ-note');
let nb = 4;
function rendreChamp(){
piedMain.innerHTML = 'Document mis à jour en septembre 2026 &nbsp;&nbsp;&nbsp; Page 1 sur 4';
piedChamp.innerHTML = 'Document mis à jour en septembre 2026 &nbsp;&nbsp;&nbsp; Page '
+ '<span class="at-champ">1</span> sur <span class="at-champ">'+nb+'</span>';
noteChamp.textContent = (nb === 4)
? "Le document compte 4 pages. Les deux pieds de page disent la même chose. Ajoute une page."
: "Le document compte maintenant " + nb + " pages. À gauche, le total est faux et il faudra le corriger sur chaque page. À droite, il s'est recalculé tout seul.";
}
document.getElementById('at-page-plus').addEventListener('click', function(){ if(nb < 12){ nb++; rendreChamp(); } });
document.getElementById('at-page-reset').addEventListener('click', function(){ nb = 4; rendreChamp(); });
rendreChamp();
}
/* ---------- quiz module 4 ---------- */
poserQuiz(document.getElementById('quiz4'), [
{q:"Comment fais-tu commencer un titre en haut de la page suivante&nbsp;?",
r:["En appuyant plusieurs fois sur Entrée","Avec Ctrl+Entrée","En agrandissant les marges"],
b:1, e:"Le saut de page manuel tient, même si tu ajoutes du texte avant. Les lignes vides, non."},
{q:"Où règle-t-on les marges d'un document&nbsp;?",
r:["Format, Paragraphe","Format, Style de page","Insertion, En-tête"],
b:1, e:"La marge définit où commence la zone de texte. Le retrait, lui, éloigne un paragraphe du bord de cette zone."},
{q:"Tu tapes le numéro 1 dans le pied de page de la première page. Que voit-on page 3&nbsp;?",
r:["Le numéro 3","Le numéro 1","Rien"],
b:1, e:"Un texte tapé se répète tel quel sur toutes les pages. Il faut insérer un champ, pas un chiffre."},
{q:"À quoi sert l'aperçu avant impression&nbsp;?",
r:["À imprimer plus vite","À voir le document tel qu'il sortira de l'imprimante","À corriger l'orthographe"],
b:1, e:"On y vérifie les coupures de page, les en-têtes et l'équilibre général. Avant d'imprimer, pas après."},
{q:"Tu envoies un courrier terminé aux parents. Quel format&nbsp;?",
r:["Le PDF","Le fichier .odt","Une capture d'écran"],
b:0, e:"Le PDF est figé : le destinataire le voit comme tu l'as fait. Tu gardes ton .odt pour pouvoir le modifier."},
{q:"Dans un en-tête, comment places-tu un texte à droite&nbsp;?",
r:["Avec des espaces","Avec la touche Tab","En agrandissant la marge"],
b:1, e:"Les taquets sont déjà posés dans l'en-tête : une fois Tab pour le centre, deux fois pour la droite."}
]);
})();