web-dev-qa-db-ja.com

キープレスイベントをプログラムでシミュレートすることは可能ですか?

キープレスイベントをJavaScriptでプログラム的にシミュレートすることは可能ですか?

314
tan

WebKitとgeckoの両方で動作するjquery以外のバージョン

var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";


keyboardEvent[initMethod](
                   "keydown", // event type : keydown, keyup, keypress
                    true, // bubbles
                    true, // cancelable
                    window, // viewArg: should be window
                    false, // ctrlKeyArg
                    false, // altKeyArg
                    false, // shiftKeyArg
                    false, // metaKeyArg
                    40, // keyCodeArg : unsigned long the virtual key code, else 0
                    0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
document.dispatchEvent(keyboardEvent);
160
Philip Nuzhnyy

JQuery 1.3.1を使用しても問題ない場合:

function simulateKeyPress(character) {
  jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}

$(function() {
  $('body').keypress(function(e) {
    alert(e.which);
  });

  simulateKeyPress("e");
});
68
alex2k8

あなたができることは、プログラム的にkeyeventsを発動することによってkeyeventリスナーをトリガーすることです。サンドボックス化されたセキュリティの観点からこれを許可することは理にかなっています。この能力を使って、典型的な オブザーバパターン を適用することができます。このメソッドを "simulating"と呼ぶことができます。

以下は、j3と共にW3C DOM標準でこれを実現する方法の例です。

function triggerClick() {
  var event = new MouseEvent('click', {
    'view': window,
    'bubbles': true,
    'cancelable': true
  });
  var cb = document.querySelector('input[type=submit][name=btnK]'); 
  var canceled = !cb.dispatchEvent(event);
  if (canceled) {
    // preventDefault was called and the event cancelled
  } else {
    // insert your event-logic here...
  }
}

この例は、 https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events に基づいています。

JQueryでは:

jQuery('input[type=submit][name=btnK]')
  .trigger({
    type: 'keypress',
    which: character.charCodeAt(0 /*the key to trigger*/)      
   });

しかし最近では、ブラウザサンドボックスを離れるようなキーイベントを実際に引き起こす[DOM]方法はありません。そしてすべての主要なブラウザベンダはそのセキュリティコンセプトを固守するでしょう。

Adobe Flashのような - NPAPIベースで、サンドボックスを迂回することを許可するプラグインに関しては、これらは 段階的廃止 です。 Firefox

詳細説明:

(Pekkaがすでに指摘したように)あなたはできないし、あなたはセキュリティ上の理由からしてはいけません。あなたは常にその間にユーザーの操作が必要になります。さらに、さまざまなプログラムによるキーボードイベントがなりすまし攻撃を引き起こす可能性があるため、ブラウザベンダがユーザーから訴えられる可能性を想像してください。

選択肢や詳細についてはこちら の投稿 をご覧ください。フラッシュベースのコピー&ペーストが常にあります。これはエレガントな 例です 。同時に、なぜWebがプラグインベンダから離れようとしているのかの証です。

プログラムでリモートコンテンツにアクセスするための オプトインCORSポリシー の場合にも、同様のセキュリティの考え方が適用されます。

答えは:
サンドボックスブラウザ環境でプログラム的に入力キーをトリガーする方法は通常ありません

結論:将来的には、特別なブラウザモードやゲームの最終目標に対する特権、あるいは同様のユーザーエクスペリエンスの下では不可能になるとは言っていません。ただし、このようなモードに入る前に、 フルスクリーンAPIモデル と同様に、ユーザーにアクセス許可とリスクの入力が求められます。

便利:キーコードのコンテキストでは、 この ツールとキーコードのマッピングが役立ちます。

開示:答えはここでの答え に基づいています

46
Lorenz Lo Sauer

dispatchEvent()を使うことができます:

function simulateKeyPress() {
  var evt = document.createEvent("KeyboardEvent");
  evt.initKeyboardEvent("keypress", true, true, window,
                    0, 0, 0, 0,
                    0, "e".charCodeAt(0))
  var body = document.body;
  var canceled = !body.dispatchEvent(evt);
  if(canceled) {
    // A handler called preventDefault
    alert("canceled");
  } else {
    // None of the handlers called preventDefault
    alert("not canceled");
  }
}

私はこれをテストしませんでした、しかしそれは dispatchEvent()のドキュメント のコードから適応されています。あなたはおそらくそれを通して、そしてまたcreateEvent()とinitKeyEvent()のためのドキュメントを読みたくなるでしょう。

22
Plutor

このような要素にキーボードイベントを送ることができます

element.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));
21
aljgom

キーボードイベントを作成して送出することができ、それらは適切な登録済みイベントハンドラを起動しますが、例えばinput要素に送出された場合、それらはテキストを生成しません

テキスト入力を完全にシミュレートするには、一連のキーボードイベントを生成し、input要素のテキストを明示的に設定する必要があります。イベントの順序は、テキスト入力をどれだけ徹底的にシミュレートしたいかによって異なります。

最も簡単な形式は次のとおりです。

$('input').val('123');
$('input').change();
20
Alex Burtsev

Alex2k8からの答えを土台に、jQueryがサポートするすべてのブラウザで動作する修正版を紹介します(問題はjQuery.event.triggerの引数が欠落していたことです。これは、その内部関数を使用する場合は忘れがちです)。

// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
  // Internally calls jQuery.event.trigger with arguments (Event, data, elem).
  // That last argument, 'elem', is very important!
  jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};

jQuery(function ($) {
  // Bind event handler
  $('body').keypress(function (e) {
    alert(String.fromCharCode(e.which));
    console.log(e);
  });
  // Simulate the key press
  $('body').simulateKeyPress('x');
});

これをさらにプッシュして、イベントをシミュレートするだけでなく実際に文字を挿入させることもできます(input要素の場合)。ただし、そうすることを試みるときには、ブラウザを越えたやり方がたくさんあります。 SendKeys のようなより複雑なプラグインを使用してください。

13
Timo Tijhof

keypressイベントが必要な機能を提供できない場合があります。一般に、イベントは2つの結果として発生するイベントkeydownと、それに続くそれが同じキーに対してkeyupから結合されます。 1つずつイベントを生成してください。

element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));

興味のある人のために、実際には、キーボード入力イベントを確実に再現することができます。入力領域のテキストを変更する(カーソルを移動する、または入力文字を介してページを移動する)には、DOMイベントモデルに厳密に従う必要があります。 http://www.w3.org/TR/DOM-Level-3-Events /#h4_events-inputevents

モデルはするべきです:

  • フォーカス(ターゲットセットを持つDOMにディスパッチされます)

それから、各文字について:

  • keydown(DOMから派遣)
  • beforeinput(テキスト領域または入力の場合はターゲットに送出されます)
  • キープレス(DOM上で送出されます)
  • 入力(テキスト領域または入力の場合はターゲットに送出されます)
  • 変更(選択の場合はターゲットに送出されます)
  • キーアップ(DOM上で送出)

その後、オプションでほとんどの場合:

  • ぼかし(ターゲットセットを持つDOM上で送出されます)

これは実際には(valueステートメントを変更することなく)javascriptを介してページ内のテキストを変更し、適切なjavascriptリスナ/ハンドラを開始します。シーケンスのJavaScriptが適切な順序で起動されない場合、入力ボックスのテキストは変更されず、選択内容は変更されず、カーソルはテキスト領域の次のスペースに移動しません。

残念ながら、コードはNDAの下で雇用主のために書かれたものなので共有できませんが、それは可能ですが、各要素のキー入力「スタック」全体を正しい順序で再作成する必要があります。

8
Trevor

このアプローチは、ブラウザ間でキーコードの値を変更することをサポートします。 出典

var $textBox = $("#myTextBox");

var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;

$textBox.trigger(press);
7
Ata Iravani

customEventを使うだけ

Node.prototype.fire=function(type,options){
     var event=new CustomEvent(type);
     for(var p in options){
         event[p]=options[p];
     }
     this.dispatchEvent(event);
}

4 ex ctrl + zをシミュレートしたい

window.addEventListener("keyup",function(ev){
     if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
     })

 document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})
7
bortunac

これは私のために働きました、そしてそれは私のtextaeraのためのキーアップをシミュレートします。あなたがそれをページ全体のために望むならば、ちょうどこのKeySimulation()のように<body>の上に<body onmousemove="KeySimulation()">を置くか、あるいはonmousemoveでないならば、onmouseoverまたはonloadもまた働きます。

<script>
function KeySimulation()
{
var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) {  // Chrome, IE
    e.initKeyboardEvent("keyup", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FireFox
    e.initKeyEvent("keyup", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("MyTextArea").dispatchEvent(e);
}
</script>

<input type="button" onclick="KeySimulation();" value=" Key Simulation " />
<textarea id="MyTextArea" rows="15" cols="30"></textarea>
4
SeekLoad

これは本当に役に立つライブラリです: https://cdn.rawgit.com/ccampbell/mousetrap/2e5c2a8adbe80a89050aaf4e02c45f02f1cc12d4/tests/libs/key-event.js

どこから来たのかはわかりませんが、役に立ちます。 window.KeyEvent.simulate()メソッドが追加されているので、enterをシミュレートする場合はKeyEvent.simulate(0, 13)'Q'の場合はKeyEvent.simulate(81, 81)を使用します。

私は https://github.com/ccampbell/mousetrap/tree/master/tests でそれを得ました。

4
fiatjaf

コピー+貼り付けコンソールの準備ができている単一行のVanilla Javascript Webインスペクタ男。ほとんどの開発者にとってすでに魅力的なので、彼を説得しようとしないでください - 彼は独身になるべきです..行)

    var pressthiskey = "q"/* <--- :) !? q for example */;
    var e = new Event("keydown");
    e.key = pressthiskey;
    e.keyCode = e.key.charCodeAt(0);
    e.which = e.keyCode;
    e.altKey = false;
    e.ctrlKey = true;
    e.shiftKey = false;
    e.metaKey = false;
    e.bubbles = true;
    document.dispatchEvent(e);
3

これは私が見つけたものです:

function createKeyboardEvent(name, key, altKey, ctrlKey, shiftKey, metaKey, bubbles) {
  var e = new Event(name)
  e.key = key
  e.keyCode = e.key.charCodeAt(0)
  e.which = e.keyCode
  e.altKey = altKey
  e.ctrlKey = ctrlKey
  e.shiftKey = shiftKey
  e.metaKey =  metaKey
  e.bubbles = bubbles
  return e
}

var name = 'keydown'
var key = 'a'

var event = createKeyboardEvent(name, key, false, false, false, false, true)

document.addEventListener(name, () => {})
document.dispatchEvent(event)
3
Konowy

これはChromeとChromiumで動作するソリューションです(これらのプラットフォームのみをテストしました)。 Chromeには、キーコードを処理するためのバグまたは独自のアプローチがあるため、このプロパティはKeyboardEventに別途追加する必要があります。

function simulateKeydown (keycode,isCtrl,isAlt,isShift){
    var e = new KeyboardEvent( "keydown", { bubbles:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt } );
    Object.defineProperty(e, 'keyCode', {get : function() { return this.keyCodeVal; } });     
    e.keyCodeVal = keycode;
    document.dispatchEvent(e);
}
3
Soren

ユーザーが問題のキーを押すとすぐにそれへの参照を保存し、他のHTMLの他の要素にそれを使用することができます。

EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input>
TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)">
Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)">
<script>
var gZeroEvent;
function keyPressRecorder(e)
{
  gZeroEvent = e;
}
function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT)
{
  if(typeof(gZeroEvent) != 'undefined')  {
TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent);
keyPressHandler(TTT);
  }
}
function keyPressHandler(TTT)
{
  if(typeof(gZeroEvent) != 'undefined')  {
TTT.currentTarget.value+= gZeroEvent.key;
event.preventDefault();
event.stopPropagation();
  }
}
</script>

独自のイベントを作成した場合はkeyCodeを設定でき、実際のキーボードイベントから既存のパラメータをコピーすることができます(dispatchEventの仕事であるためターゲットを無視します)。

ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})
0
yan bellavance

これを機能させるための重要な部分は、charCodekeyCode、およびwhichすべての非推奨のメソッド であることを認識することです。したがって、コードprocessingがキープレスイベントでこれら3つのいずれかを使用すると、偽の回答(デフォルトの0など)が返されます。

keyなどの非推奨のメソッドを使用してキープレスイベントにアクセスする限り、問題ありません。

完了のために、イベントをトリガーするための基本的なJavaScriptコードを追加しました。

const rightArrowKey = 39
const event = new KeyboardEvent('keydown',{'key':rightArrowKey})
document.dispatchEvent(event)
0
Jack Kinsella

TypeScriptをサポートするネイティブJavaScriptソリューション:

KeyCodeまたは使用しているプロパティを入力し、KeyboardEventInitにキャストします

const event = new KeyboardEvent("keydown", {
          keyCode: 38,
        } as KeyboardEventInit);
0
eugen sunic

私は質問がキープレスをシミュレートするJavaScriptの方法を要求することを知っています。しかし、物事を行うjQueryの方法を探している人のために:

var e = jQuery.Event("keypress");
e.which = 13 //or e.keyCode = 13 that simulates an <ENTER>
$("#element_id").trigger(e); 
0