En action
--
✅ Clean, delegation‑free version
Each button gets its own click listener. The structure is simple
--- remove text / not node
// Delete: remove last character
if (action === "del") {
const text = choices.textContent || "";
if (text.length > 0) {
choices.textContent = text.slice(0, -1);
}
return;
}
✅ Delegation + delete last text node
const container = document.querySelector(".container"); const choices = document.querySelector(".choices"); // Select all keys directly (no delegation) const keys = container.querySelectorAll("button.key"); keys.forEach(key => { key.addEventListener("click", () => { // brief visual feedback key.classList.add("pressed"); setTimeout(() => key.classList.remove("pressed"), 800); const action = key.dataset.action; // Delete: remove exactly one character from the end if (action === "del") { const text = choices.textContent || ""; if (text.length > 0) { choices.textContent = text.slice(0, -1); } return; } // Regular key: use the data-symbol from HTML const symbol = key.dataset.symbol || key.textContent.trim(); if (!symbol) return; choices.appendChild(document.createTextNode(symbol)); }); });
const container = document.querySelector(".container"); const choices = document.querySelector(".choices"); container.addEventListener("click", (event) => { const key = event.target.closest("button.key"); if (!key) return; const action = key.dataset.action; // DELETE: remove the last text node if (action === "del") { const last = choices.lastChild; if (last && last.nodeType === Node.TEXT_NODE) { choices.removeChild(last); } return; } // REGULAR KEY: append a new text node const symbol = key.dataset.symbol || key.textContent.trim(); if (!symbol) return; choices.appendChild(document.createTextNode(symbol)); });
-------------- 🚨Action du delete -------------------What happens when you press A, B, C
Your DOM looks like this:
Codechoices ├─ #text "A" ├─ #text "B" └─ #text "C"What happens when you delete C
if you run:
choices.textContent = text.slice(0, -1);
choices.textContentremoves all existing child nodes and replaces them with one new text node containing"AB".So the DOM becomes:
Codechoices └─ #text "AB"This is expected behavior —
textContentalways normalizes everything into a single text node.
✔️ If you want to keep separate text nodes
Then you must delete from the last text node, not rewrite the whole element.
If you press A, B, C
You create three separate text nodes:
Codechoices ├─ #text "A" ├─ #text "B" └─ #text "C"When you delete
You remove the entire last text node, not just its last character.
So after deleting C (the textNode)
choices ├─ #text "A" └─ #text "B"You now have two nodes, not one — and the content is
"AB"because those two nodes happen to be adjacent.This is correct behavior for your code.
help !
const pizzas = [
{ name: "queen", toppings: ["🐷", "🍄", "🍅", "🧀"] },
{ name: "me", toppings: ["🧀"] }
];
const headers = Object.keys(pizzas[0]);
const template = `
<ul>
${pizzas
.map(pizza => {
const line = headers
.map(header => `${header}: ${pizza[header]}`)
.join(" ");
return ` <li>${line}</li>`;
})
.join("\n")}
</ul>
`;
console.log(template);
Offre pour une alternance
🌟 Offre d’alternance – Développeur Web (Typescript / Angular)
Vous êtes motivé pour rejoindre une entreprise innovante spécialisée dans le développement Web ?
Vous souhaitez évoluer dans un environnement technique moderne (Typescript, Angular) au sein d’une équipe qui a déjà accueilli deux étudiants en alternance de notre établissement avec succès ?
Cette opportunité est faite pour vous.
🚀 Ce que l’entreprise propose
- Une alternance au sein d’une société dynamique et tournée vers l’innovation
- Un accompagnement par des développeurs expérimentés
- Des projets concrets en Typescript, Angular et technologies Web modernes
- Un cadre idéal pour progresser rapidement et gagner en autonomie
🎯 Profil recherché
- Étudiant(e) en L3 informatique ou développement Web
- Curiosité, motivation et envie d’apprendre
- Intérêt marqué pour les technologies front-end modernes
📩 Intéressé(e) ?
Remplissez rapidement le formulaire ci-dessous.
Je transmettrai directement votre candidature aux recruteur (ne me contactez pas)
Liste projets
Interface
Application
✔️ Js calculette 1 : variables et fx
https://github.com/dupontdenis/Quiz-statique.git
https://github.com/dupontdenis/taux.git
API :
https://github.com/dupontdenis/Quiz-App-Master.git
https://github.com/dupontdenis/quiz-top.git
https://github.com/dupontdenis/filmsGhibli_Vanilla.git
https://github.com/dupontdenis/weather-fetch.git
https://github.com/dupontdenis/Infinite-Scroll.git
Base de données
🆘 Installation : mongodb →
Examen
Donnez le corps de la fonction some(array, test) qui teste si au moins un élément du tableau en argument passe le test implémenté.
→ Soit la BD d'animaux, comprenant des 🐶 et des chats 🐱.
Animals = [{name: 'But',age: 3,type: 🐶},{name: 'Lizzy',age: 6,type:🐶}, … ];
La fonction getAges, calcule la somme des âges des chiens en équivalent humain (1 an pour un homme est équivalent à 7 ans pour un chien)
function getAges(array) {
let sum = 0;
for (var i = 0; i < array.length; i++){
if (array[i].type === 🐶){
let tempAge = array[i].age;
sum += (tempAge * 7); } }
return sum; }
Écrivez la fonction getAges sous la forme Animals.filter(?).map(?).reduce(?);
→ Soit la BD des étudiants L2 = [{name: "bob", age: 18, notes: [12,18,14]}, {name: "Abdel", age: 21, notes: [17, 04]}, ...]
Donnez les noms des étudiants par génération (même âge).
Donnez les deux étudiants qui ont eu les meilleures notes.
→ Affichez (DOM) la liste (ul) des noms, avec en rouge ceux qui ont au moins une note inférieure au plafond de 05/20.
→ Affichez (DOM) la liste (ul) des noms avec pour effet "hover" la moyenne de l'étudiant qui s'affiche. Le CSS fourni est : li:hover:before{content: attr(data-average)}
→ ⌨️Application
Donnez le code pour l'application clavier !
🧮Projet : Calculette
🧮Etat interne
➕DOM
🚀Interaction 
Cours : formulaire
Délégation :
How forms work : 🪛→ simple use
🍕En action : select pizza
Révisions :
Code
Bilan
Affichage en cohortes : Bootstrap[accordion]
https://dupontdenis.github.io/cohorteAccordeon/
Affichages en cohortes : Grid
Examen : training
export const students = [
Entrainement Examen
const ob = { a: 1, b: 2 }; const anotherObject = ob; anotherObject.b = 4; | dessiner la mémoire |
const [,y,,x] = [() => 1, 2, {}, function (a) { console.log(a); }, { nom: "John" }] | Valeurs de x,y |
x = 10; y = x++; z = ++x; | Valeurs de x, y, z |
🪛Donner le code de la fonction filtre(array,fx)
⚽const joueurs = [
{nom:"Benzema",pays:"France",but:7},{nom:"Mbappe",pays:"FRANCE",but:8},
{nom:"Neymar",pays:"brésil",but:3}, {nom:"Messi",pays:"argentine",but:1},
{nom:"Mané",pays:"SENEGAL",but:3}, {nom:"Sarr",pays:"senegal",but:1},
];
const map = new Map([
["france","Fr"],["brésil","Br"],["argentine","Ar"],["senegal","Se"],
]);
Normaliser les pays en minuscule
Donner la liste des joueurs français
Donner la liste des joueurs d'un pays
Donner un objet avec pour chaque pays la liste des joueurs
Donner le nombre de buts marqués
Afficher pour chaque pays le meilleurs buteur
On dispose d'une grille.
.bestPlayer {
display: grid;
grid-auto-flow: column;
grid-template-columns: [Fr] 1fr [Br] 1fr [Ar] 1fr [Se] 1fr;
}
