最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - Re-fire a javascript event from a stored event object - Stack Overflow

programmeradmin1浏览0评论

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 failed attempts were:

document.getElementById('simulator').dispatchEvent(e);

And

$('#simulator').trigger(e);

The question is how to trigger an event based on an already stored event object. It can be a Mouse or Keyboard event.

P.S. The example is about running a playback of pressed keys with the support of cursor changing/highlighting using mouse.

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 failed attempts were:

document.getElementById('simulator').dispatchEvent(e);

And

$('#simulator').trigger(e);

The question is how to trigger an event based on an already stored event object. It can be a Mouse or Keyboard event.

P.S. The example is about running a playback of pressed keys with the support of cursor changing/highlighting using mouse.

Share Improve this question edited Nov 10, 2011 at 2:33 CodeOverload asked Nov 10, 2011 at 1:29 CodeOverloadCodeOverload 48.6k56 gold badges133 silver badges223 bronze badges 4
  • stackoverflow./questions/596481/… – airportyh Commented Nov 10, 2011 at 2:24
  • Not sure if you can use a previous event object. But you can definitely create new ones based on the old ones. – airportyh Commented Nov 10, 2011 at 2:25
  • Are you sure that the javascript interpreter must create a new fresh object for each event? I think it can possibly reuse event objects and in that case you cannot just store them away, you need to make a copy. – 6502 Commented Nov 10, 2011 at 7:05
  • @Ryan I've been trying to figure it out a bit, I've asked a question over here that is somewhat related, it might help you out: stackoverflow./questions/8084970/… – Incognito Commented Nov 10, 2011 at 20:19
Add a ment  | 

3 Answers 3

Reset to default 2 +50

I think I got this close to what you wanted. Test it on jsbin here: http://jsbin./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./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./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 rethrow events and include highlight/cursor position - but it does allow you to playback the text entry from one textarea on another textarea including the pauses between keypress, deletes, insertions, 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

http://jsfiddle/ZtgME/1/

Use e.originalEvent

You'll enter an infinite loop however so be careful:

You get your events from keyslog fire each one in there.

When the event is fired it's "re-added" to the keyslog in the event handler, then the loop grows by one forever until you run out of puter.

assigning keyslog.length to a local variable before you enter the loop maybe a solution.

发布评论

评论列表(0)

  1. 暂无评论