JavaScript : Simulate Key Events into Textbox/Input

拜拜、爱过 提交于 2019-12-04 10:49:41

问题


Despite many article on SO on how to simulate key presses (keydown/keypress) in JS, no one solution seems to be working with the browsers I'm using (Firefox ESR 17.0.7, Chrome 28.0.1500.72, IE 10). The solutions I have tested were taken from here, here, and here.

What I'm trying to do is to simulate ANY keystroke in a textarea / input. While I can append / delete characters directly changing "value", I see no option but input simulation for the keys like "Up", "Down", "Home", and some others.

According to the documentation, it should be simple. For example:

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);

indeed fires the "Enter" keydown event, and my handler can catch it. However, it does not affect the textarea in any way - a new line does not appear. Same for other key-codes: characters do not appear, arrows do not change the caret's location, etc.

I have extended the code by Orwellophile and posted it to http://jsfiddle.net/npF3d/4/ , so anyone can play with the code. In my browsers, no button produces any effect on the textarea in any condition.

I would appreciate any help on this issue.


回答1:


I'm pretty certain that this is a "security" thing, as I've run into the same thing when trying to simulate key presses before.

Q: How can I type programatically then?
A: Getting/setting selectionStart, selectionEnd, etc, as well as using these in combination with String methods like slice to insert characters. (See HTMLTextAreaElement reference)

Q: Why would you still use this kind of event then?
A: All of the event listeners will work as if it was a real key event.


Reduced functionality for arrows/home/end can be achieved thusly DEMO

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;
}

Q: Where does it go wrong?
A: If lines are long enough to be wrapped, it will treat them as if unwrapped.




回答2:


Sending keys to the browser can be achieved via Selenium: http://docs.seleniumhq.org/

It provides a driver for each browser that can be programmed. It usually starts with opening a URL then your script will act as a remote control to the browser. Thus allowing you to send actual keys rather than simulating them which is not possible programatically within the browser.

You could for instance achieve this using http://webdriver.io/



来源:https://stackoverflow.com/questions/17880821/javascript-simulate-key-events-into-textbox-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!