2011-11-10 35 views
4

我有以下幾點:重新觸發一個JavaScript事件

<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? 
    } 
} 

我失敗的嘗試是:

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

而且

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

問題是如何基於已經存儲的事件對象觸發事件。它可以是鼠標或鍵盤事件。

P.S.這個例子是關於在光標改變/使用鼠標突出顯示的支持下運行按下的鍵的回放。

+0

http://stackoverflow.com/questions/596481/simulate-javascript-key-events – airportyh

+0

不確定您是否可以使用以前的事件對象。但你可以根據舊的創建新的。 – airportyh

+0

你確定JavaScript解釋器必須爲每個事件創建一個新的新對象嗎?我認爲它可能會重用事件對象,在這種情況下,你不能將它們存儲起來,你需要複製一份。 – 6502

回答

2

我想我接近你想要的東西。測試它jsbin這裏:http://jsbin.com/epaqej/18 或複製代碼:

JavaScript代碼:

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代碼:

<!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> 
+0

一個驚人的努力,但你是否建議事件調度不能用來做到這一點自動神奇? – Incognito

+0

老實說,我已經搜索了一段時間才實現這一點,但它似乎事件派遣不能自動奇蹟地寫入一個textarea等... – alessioalex

+0

這就是我所害怕的。我很好奇,如果未來的瀏覽器版本確實有這種行爲,或者這種事件的重新創建僅限於某些輸入類型。 – Incognito

0

使用e.originalEvent

你進入無限循環然而所以一定要小心:

你得到你從keyslog火每一個在那裏活動。

當事件被觸發時,它會被重新添加到事件處理程序中的keyslog中,然後循環會一直增長,直到用完計算機。

在進入循環之前將keyslog.length分配給本地變量可能是一個解決方案。

1

瑞安,這可能不是做什麼你正在尋找 - 即,您要求一種重新拋出事件幷包括突出顯示/光標位置的方式 - 但它確實允許您從一個在另一文本區域包括按鍵之間的暫停textarea的,刪除,插入,等等

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.net/ZtgME/1/