--
✅ Clean, delegation‑free version
Each button gets its own click listener.
The structure is simple
const container = document.querySelector(".container");
const choices = document.querySelector(".choices");
// 🪛Direct listeners on each key
const keys = container.querySelectorAll("button.key");
keys.forEach(key => {
key.addEventListener("click", () => {
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 symbol as a new text node
const symbol = key.dataset.symbol || key.textContent.trim();
if (!symbol) return;
choices.appendChild(document.createTextNode(symbol));
});
});
--- 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:
choices
├─ #text "A"
├─ #text "B"
└─ #text "C"
What happens when you delete C
if you run:
choices.textContent = text.slice(0, -1);
choices.textContent removes all existing child nodes and replaces them with one new text node containing "AB".
So the DOM becomes:
This is expected behavior — textContent always 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:
choices
├─ #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.