web-dev-qa-db-ja.com

JavaScriptを使用してキーの押下やクリックをシミュレートする方法は?

Google Chrome拡張機能を作成しました。拡張機能を使用するサイトでは、テキストボックスをクリックまたはタブ移動する必要があります(javaScript検証 "onClick"のみを実行するため)。私は私の拡張機能を使用してボックス内のテキストを取得できます:

document.getElementById("input1").value = 'test';

ただし、[送信]をクリックすると、「input1」テキストボックスには何も入力しなかったと見なされます。これは、クリックもタブ入力も行わなかったためです。

誰かがこれを回避するのを手伝ってもらえますか?

38
milan

マウスクリックのシミュレーション

私の推測では、Webページはクリックではなくマウスダウンをリッスンしていると考えられます(ユーザーがキーボードを使用すると、マウスダウンではなく、フォーカスとクリックのみが発生するため、アクセシビリティに悪影響を及ぼす)。したがって、マウスダウン、クリック、およびマウスアップをシミュレートする必要があります(ところで、これは タップイベントでiPhone、iPod Touch、およびiPadが行うこと )。

マウスイベントをシミュレートするには、 DOM 2 Events をサポートするブラウザーにこのスニペットを使用できます。より確実なシミュレーションを行うには、代わりにinitMouseEventを使用してマウスの位置を入力します。

// DOM 2 Events
var dispatchMouseEvent = function(target, var_args) {
  var e = document.createEvent("MouseEvents");
  // If you need clientX, clientY, etc., you can call
  // initMouseEvent instead of initEvent
  e.initEvent.apply(e, Array.prototype.slice.call(arguments, 1));
  target.dispatchEvent(e);
};
dispatchMouseEvent(element, 'mouseover', true, true);
dispatchMouseEvent(element, 'mousedown', true, true);
dispatchMouseEvent(element, 'click', true, true);
dispatchMouseEvent(element, 'mouseup', true, true);

シミュレートされたクリックイベントを発生させると、ブラウザは実際にデフォルトアクションを発生させます(たとえば、リンクのhrefに移動するか、フォームを送信します)。

IEでは、同等のスニペットはこれです(私にはIEがないので未確認です)。イベントハンドラーにマウスの位置を与えることができるとは思わない。

// IE 5.5+
element.fireEvent("onmouseover");
element.fireEvent("onmousedown");
element.fireEvent("onclick");  // or element.click()
element.fireEvent("onmouseup");

キーダウンとキー押下のシミュレーション

Keydownイベントとkeypressイベントをシミュレートできますが、残念ながらChromeでイベントハンドラーを起動するだけで、デフォルトのアクションは実行されません。これは、DOM 3 Eventsワーキングドラフトがこのファンキー キーイベントの順序

  1. keydown(多くの場合、fire click、submit、textInputイベントなどのデフォルトアクションがあります)
  2. キーを押す(キーがShiftやCtrlなどの修飾キーではない場合)
  3. (キーダウン、キー押下)ユーザーがボタンを押した場合にrepeat = trueを使用
  4. キーダウンのデフォルトのアクション!!
  5. キーアップ

これは、( HTML5DOM 3 Events ドラフトを組み合わせながら)ブラウザーがそうしない場合の大量の動作をシミュレートする必要があることを意味します。私はそれをしなければならないときにそれを嫌います。たとえば、これは入力またはテキスト領域でのキーの押下をシミュレートするおおよその方法です。

// DOM 3 Events
var dispatchKeyboardEvent = function(target, initKeyboradEvent_args) {
  var e = document.createEvent("KeyboardEvents");
  e.initKeyboardEvent.apply(e, Array.prototype.slice.call(arguments, 1));
  target.dispatchEvent(e);
};
var dispatchTextEvent = function(target, initTextEvent_args) {
  var e = document.createEvent("TextEvent");
  e.initTextEvent.apply(e, Array.prototype.slice.call(arguments, 1));
  target.dispatchEvent(e);
};
var dispatchSimpleEvent = function(target, type, canBubble, cancelable) {
  var e = document.createEvent("Event");
  e.initEvent.apply(e, Array.prototype.slice.call(arguments, 1));
  target.dispatchEvent(e);
};

var canceled = !dispatchKeyboardEvent(element,
    'keydown', true, true,  // type, bubbles, cancelable
    null,  // window
    'h',  // key
    0, // location: 0=standard, 1=left, 2=right, 3=numpad, 4=mobile, 5=joystick
    '');  // space-sparated Shift, Control, Alt, etc.
dispatchKeyboardEvent(
    element, 'keypress', true, true, null, 'h', 0, '');
if (!canceled) {
  if (dispatchTextEvent(element, 'textInput', true, true, null, 'h', 0)) {
    element.value += 'h';
    dispatchSimpleEvent(element, 'input', false, false);
    // not supported in Chrome yet
    // if (element.form) element.form.dispatchFormInput();
    dispatchSimpleEvent(element, 'change', false, false);
    // not supported in Chrome yet
    // if (element.form) element.form.dispatchFormChange();
  }
}
dispatchKeyboardEvent(
    element, 'keyup', true, true, null, 'h', 0, '');

IEで重要なイベントをシミュレートすることは不可能だと思います。

75
yonran

あなたはすることで要素のクリックイベントを発生させることができます

// this must be done after input1 exists in the DOM
var element = document.getElementById("input1");

if (element) element.click();

ここの例

9
Russ Cam

またはさらに短く、標準的な最新のJavascriptのみを使用します。

var first_link = document.getElementsByTagName('a')[0];
first_link.dispatchEvent(new MouseEvent('click'));

new MouseEventコンストラクターは、必須のイベントタイプ名を受け取り、オプションのオブジェクト(少なくともChromeでは)を受け取ります。したがって、たとえば、イベントのいくつかのプロパティを設定できます。

first_link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true}));
7
chbrown

Chromeでキーボードイベントをシミュレートするには:

Webkitには、initKeyboardEventで初期化されたときにキーボードイベントが0の不正なkeyCodeとcharCodeを取得するという関連バグがあります。 https://bugs.webkit.org/show_bug.cgi?id=16735

そのための有効なソリューションは this SO answer に投稿されています。

5
tanushree

焦点はあなたが探しているものかもしれません。タブまたはクリックすると、要素にフォーカスを与えることを意味すると思います。 Russと同じコード(申し訳ありませんが盗んだ:P)が、他のイベントを発生させます。

// this must be done after input1 exists in the DOM
var element = document.getElementById("input1");

if (element) element.focus();
0
Mark Baijens