2012-05-04 20 views
25

htmlページ内の特定のtextarea要素でkeydownイベントをシミュレートします。私はクロムを使用しているので、私はinitKeyboardEventを私の変数に呼び出し、私はkeyCodeを渡してテキストエリアに入力します。ここに私が試したものです:ChromeのKeydown Simulationが正常に起動しますが、正しいキーが表示されません

このコードで
var keyEvent = document.createEvent('KeyboardEvent'); 
keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 77, 0); 
inputNode.dispatchEvent(keyEvent); 

テキストエリアのみEnterの鍵であるのkeyCode 13を取得しているが、私は手紙mを入力しています。だから、私は私がkeyCodeValに値を設定し、オンラインを見オーバーライドコードを試みたが、成功しません

var keyEvent = document.createEvent('KeyboardEvent'); 
Object.defineProperty(keyEvent, 'keyCode', { 
         get : function() { 
           return this.keyCodeVal; 
         } 
         }); 
keyEvent.initKeyboardEvent('keydown', true, false, null, 0, false, 0, false, 77, 0); 
keyEvent.keyCodeVal = 77; 
inputNode.dispatchEvent(keyEvent); 

誰がどのようにキーコード値を設定するという考えを持っていますか?

+0

注:イベントを手動で発生させても、そのイベントに関連付けられたデフォルトのアクションは生成されません。たとえば、キーイベントを手動で起動しても、その文字がフォーカスされたテキスト入力に表示されることはありません。 UIイベントの場合、セキュリティ上の理由から、スクリプト自体がブラウザとやりとりするユーザーアクションをシミュレートできないため、これは重要です。 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent –

+0

** EDITED **:Orwellophileのソリューションが機能します。このデモを試してみてください。これは実際の動作と一般的なイベントの代替方法です:http://jsbin.com/awenaq/4 –

答えて

77

非常に非常に近い...

あなたは 'which'プロパティをオーバーライドする必要があります。ここではいくつかのサンプルコードです:

Podium = {}; 
Podium.keydown = function(k) { 
    var oEvent = document.createEvent('KeyboardEvent'); 

    // Chromium Hack 
    Object.defineProperty(oEvent, 'keyCode', { 
       get : function() { 
        return this.keyCodeVal; 
       } 
    });  
    Object.defineProperty(oEvent, 'which', { 
       get : function() { 
        return this.keyCodeVal; 
       } 
    });  

    if (oEvent.initKeyboardEvent) { 
     oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, false, false, false, false, k, k); 
    } else { 
     oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, k, 0); 
    } 

    oEvent.keyCodeVal = k; 

    if (oEvent.keyCode !== k) { 
     alert("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ")"); 
    } 

    document.dispatchEvent(oEvent); 
} 

使用例:

Podium.keydown(65); 

注:このコードはIE、サファリ、または他のブラウザで動作するように設計されていません。まあ、おそらくFirefoxで。 YMMV。

+12

+1これは唯一の解決策です。このStackoverflow.com –

+0

私はこれをChrome拡張機能で使用してテキストエリアのキーダウンイベント(Facebook上)。何らかの理由でサイトのハンドラが起動されないため、応答しないようです。どんな考え? – freeall

+6

もう動作しないようです。代わりの提案。 –

14

オルホロフィルの解決策は機能しません。

  • まず、 'keyCode'、 'charCode'、 'which'はSafariとIE9 +(少なくとも)で読み込まれています。
  • 2番目:initKeyboardEventはちょっと混乱しています。すべてのブラウザは、それを別の方法で実装しています。 Webkitにも、initKeyboardEventの実装がいくつかあります。また、OperaのinitKeyboardEventへの "良い" の方法はありません。
  • 3番目:initKeyboardEventは推奨されていません。 initKeyEventまたはKeyboardEventコンストラクターを使用する必要があります。

ここで私はcross-browser initKeyboardEvent function(要旨)を書いた:

例:

var a = window.crossBrowser_initKeyboardEvent("keypress", {"key": 1, "char": "!", shiftKey: true}) 
alert(a.type + " | " + a.key + " | " + a.char + " | " + a.shiftKey) 

そしてここでは、クロスブラウザKeyboardEventのコンストラクタと私のDOM Keyboard Event Level 3 polyfillです。

例:

var a = new KeyboardEvent("keypress", {"key": 1, "char": "!", shiftKey: true}) 
alert(a.type + " | " + a.key + " | " + a.char + " | " + a.shiftKey) 

Example 2

Example 3

重要注1:charCodeはキーコードおよびプロパティは廃止されます。したがって、私のcrossBrowser_initKeyboardEventもKeyboardEventコンストラクタも、一部のブラウザではそのプロパティの正しい値が絶対に保証されていません。プロパティ "key"と "char"を代わりに使うか、gistを編集して、読み込み専用charCode、keyCode、およびどのプロパティを持つブラウザで強制的にinitEventを使用することができます。

重要な注記2:keypressイベントは廃止され、現在はKeyboard Event Level 3 polyfillでサポートされていません。これは、keypressイベントのkeyプロパティとcharプロパティがランダムな値を持つ可能性があることを意味します。私はその問題を下位互換性に解決するよう努めています。

+0

これまでに見た問題のベスト・ディスカッション。 +1 –

+0

@termi、私はChrome 36でイベントをシミュレートするためにソースを使用しようとしましたが、動作しません! –

+1

@AkashKava、 "cross-browser initKeyboardEvent関数(要点)"またはpolyfillを試しますか? Polyfillは古くなっています。私はそれを修正する余裕があまりありません。しかし、 "クロスブラウザのinitKeyboardEvent関数(要点)"が私のために働いています。あなたは例を挙げることができますか? – termi

4

@ OrwellophileのスクリプトをGoogle Chrome 26.0.1410.65(Mac OS X 10.7.5の場合)で動作させるには、1行を変更する必要がありました。スクリプトのパラメータがinitKeyboardEventであるようですMDN documentation for initKeyboardEventとは異なる順序です。

変更された行は次のようになります。

oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, k, k, "", "", false, ""); 
0

すべてのソリューションは、上記の作業をしているが、私はそうではないでしょう一つのケースを発見しました。

Dartが使用されている場合、KeyboardEventsを使用するDartコードは一般的なイベントでは機能しません。

get $ keyCodeは未定義です。トリックをした、私たちのイベントは、実際にKeyboardEventのあるものに

function __triggerKeyboardEvent(el, keyCode) 
{ 
    var eventObj = document.createEventObject ? 
     document.createEventObject() : document.createEvent("Events"); 

    var tempKeyboardObj = document.createEvent("KeyboardEvents"); 

    if(eventObj.initEvent){ 
     eventObj.initEvent("keydown", true, true); 
    } 
    eventObj.___dart_dispatch_record_ZxYxX_0_ = tempKeyboardObj.___dart_dispatch_record_ZxYxX_0_ 
    eventObj.keyCode = keyCode; 
    eventObj.which = keyCode; 

    el.dispatchEvent ? el.dispatchEvent(eventObj) : el.fireEvent("onkeydown", eventObj); 

} 

だましダートインターセプタ:

この上の時間のために私の頭を叩いた後、私は次のトリックを発見しました。

ここでは、WebkitベースのブラウザでDartアプリケーションをテストしようとしている貧しい人のために残しておきます。

3

上記の解決策もうまくいきました。また、@dlandのパラメータチップのおかげでうまくいきました。あなたが正しい場所でイベントを発射することができない場合は、私が有用と判断したものがあります。

@ Orwellophileのスクリプトは、ドキュメント上のイベントを発生させます。イベントリスナーが常にdocumentに登録されているとは限りません。私は最後の行を次の行に変更しましたが、今は毎回ほとんど機能しています。

document.activeElement.dispatchEvent(oEvent);

document.activeElementは、常にユーザーが現在注目している要素にイベントを発生させます。

+0

私は思いますあなたはSOのポイントを逃しています。提案がある場合は、解答のコメントに記入してください。変更があった場合は、コードを変更してください。あなたがこれらのことを行う権限を持っていない場合は、あなたの経験と一行の変更を「回答」として投稿してはいけません。 あなたの言うことは間違いありませんが、このコードはほぼ5年前に2012年にオンラインで多く参照されています。これを使用してコメントした人の量から、私はそれが動作することを知っています。 このエッジケースの変更を今行ったら、何ですか? – Orwellophile

関連する問題