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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17880821/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:58:28  来源:igfitidea点击:

JavaScript : Simulate Key Events into Textbox/Input

javascriptinputkeydownsimulate

提问by lexasss

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.

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

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.

确实会触发“Enter”keydown 事件,我的处理程序可以捕获它。但是,它不会以任何方式影响 textarea - 不会出现新行。其他键码也一样:字符不会出现,箭头不会改变插入符号的位置等。

I have extended the code by Orwellophileand 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.

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

I would appreciate any help on this issue.

我将不胜感激在这个问题上的任何帮助。

采纳答案by Paul S.

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 Stringmethods like sliceto insert characters. (See HTMLTextAreaElementreference)

问:那我如何以编程方式输入?
A:获取/设置selectionStartselectionEnd等,以及将它们与String方法结合使用,例如slice插入字符。(请参阅HTMLTextAreaElement参考)

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.

Q:那你为什么还要用这种活动呢?
A:所有的事件监听器都会像真正的关键事件一样工作。



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

减少箭头/home/end 的功能因此可以实现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.

问:哪里出错了?
A:如果行足够长可以换行,它会将它们视为未换行。

回答by Yann VR

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

可以通过 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.

它为每个可以编程的浏览器提供了一个驱动程序。它通常从打开一个 URL 开始,然后您的脚本将充当浏览器的远程控制。因此,您可以发送实际的密钥,而不是模拟它们,而这在浏览器中以编程方式是不可能的。

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

例如,您可以使用http://webdriver.io/实现此目的