JavaScript: имитация ключевых событий в текстовое поле / ввод


Несмотря на множество статей о том, как имитировать нажатия клавиш (keydown/keypress) в JS, ни одно решение, кажется, не работает с браузерами, которые я использую (Firefox ESR 17.0.7, Chrome 28.0.1500.72, IE 10). Решения, которые я проверил, были взяты из здесь, здесь , и здесь.

То, что я пытаюсь сделать, - это имитировать любое нажатие клавиши в textarea / input. Хотя я могу добавлять / удалять символы, непосредственно изменяя "значение", я не вижу другого варианта, кроме моделирования ввода для клавиши типа "вверх", "вниз", "домой" и некоторые другие.

Согласно документации , это должно быть просто. Например:

var e = document.createEvent("KeyboardEvent");
if (e.initKeyboardEvent) {  // Chrome, IE
    e.initKeyboardEvent("keydown", true, true, document.defaultView, "Enter", 0, "", false, "");
} else { // FF
    e.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, 13, 0);
}
document.getElementById("text").dispatchEvent(e);

Действительно запускает событие keydown" Enter", и мой обработчик может его поймать. Однако это никак не влияет на текстовую область-новая строка не появляется. То же самое и для других ключевых кодов: символы не появляются, стрелки не меняют расположение каретки и т. д.

Я расширил код на Orwellophile и отправил его в http://jsfiddle.net/npF3d/4/, так что любой может играть с кодом. В моих браузерах ни одна кнопка не производит никакого эффекта на текстовую область в любом состоянии.

Я был бы признателен за любую помощь в этом вопросе.
2 7

2 ответа:

Я почти уверен, что это "безопасность", так как я сталкивался с тем же самым, когда пытался имитировать нажатия клавиш раньше.

Q: Как я могу печатать программно?
A: получение / настройка selectionStart, selectionEnd и т.д., а также использовать их в сочетании с String методами, такими как slice для вставки символов. (См. HTMLTextAreaElement Ссылка)

В: Тогда почему вы все еще используете такого рода события?
А: Все слушатели события будут работать так, как если бы это было настоящее ключевое событие.


Таким образом можно добиться снижения функциональности для стрелок / home / end демо-версия

function homeKey(elm) {
    elm.selectionEnd =
        elm.selectionStart =
            elm.value.lastIndexOf(
                '\n',
                elm.selectionEnd - 1
            ) + 1;
}

function endKey(elm) {
    var pos = elm.selectionEnd,
        i = elm.value.indexOf('\n', pos);
    if (i === -1) i = elm.value.length;
    elm.selectionStart = elm.selectionEnd = i;
}

function arrowLeft(elm) {
    elm.selectionStart = elm.selectionEnd -= 1;
}

function arrowRight(elm) {
    elm.selectionStart = elm.selectionEnd += 1;
}

function arrowDown(elm) {
    var pos = elm.selectionEnd,
        prevLine = elm.value.lastIndexOf('\n', pos),
        nextLine = elm.value.indexOf('\n', pos + 1);
    if (nextLine === -1) return;
    pos = pos - prevLine;
    elm.selectionStart = elm.selectionEnd = nextLine + pos;
}

function arrowUp(elm) {
    var pos = elm.selectionEnd,
        prevLine = elm.value.lastIndexOf('\n', pos),
        TwoBLine = elm.value.lastIndexOf('\n', prevLine - 1);
    if (prevLine === -1) return;
    pos = pos - prevLine;
    elm.selectionStart = elm.selectionEnd = TwoBLine + pos;
}

Вопрос: Где же все идет не так?
A: если линии достаточно длинные, чтобы быть завернутыми, он будет относиться к ним как к развернутым.

Отправка ключей в браузер может быть достигнута с помощью Selenium: http://docs.seleniumhq.org/

Он предоставляет драйвер для каждого браузера, который может быть запрограммирован. Обычно он начинается с открытия URL-адреса, после чего ваш скрипт будет действовать как пульт дистанционного управления браузером. Таким образом, вы можете отправлять реальные ключи, а не имитировать их, что невозможно программно в браузере.

Вы могли бы, например, достичь этого, используя http://webdriver.io/