Restart javascript event from event stored object
I have the following:
<textarea id="text"></textarea> <textarea id="simulator"></textarea> <br/> <div onclick="simulate()">Simulate</div> keyslog = []; $('#text').bind('keyup keydown keypress mousedown mouseup', function(e){ keyslog.push(e); } function simulate(){ for(var i=0;i<keyslog.length;i++){ var e = keyslog[i]; // how to fire "e" event again on #simulator? } } My unsuccessful attempts:
document.getElementById('simulator').dispatchEvent(e); and
$('#simulator').trigger(e); The question is how to trigger an event based on an already saved event object. This could be a mouse or keyboard event.
PS An example is to play keystrokes with support for changing / highlighting the cursor with the mouse.
I think I got to what I wanted. Check it out on jsbin here: http://jsbin.com/epaqej/18 or copy the code:
JavaScript Code:
jQuery(function() { var keyslog = [], ctime = [], counter = 0, when = [], $simulator = $('#simulator'), $log = $('#log'); $('#text').bind('keyup keydown keypress mousedown mouseup', function(e){ when[counter] = Date.now(); // get the current time // delay_time is 0 for the first element // and the difference between the time past since the last event and the current event otherwise e.delay_time = (counter) ? (when[counter] - when[counter-1]) : 0; keyslog.push(e); counter++; }); $('#simulator').bind('keyup keydown keypress mousedown mouseup', function (e) { // console.log(e.type + ' called on #simulator'); }); function simulate(current) { var e, text = '', char_code, simtext = ''; // console.log('executing event ' + current + ' of ' + keyslog.length); if (current < keyslog.length) { e = keyslog[current]; setTimeout(function() { char_code = e.which || e.charCode || e.keyCode; text += e.type + ' called after ' + e.delay_time + '<br />'; if (e.type === 'keypress') { simtext += String.fromCharCode(char_code); } else if (e.type === 'mousedown') { $simulator.focus(); } else if (e.type === 'mouseup') { $simulator.blur(); } $log.append(text); // write to logger $simulator.append(simtext); // add text to textarea if exists $simulator.trigger(e); // trigger the event on $simulator current += 1; // increase the iterator variable simulate(current); }, e.delay_time); } else { $log.append(' == FINISHED == '); } } $('#simulate').click(function() { simulate(0); }); }); HTML code:
<!DOCTYPE html> <html> <head> <script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script src="events.js"></script> <meta charset=utf-8 /> <title>JS Bin</title> <!--[if IE]> <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <style> article, aside, figure, footer, header, hgroup, menu, nav, section { display: block; } #simulate { cursor: pointer; border: 2px solid #CCC; width: 80px; text-align: center; } #container, #log { float: left;} #container { width: 25%; } #log { width: 50%; } </style> </head> <body> <div id="container"> <h4>Write your text here:</h4> <textarea id="text"></textarea> <br/><br /> <div id="simulate">Simulate:</div> <br/> <textarea id="simulator"></textarea> </div> <div id="log"> <h4>Logger here</h4> </div> </body> </html> Ryan, this may not do exactly what you are looking for, namely, you asked for a way to reconstruct the events and turn on the cursor selection / position, but this allows you to play a text entry from one text field to another text field, including pauses between keystrokes, deletions, inserts, etc.
HTML
<textarea id="text"></textarea> <textarea id="simulator"></textarea> <br /> <div id="simulate" >Simulate</div> Javascript
var keyslog = []; var baseTime = 0; $('#text').bind('keyup keydown keypress', function(e){ if (baseTime <= 0) baseTime = e.timeStamp; keyslog.push({delay:e.timeStamp-baseTime, text:$('#text').val()}); }); $('#simulate').click(function () { $simulator = $('#simulator'); while(keyslog.length > 0) { var e = keyslog.shift(); window.setTimeout(updateText, e.delay, $simulator, e.text); } }); function updateText($s, t) { $s.val(t); } jsFiddle
Use e.originalEvent
You enter an infinite loop, but be careful:
You get your events from keylog fire each of them.
When an event is triggered, it is βaddedβ to the keylog in the event handler, then the loop grows one forever until the computer is finished.
assigning keylog.length to a local variable before entering a loop is probably the solution.