Как имитировать нажатия клавиш или щелчок с помощью JavaScript?

Я написал расширение Google Chrome и сайт, на котором я хочу использовать расширение, требует, чтобы я щелкнул или вложил в текстовое поле (потому что я думаю, что он запускает проверку Java-скрипта "onClick" ). Я могу получить текст в поле с моим расширением, используя:

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

Но когда я нажимаю кнопку "Отправить", он думает, что я ничего не вводил в текстовое поле "input1", потому что я никогда не щелкал его или не накладывал на него.

Может кто-нибудь помочь мне обойти это?

Ответ 1

Имитация щелчка мыши

Я предполагаю, что веб-страница прослушивает mousedown, а не клик (что плохо для доступности, потому что, когда пользователь использует клавиатуру, стреляют только фокус и клик, а не mousedown). Таким образом, вы должны моделировать mousedown, click и mouseup (что, кстати, то, что делают 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 описывает этот фанковый порядок ключевых событий:

  • keydown (часто имеет действие по умолчанию, такое как событие "щелкнуть по щелчку", "отправить" или "textInput" ).
  • keypress (если ключ не является только ключом модификатора, например Shift или Ctrl)
  • (keydown, keypress) с repeat = true, если пользователь удерживает кнопку
  • действия по умолчанию keydown!
  • KeyUp

Это означает, что вам нужно (при расчесывании HTML5 и DOM 3 события) имитируют большое количество того, что в противном случае сделал бы браузер. Я ненавижу это, когда я должен это делать. Например, это примерно то, как имитировать нажатие клавиши на входе или в текстовом поле.

// 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.

Ответ 2

вы можете поднять событие click на элементе, выполнив

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

if (element) element.click();

Пример здесь

Ответ 3

Или даже короче, только с стандартным современным 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}));

Ответ 4

Для моделирования событий клавиатуры в Chrome:

В webkit есть связанная ошибка, при которой события клавиатуры при инициализации initKeyboardEvent получает неверный keyCode и charCode 0: https://bugs.webkit.org/show_bug.cgi?id=16735

Рабочее решение для него опубликовано в этом SO-ответе.

Ответ 5

Фокус может быть тем, что вы ищете. С табулированием или щелчком я думаю, что у означает дать элементу фокус. Тот же код, что и Russ (Извините, я украл его: P), но уволил другое событие.

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

if (element) element.focus();