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.