9

尽管有很多关于如何在 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 事件,我的处理程序可以捕捉到它。但是,它不会以任何方式影响 textarea - 不会出现新行。其他键码也一样:字符不出现,箭头不改变插入符号的位置等。

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

我将不胜感激有关此问题的任何帮助。

4

2 回答 2

7

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

问:那我怎样才能以编程方式输入呢?
A:获取/设置selectionStartselectionEnd等,以及将它们与插入字符等String方法结合使用。slice(参见HTMLTextAreaElement参考)

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


因此可以实现箭头/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;
}

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

于 2013-07-26T12:28:44.657 回答
2

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

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

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

于 2017-07-10T21:35:51.387 回答