JavaScript:将关键事件模拟​​到文本框/输入中

JavaScript:将关键事件模拟​​到文本框/输入中

问题描述:

尽管在JS上有很多关于如何模拟按键(keydown / keypress)的文章,但似乎没有一个解决方案可以使用我正在使用的浏览器(Firefox ESR 17.0.7,Chrome 28.0.1500.72,IE 10) )。我测试的解决方案来自此处 here 此处

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.

我要做的是模拟textarea / input中的任何击键。虽然我可以追加/删除直接更改值的字符,但我看不到选项,只能输入Up,Down,Home等键的模拟。

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

确实触发了Enterkeydown事件,我的处理程序可以捕获它。但是,它不会以任何方式影响textarea - 不会出现新行。其他键码相同:不显示字符,箭头不会更改插入符号的位置等。

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.

我已将代码扩展为 Orwellophile 并将其发布到 http:/ /jsfiddle.net/npF3d/4/ ,所以任何人都可以使用代码。在我的浏览器中,在任何情况下都没有按钮对textarea产生任何影响。

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.

我我很确定这是一个安全的事情,因为我在尝试模拟按键之前遇到了同样的事情。

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.

问:我怎么能然后以编程方式输入?

A:获取/设置 selectionStart selectionEnd 等,以及将它们与 String结合使用 slice 这样的方法来插入字符。 (参见 HTMLTextAreaElement 参考)

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.

因此可以实现箭头/ home / end的减少功能 DEMO

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

问:哪里出错?

A :如果线条足够长以便包裹,它会将它们视为未包装。

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