<main>
<h1>Undoable counter</h1>
<div>
<button id="undo">Undo</button>
<button id="redo">Redo</button>
</div>
<div class="box-counter">
<div>
<button class="dec">-100</button>
<button class="dec">-10</button>
<button class="dec">-1</button>
</div>
<p id="counter">0</p>
<div>
<button class="inc">+1</button>
<button class="inc">+10</button>
<button class="inc">+100</button>
</div>
</div>
<div class="history">
<h1>History</h1>
<div id="box-history"></div>
</div>
</main>
@import url("https://fonts.googleapis.com/css2?family=Righteous&display=swap");
html,
body {
height: 100vh;
margin: 0;
}
body {
display: flex;
align-items: center;
justify-content: center;
font-size: 1.25em;
font-family: "Righteous", cursive;
}
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.box-counter {
display: flex;
align-items: center;
justify-content: space-evenly;
width: 20em;
}
.box-counter > div {
display: flex;
}
#counter {
margin: 1em;
}
button {
width: 6em;
padding: 1em 0.5em;
border-radius: 5px;
background: rgb(46, 46, 198);
color: white;
border: 1px solid white;
cursor: pointer;
}
button:hover {
background: rgb(38, 38, 162);
}
button:active {
background: rgb(46, 46, 198);
}
#undo {
background: rgb(255, 82, 82);
}
#undo:hover {
background: rgb(205, 65, 65);
}
#undo:active {
background: rgb(255, 82, 82);
}
#redo {
background: rgb(48, 167, 91);
}
#redo:hover {
background: rgb(42, 146, 80);
}
#redo:active {
background: rgb(48, 167, 91);
}
.history {
text-align: center;
}
#box-history {
display: flex;
flex-direction: column-reverse;
width: 16em;
height: 10em;
border: 1px solid black;
overflow-y: scroll;
}
@media (max-width: 700px) {
.box-counter {
flex-direction: column;
}
}
let counter = 0;
let history = [0];
const historyBox = document.getElementById("box-history");
const counterText = document.getElementById("counter");
Object.values(document.getElementsByClassName("dec")).forEach((button) =>
button.addEventListener("click", onCounterChange)
);
Object.values(document.getElementsByClassName("inc")).forEach((button) =>
button.addEventListener("click", onCounterChange)
);
document.getElementById("undo").addEventListener("click", handleUndo);
document.getElementById("redo").addEventListener("click", handleRedo);
function onCounterChange(event) {
const currentButton = event.currentTarget;
if (clickUndo > 1) {
console.log(history);
history.splice(history.length - (clickUndo - 1), clickUndo - 1);
console.log(history);
}
if (currentButton.className === "inc") {
counter += currentButton.innerText.slice(1) - "";
} else {
counter -= currentButton.innerText.slice(1) - "";
}
clickUndo = 1;
history.push(counter);
counterText.innerText = counter;
let historyText = document.createElement("p");
historyText.innerText = `${currentButton.innerText} (${
history[history.length - 2]
} -> ${history[history.length - 1]})`;
historyBox.appendChild(historyText);
}
let undoTexts = [];
let clickUndo = 1;
function handleUndo() {
if (history.length - clickUndo === 0 ) {
return false;
}
clickUndo++;
counter = history[history.length - clickUndo];
counterText.innerText = counter;
undoTexts.push(historyBox.lastChild.innerText);
historyBox.lastChild.remove();
}
function handleRedo() {
if (clickUndo === 1) {
return false;
}
clickUndo--;
counter = history[history.length - clickUndo];
counterText.innerText = counter;
let historyText = document.createElement("p");
historyText.innerText = undoTexts[undoTexts.length - 1];
historyBox.appendChild(historyText);
undoTexts.pop();
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.