I'd like to be able to record then playback whatever happened in a textarea.
I've came across some solutions but they're not reliable, Like sending each keystroke via AJAX. In that case i'll end up having millions of rows in my DB.
The idea that i had in mind is to log the keystrokes to a variable in client side, updating that variable with the action, but keeping track of time between each keystoke. Also making sure that it supports deleting data as well.
At the end i'd send this whole variable to the db one time, then i can decode it later for playback.
Mind Map of what the variable would look like:
hellooo[1.2][backspace][0.6][backspace]World![return]
Idle time __^ Removes one char __^
I believe that google docs is doing something like that to playback whatever users were typing.
Any Ideas?
Luckily JavaScript events already take care of all the encoding issues for you. You can just toss the whole event object that a keyup/keydown/keypress/whatever was directly into an array.
Each object contains:
You can then just encode the array and send it off with your favourite ajax method to the server for storage.
So your code only needs a function that can store data. Don't use this exact function it's just for demonstration purposes.
var handler = function (e) {
handler.data.push(e);
console.log(handler.data);
}
handler.data = [];
window.addEventListener("keyup", handler);
window.addEventListener("keydown", handler);
window.addEventListener("keypress", handler);
Since it's an array, they should all be in order, but in the odd event it goofs, you have timestamp data on each event (which also lets you find out the delay between events, which is AWESOME if you have mixed keypresses.).
You can then replay events however you wish to design them -- but now you don't have to invent your own spec because the lovely fokes at w3c did all the hard work for you when they designed the DOM event spec.
Store the time of each action and the result of that action and when you are finished serialise the log and store that.
It is over-complicated to replay each action individually. Say a user moves back a few characters and adds new ones there. You will need to keep track of the cursor position.
Just remember the entire value of the textarea for each keystroke. There is no need to remember how that occurred is there?
Here's an implementation. fiddle
<textarea id="recorder"></textarea>
<textarea id="playback"></textarea>
<script type="text/javascript">
var Playback = {
//store the time an action occured and the resulting state in an object
//don't use an array because they are not sparce - interstitial keys
//will have to be iterated over
record: {},
init: function( recorderId, playbackId ) {
this.recorder = document.getElementById( recorderId );
this.playback = document.getElementById( playbackId );
this.recorder.addEventListener( 'focus', function() {
Playback.record = {};
this.value = '';
}, false );
this.recorder.addEventListener( 'keyup', function( e ) {
Playback.record[ (new Date()).getTime() ] = this.value;
}, false );
this.recorder.addEventListener( 'blur', function( e ) {
Playback.playback.value = '';
//store the time the sequence started
//so that we can subtract it from subsequent actions
var mark = null;
for( var t in Playback.record ) {
if( mark ) {
var timeout = t - mark;
} else {
var timeout = 0;
mark = t;
}
// We need to create a callback which closes over the value of t
// because t would have changed by the time this is run
setTimeout( Playback.changeValueCallback( Playback.record[t] ), timeout );
}
}, false );
},
changeValueCallback: function( val ) {
return function() { Playback.playback.value = val }
}
}
Playback.init( 'recorder', 'playback' );
</script>
Caveat: The event handling is for compliant browsers only, you'd need to accommodate internet explorer yourself
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With