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

JavaScript : Simulate Key Events into Textbox/Input

本文关键字:文本 输入 模拟 事件 JavaScript      更新时间:2023-09-26

尽管SO上有很多关于如何在JS中模拟按键(keydown/keypress)的文章,但似乎没有一个解决方案适用于我使用的浏览器(Firefox ESR 17.0.7、Chrome 28.0.1500.72、IE 10)。我测试过的解决方案是从这里、这里和这里获得的。

我想做的是模拟文本区域/输入中的任意击键。虽然我可以直接添加/删除字符来更改"值",但我看不到任何选项,只能输入模拟键,如"向上"、"向下"、"主页"和其他一些键。

根据文件,它应该很简单。例如:

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

确实触发了"Enter"keydown事件,我的处理程序可以捕捉到它。但是,它不会以任何方式影响文本区域——不会出现新行。其他键代码也是如此:字符不会出现,箭头不会改变插入符号的位置,等等。

我已经扩展了Orwellophile的代码,并将其发布到http://jsfiddle.net/npF3d/4/,所以任何人都可以玩这个代码。在我的浏览器中,没有任何按钮在任何情况下都会对文本区域产生任何影响。

如果能在这个问题上提供任何帮助,我将不胜感激。

我很确定这是一件"安全"的事情,因为我以前在模拟按键时也遇到过同样的事情。

Q: 那我怎样才能用程序打字呢
A: 获取/设置selectionStartselectionEnd等,并将它们与sliceString方法结合使用以插入字符。(参见HTMLTextAreaElement参考)

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


因此可以减少箭头/主页/端的功能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: 哪里出了问题
A: 如果线条足够长,可以进行包裹,则会将其视为未包裹。

向浏览器发送密钥可以通过Selenium实现:http://docs.seleniumhq.org/

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

例如,您可以使用http://webdriver.io/