是否可以在JavaScript中以编程方式模拟按键事件?


当前回答

在某些情况下,按键事件不能提供所需的功能。从mozilla文档中我们可以看到该特性已被弃用:

不再推荐使用此特性。虽然一些浏览器可能仍然支持它,但它可能已经从相关的网络标准中删除了,可能正在被删除的过程中,或者可能只是为了兼容性的目的而保留。避免使用它,并尽可能更新现有代码;请参阅本页底部的兼容性表,以指导您的决定。请注意,此功能可能在任何时候停止工作。

因此,由于按键事件是由两个随后触发的事件keydown和接下来的同一个按键的keyup组合而成的,只需一个接一个地生成事件:

element.dispatchEvent(new KeyboardEvent('keydown',{'key':'Shift'}));
element.dispatchEvent(new KeyboardEvent('keyup',{'key':'Shift'}));

其他回答

只要用户按下有问题的键,你就可以存储对该even的引用,并将其用于任何HTML其他元素:

EnterKeyPressToEmulate<input class="lineEditInput" id="addr333_1" type="text" style="width:60%;right:0%;float:right" onkeydown="keyPressRecorder(event)"></input> TypeHereToEmulateKeyPress<input class="lineEditInput" id="addr333_2" type="text" style="width:60%;right:0%;float:right" onkeydown="triggerKeyPressOnNextSiblingFromWithinKeyPress(event)"> Itappears Here Too<input class="lineEditInput" id="addr333_3" type="text" style="width:60%;right:0%;float:right;" onkeydown="keyPressHandler(event)"> <script> var gZeroEvent; function keyPressRecorder(e) { gZeroEvent = e; } function triggerKeyPressOnNextSiblingFromWithinKeyPress(TTT) { if(typeof(gZeroEvent) != 'undefined') { TTT.currentTarget.nextElementSibling.dispatchEvent(gZeroEvent); keyPressHandler(TTT); } } function keyPressHandler(TTT) { if(typeof(gZeroEvent) != 'undefined') { TTT.currentTarget.value+= gZeroEvent.key; event.preventDefault(); event.stopPropagation(); } } </script>

如果你创建自己的事件,你可以设置keyCode,你可以从任何真实的键盘事件复制现有的参数(忽略目标,因为它的工作dispatchEvent)和:

ta = new KeyboardEvent('keypress',{ctrlKey:true,key:'Escape'})

一个非jquery版本,工作在webkit和gecko:

var keyboardEvent = document.createEvent('KeyboardEvent'); var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? 'initKeyboardEvent' : 'initKeyEvent'; keyboardEvent[initMethod]( 'keydown', // event type: keydown, keyup, keypress true, // bubbles true, // cancelable window, // view: should be window false, // ctrlKey false, // altKey false, // shiftKey false, // metaKey 40, // keyCode: unsigned long - the virtual key code, else 0 0, // charCode: unsigned long - the Unicode character associated with the depressed key, else 0 ); document.dispatchEvent(keyboardEvent);

您所能做的就是通过触发键事件以编程方式触发keyevent侦听器。从沙盒安全的角度来看,允许这样做是有意义的。使用此功能,您可以应用典型的观察者模式。您可以将此方法称为“模拟”。

下面是如何在W3C DOM标准和jQuery中实现这一点的示例:

function triggerClick() {
  var event = new MouseEvent('click', {
    'view': window,
    'bubbles': true,
    'cancelable': true
  });
  var cb = document.querySelector('input[type=submit][name=btnK]'); 
  var canceled = !cb.dispatchEvent(event);
  if (canceled) {
    // preventDefault was called and the event cancelled
  } else {
    // insert your event-logic here...
  }
}

此示例改编自:https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

jQuery:

jQuery('input[type=submit][name=btnK]')
  .trigger({
    type: 'keypress',
    which: character.charCodeAt(0 /*the key to trigger*/)      
   });

但是到目前为止,还没有[DOM]方法来触发离开浏览器沙箱的键事件。所有主要的浏览器供应商都将遵循这一安全概念。

至于Adobe Flash等基于NPAPI的插件,允许绕过沙盒:这些插件正在逐步淘汰;Firefox。

详细解释:

出于安全原因(正如Pekka已经指出的),您不能也不应该这样做。在两者之间总是需要用户交互。此外,想象一下浏览器供应商被用户起诉的可能性,因为各种编程键盘事件将导致欺骗攻击。

有关替代方案和更多细节,请参阅这篇文章。总是有基于flash的复制粘贴。这里有一个很好的例子。同时,它也证明了为什么网络正在远离插件供应商。

在选择加入CORS策略以编程方式访问远程内容的情况下,也应用了类似的安全思想。

答案是: 在正常情况下,在沙箱浏览器环境中无法以编程方式触发输入键。

底线:我并不是说在未来,在特殊的浏览器模式和/或游戏最终目标的特权下,这是不可能的,或类似的用户体验。然而,在进入这些模式之前,用户将被询问权限和风险,类似于全屏API模型。

有用:在KeyCodes上下文中,此工具和键码映射将派上用场。

披露:答案是基于这里的答案。

下面是一个在Chrome和Chromium上工作的解决方案(只测试了这些平台)。似乎Chrome有一些错误或自己的方法来处理关键代码,所以这个属性必须单独添加到KeyboardEvent。

函数simulateKeydown (keycode, istrl,isAlt,isShift){ var e = new KeyboardEvent("keydown",{冒泡泡:true, cancelable:true, char:String.fromCharCode(keycode), key:String.fromCharCode(keycode), shiftKey:isShift, ctrlKey:isCtrl, altKey:isAlt}); Object.defineProperty(e, 'keyCode', {get: function(){返回this.keyCodeVal;}}); e.keyCodeVal = keycode; document.dispatchEvent (e); } simulateKeydown(39, false, false, false);

只需使用CustomEvent

Node.prototype.fire=function(type,options){
     var event=new CustomEvent(type);
     for(var p in options){
         event[p]=options[p];
     }
     this.dispatchEvent(event);
}

4 ex想模拟ctrl+z

window.addEventListener("keyup",function(ev){
     if(ev.ctrlKey && ev.keyCode === 90) console.log(ev); // or do smth
     })

 document.fire("keyup",{ctrlKey:true,keyCode:90,bubbles:true})