↩️ Native Undo & Redo for the Web

Sam Thorogood
May 15, 2018 · 6 min read

Why


How


Build It

1. The ‘hidden’ text field

const undoer = document.createElement('input');
undoer.value = '0';
undoer.tabIndex = -1; // don't allow automatic tab
undoer.addEventListener('focus', () => {
// prevent focus, delay for Safari
window.setTimeout(() => undoer.blur(), 0);
});
// You could hide it (not with `display: none`—it must be on page):
//undoer.style.opacity = 0;
//undoer.style.position = 'absolute';
document.body.appendChild(undoer);

2. Pretending to enter input

let duringInput = false;
const undoStack = [{x: 1, y: 1}]; // have to start w/initial state
function pushNewUndoState(data) {
// remove states past now, add our new state
const nextState = +undoer.value + 1;
undoStack.splice(nextStateId, undoStack.length - nextState, data);

duringInput = true;

// focus and "type" the next number
undoer.focus();
document.execCommand('selectAll');
document.execCommand('insertText', false, nextStateId);

duringInput = false;
}

3. Listening to input events

undoer.addEventListener('input', (ev) => {
// nb. don't use 'change', it doesn't fire in all browsers
if (!duringInput) {
const data = undoStack[+undoer.value];
updateMazeWithData(data);
}
});

4. Special-case for Firefox


Extras

Intercepting Undo & Redo for text fields

theInput.addEventListener('input', (ev) => {
const currentValue = theInput.value;
document.execCommand('undo'); // undo this change
theInput.value = currentValue; // ... but reset the value
// TODO: You might want to persist the selection position.
pushNewUndoState(currentValue); // ... our special state to keep
});

The undo keyboard shortcuts


Thanks

Acknowledgements

Sam Thorogood

Written by

🎅🎄 Santaware Engineer at Google in sunny Sydney, Australia 🇦🇺 —evangelizes Chrome and the mobile web!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade