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

Posted

技术标签:

【中文标题】JavaScript:将关键事件模拟​​到文本框/输入中【英文标题】:JavaScript : Simulate Key Events into Textbox/Input 【发布时间】:2013-07-26 16:36:35 【问题描述】:

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

我要做的是模拟文本区域/输入中的任何击键。虽然我可以附加/删除直接更改“值”的字符,但我看不到任何选项,只能输入模拟“上”、“下”、“主页”等键。

根据documentation,应该很简单。例如:

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

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

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

【问题讨论】:

【参考方案1】:

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

问:那我如何以编程方式输入? A: 获取/设置 selectionStartselectionEnd 等,以及将这些与 sliceString 方法结合使用来插入字符。 (参考htmlTextAreaElement

问:那你为什么还要使用这种活动呢? 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:如果行长到可以被换行,它会将它们视为未换行。

【讨论】:

好的,我也有同样的感觉,出于安全原因,可以故意这样做。截至Q/A:编辑文本不是问题,问题是模拟“Up”、“Down”、“Home”之类的...... 如果您将 textarea/input 重新创建为一个块节点,其中包含每个字符的内联节点,并具有匹配的换行、大小和样式,那么这些可能会被实现,然后计算所有不同的矩形以找到您的位置想要结束。我无法想象它很容易实现......也许更简洁的方法是使用等宽字体,计算出前一个换行符的位置,然后只计算字符数。 谢谢。但是,我模拟了第三页上的输入,例如 google.com。我的虚拟键盘是作为 Chrome 扩展程序实现的,并且必须能够允许用户仅使用此键盘在任何页面上的表单中键入和修改文本。如果必须删除某些功能,那将是非常令人失望的。 感谢这个解决方案,@Paul S,我也在考虑同样的问题,但你让我的任务变得更容易了。接下来,我将尝试更新您的解决方案,以便即使换行也能正常工作,但有一点希望。 解决方案很好,但我可以模拟打字吗?你能举个例子,比如在文本框中输入“abc”吗?非常感谢【参考方案2】:

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

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

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

【讨论】:

以上是关于JavaScript:将关键事件模拟​​到文本框/输入中的主要内容,如果未能解决你的问题,请参考以下文章

单击文本框时会触发哪个 javascript 事件?

如何在codebehind的pageload事件被触发之前,在页面加载时将一个会话存储值传递到文本框中?

通过 onchange 事件将 SELECT 的值传递给 Javascript 函数?

Javascript中,当鼠标点击选中某个文本输入框时,该文本框可以响应啥事件

Javascript在选择时将值生成到表单文本框中

通过另外一个应用程序给多个文本框赋值, 模拟单击事件