Как смоделировать нажатия клавиш или клик с помощью JavaScript? - PullRequest
38 голосов
/ 11 ноября 2010

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

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

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

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

Ответы [ 5 ]

75 голосов
/ 14 ноября 2010

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

Я предполагаю, что веб-страница слушает mousedown, а не щелчок (что плохо для доступности, потому что когда пользователь использует клавиатуру, только фокус и щелчок запускаются, а не mousedown). Таким образом, вы должны имитировать mousedown, click и mouseup (что, кстати, , что iPhone, iPod Touch и iPad делают при событиях касания ).

Для имитации событий мыши вы можете использовать этот фрагмент для браузеров, которые поддерживают События DOM 2 . Для более надежной симуляции заполните позицию мыши, используя 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);

Когда вы запускаете событие имитации клика, браузер фактически запускает действие по умолчанию (например, перейдите к ссылке на ссылку или отправьте форму).

В IE эквивалентный фрагмент этого (непроверенный, так как у меня нет IE). Я не думаю, что вы можете указывать позиции мыши обработчика событий.

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

Имитация нажатия клавиш и нажатия клавиш

Вы можете имитировать события нажатия клавиш и нажатия клавиш, но, к сожалению, в Chrome они только запускают обработчики событий и не выполняют никаких действий по умолчанию. Я думаю, это связано с тем, что рабочий проект DOM 3 Events описывает этот фанковый порядок ключевых событий :

  1. нажатие клавиши (часто имеет действие по умолчанию, например, щелчок, отправка или события textInput)
  2. нажатие клавиши (если клавиша не просто клавиша-модификатор, такая как Shift или Ctrl)
  3. (нажатие клавиши, нажатие клавиши) с repeat = true, если пользователь удерживает нажатой кнопку
  4. действия по умолчанию при нажатии клавиш !!
  5. 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 можно моделировать ключевые события.

9 голосов
/ 11 ноября 2010

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

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

if (element) element.click();

Пример здесь

7 голосов
/ 17 января 2014

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

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

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

Работающийрешение для этого отправлено в этот SO ответ .

0 голосов
/ 11 ноября 2010

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

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

if (element) element.focus();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...