如何使用 JavaScript 模拟按键或点击?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4158847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 11:09:28  来源:igfitidea点击:

How to simulate key presses or a click with JavaScript?

javascriptgoogle-chromegoogle-chrome-extension

提问by milan

I wrote a Google Chrome extension and the site that I want to use my extension on requires me to click or tab onto a text box (because I think it runs javaScript verification "onClick" only). I can get the text in the box with my extension using:

我写了一个谷歌浏览器扩展程序,我想使用我的扩展程序的站点要求我单击或选择文本框(因为我认为它只运行 javaScript 验证“onClick”)。我可以使用扩展名获取框中的文本:

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

But when I click submit, it thinks I did not enter anything in the "input1" text box because I never clicked it or tabbed on it.

但是当我点击提交时,它认为我没有在“input1”文本框中输入任何内容,因为我从来没有点击过它或在它上面打过标签。

Can someone help me get around this?

有人可以帮我解决这个问题吗?

回答by yonran

Simulating a mouse click

模拟鼠标点击

My guess is that the webpage is listening to mousedown rather than click (which is bad for accessibility because when a user uses the keyboard, only focus and click are fired, not mousedown). So you should simulate mousedown, click, and mouseup (which, by the way, is what the iPhone, iPod Touch, and iPad do on tap events).

我的猜测是该网页正在侦听 mousedown 而不是 click (这对可访问性不利,因为当用户使用键盘时,只会触发焦点和点击,而不是 mousedown )。所以你应该模拟 mousedown、click 和 mouseup(顺便说一下,这就是 iPhone、iPod Touch 和 iPad 在点击事件上所做的)。

To simulate the mouse events, you can use this snippet for browsers that support DOM 2 Events. For a more foolproof simulation, fill in the mouse position using initMouseEventinstead.

要模拟鼠标事件,您可以将此代码段用于支持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);

When you fire a simulated click event, the browser will actually fire the default action (e.g. navigate to the link's href, or submit a form).

当您触发模拟点击事件时,浏览器实际上会触发默认操作(例如导航到链接的 href,或提交表单)。

In IE, the equivalent snippet is this (unverified since I don't have IE). I don't think you can give the event handler mouse positions.

在 IE 中,等效的代码段是这样的(由于我没有 IE,因此未经验证)。我不认为你可以给事件处理程序鼠标位置。

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

Simulating keydown and keypress

模拟按键和按键

You can simulate keydown and keypress events, but unfortunately in Chrome they only fire the event handlers and don't perform any of the default actions. I think this is because the DOM 3 Events working draft describes this funky order of key events:

您可以模拟 keydown 和 keypress 事件,但不幸的是,在 Chrome 中,它们只触发事件处理程序,不执行任何默认操作。我认为这是因为 DOM 3 Events 工作草案描述了关键事件的这种时髦顺序

  1. keydown (often has default action such as fire click, submit, or textInput events)
  2. keypress (if the key isn't just a modifier key like Shift or Ctrl)
  3. (keydown, keypress) with repeat=true if the user holds down the button
  4. default actions of keydown!!
  5. keyup
  1. keydown(通常具有默认操作,例如触发点击、提交或 textInput 事件)
  2. 按键(如果该键不仅仅是 Shift 或 Ctrl 等修饰键)
  3. (keydown, keypress) with repeat=true 如果用户按住按钮
  4. keydown 的默认操作!!
  5. 按键

This means that you have to (while combing the HTML5and DOM 3 Eventsdrafts) simulate a large amount of what the browser would otherwise do. I hate it when I have to do that. For example, this is roughly how to simulate a key press on an input or textarea.

这意味着您必须(在结合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, '');

I don't think it is possible to simulate key events in IE.

我认为在 IE 中模拟关键事件是不可能的。

回答by Russ Cam

you can raise the click event on an element by doing

您可以通过执行以下操作来引发元素上的点击事件

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

if (element) element.click();

Example here

示例在这里

回答by chbrown

Or even shorter, with only standard modern Javascript:

或者更短,只有标准的现代 Javascript:

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

The new MouseEventconstructor takes a required event type name, then an optional object (at least in Chrome). So you could, for example, set some properties of the event:

所述new MouseEvent构造函数采用一个所需事件类型名称,然后可选对象(至少在Chrome)。例如,您可以设置事件的一些属性:

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

回答by tanushree

For simulating keyboard events in Chrome:

在 Chrome 中模拟键盘事件:

There is a related bug in webkit that keyboard events when initialized with initKeyboardEvent get an incorrect keyCode and charCode of 0: https://bugs.webkit.org/show_bug.cgi?id=16735

webkit 中存在一个相关错误,即使用 initKeyboardEvent 初始化时键盘事件会得到不正确的 keyCode 和 charCode 为 0:https://bugs.webkit.org/show_bug.cgi?id=16735

A working solution for it is posted in this SO answer.

这个 SO answer 中发布了一个可行的解决方案。

回答by Mark Baijens

Focus might be what your looking for. With tabbing or clicking I think u mean giving the element the focus. Same code as Russ (Sorry i stole it :P) but firing an other event.

焦点可能是您要寻找的。通过 Tab 键或单击,我认为您的意思是将焦点放在元素上。与 Russ 相同的代码(对不起,我偷了它:P)但触发了另一个事件。

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

if (element) element.focus();