Previously, we created a javascript keyboard buffer that can edit text in a static html page. Using those functions I’d like to add a buffer replay.
I would like to add an onclick event to a specified div such that it will activate the keyboard buffer and leverage the previously discussed handleKey() event handler, as well as the appendChar(el) function. E.g.,
//
// onclick event handler
// initialize this element for keyboard buffer
function initEditable() {
selectElement(this);
var SPECIAL = [8, 32, 37, 39, 222];
document.onkeydown = handleKey(function(k) {return SPECIAL.contains(k)});
document.onkeypress = handleKey(function(k) {return !SPECIAL.contains(k)});
}
targetDiv = $('target');
targetDiv.onclick = initEditable;
The function calls selectElement(this) which will need to modify the element to add a temporary link for starting a replay. Once selected, that div will be editable, I would like another temporary link that when pressed will remove all temporary links and remove the onkey events (making the div non-editable).
The following JavaScript will enable the target div to toggle between editable and non-editable:
//
// create <a> element
function newA(aid, alabel, ahref, fonclick) {
var newA = document.createElement('a');
newA.appendChild(document.createTextNode(alabel));
newA.setAttribute('href', ahref);
newA.setAttribute('id', aid);
newA.onclick = fonclick;
return newA;
}
//
// prepare <div>, add 'replay' and 'save' links
function selectElement(el) {
clearSelected();
origText = el.innerHTML;
el.innerHTML = '';
var newDiv = document.createElement('div');
newDiv.innerHTML = origText;
newDiv.setAttribute('id', 'editSelected');
el.appendChild(newDiv);
el.appendChild(newA('areplay', 'replay', '#', replayKeys));
el.appendChild(newA('aclear', 'save', 'javascript:clearSelected()', null));
el.onclick = null;
}
//
// clear any <div> that is intercepting onkey events
// and clear the buffer
function clearSelected() {
document.onkeypress = null;
document.onkeyup = null;
document.onkeydown = null;
BUFFER = [];
bp = 0;
var el = $('editSelected');
if (el) {
var oldText = el.innerHTML;
var pel = el.parentNode;
pel.removeChild(el);
pel.removeChild($('areplay'));
pel.removeChild($('aclear'));
pel.innerHTML = oldText;
pel.onclick = initEditable;
}
}
When the target div is clicked it will activate the keyboard buffer such that all keystrokes will appear in the innerHTML of that div and link to a replayKeys() function. The replayKeys() function simply needs to process the BUFFER according to a timer, e.g.,
TIMER = 100;
//
// replay all keystrokes from buffer
function replayKeys() {
el = $('editSelected');
el.innerHTML = origText;
bp = 0;
replaying = setInterval(replayHandler, TIMEOUT);
}
function replayHandler() {
el = $('editSelected');
if (bp < BUFFER.length) {
appendChar(el);
} else {
replaying ? clearInterval(replaying) : false;
}
}
The built-in setInterval() function will call a specified function periodically according to the TIMEOUT value in milliseconds, and will continue running until the clearInterval() function is called.
Next, I’d like to combine all of this into a single JavaScript include such that it can register multiple editable div’s.