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

lex*_*sss 9 javascript input keydown simulate

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

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

根据文档,它应该很简单.例如:

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);
Run Code Online (Sandbox Code Playgroud)

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

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

我将不胜感激这个问题的任何帮助.

Pau*_* S. 7

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

问:如何以编程方式输入?
答:获取/设置selectionStart,selectionEnd等,以及将这些与String方法结合使用,如slice插入字符.(参见HTMLTextAreaElement参考)

问:为什么你还会使用这种活动呢?
答:所有的事件监听器都会像真正的关键事件一样工作.


为箭头/ 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;
}
Run Code Online (Sandbox Code Playgroud)

问:哪里出错了?
答:如果线条足够长以便包裹,它会将它们视为未包装.