当前位置:  开发笔记 > 编程语言 > 正文

是否可以通过编程方式模拟按键事件?

如何解决《是否可以通过编程方式模拟按键事件?》经验,为你挑选了11个好方法。

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



1> Philip Nuzhn..:

一个非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);


`keyCode`始终为0,我无法更改它.
看来Chromium中存在一个错误,当使用`document.createEvent("KeyboardEvent")时,会导致`event.which`始终为'0`.@lluft在这个[评论](http://stackoverflow.com/questions/961532/firing-a-keyboard-event-in-javascript#comment-44022523)上分享了详细信息和解决方法,这对我有用.不同的线程.基本上,你需要使用`document.createEvent('Event')`来创建一个通用事件,然后将类型设置为`keydown`并给出一个等于key的charcode的`keyCode`属性.
Philip,这看起来像我需要的代码,但我需要将keypress事件发送到textarea.我试图修改你的代码发送到textarea,但它似乎没有工作,至少铬,任何想法可能是错的?这是我演示的jsfiddle:http://jsfiddle.net/szmJu/
现在似乎已删除此功能.不过,MDN已经考虑过它已经弃用了很长一段时间.
事实证明Chromium中存在一个带有KeyboardEvent调度的错误.有关更多详细信息,请查看此主题:http://stackoverflow.com/questions/10455626/keydown-simulation-in-chrome-fires-normally-but-not-the-correct-key/12522769#12522769.
注意:MDN上的KeyboardEvent.initKeyboardEvent()的上述链接是错误的.正确的链接:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/initKeyboardEvent

2> alex2k8..:

如果你可以使用jQuery 1.3.1:

function simulateKeyPress(character) {
  jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });
}

$(function() {
  $('body').keypress(function(e) {
    alert(e.which);
  });

  simulateKeyPress("e");
});


它在Chrome中无法正常运行,抱歉.jQuery创建了Event,但是没有重要的属性 - charCode,keyCode.
@tan这是不可能的.请参阅我的答案,了解其背后的原因.
请注意,“触发” [无法用于模仿本机浏览器事件](http://stackoverflow.com/questions/32428993/why-doesnt-simulating-a-tab-keypress-change-focus-of-input-字段)。

3> Lorenz Lo Sa..:

你可以做的是通过触发keyevents以编程方式触发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]方法实际触发离开浏览器沙箱的关键事件.所有主要的浏览器供应商都将遵循这一安全概念.

对于基于NPAPI的Adobe Flash等插件,允许绕过沙箱:这些都是逐步淘汰的 ; 火狐.

详细说明:

你不能也不能出于安全原因(正如Pekka已经指出的那样).您将始终需要用户之间的互动.此外,想象一下浏览器供应商被用户起诉的可能性,因为各种程序化键盘事件将导致欺骗攻击.

有关替代品和更多详细信息,请参阅此帖 总有基于闪存的复制粘贴.这是一个优雅的 例子.与此同时,它证明了为什么网络正在远离插件供应商.

如果选择加入CORS策略以编程方式访问远程内容,则应用类似的安全思维模式.

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

底线:我并不是说将来,在特殊的浏览器模式和/或特权用于游戏的最终目标或类似的用户体验下,它是不可能的.但是,在进入此类模式之前,将要求用户提供权限和风险,类似于Fullscreen API模型.

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

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



4> aljgom..:

您可以在像这样的元素上调度键盘事件

element.dispatchEvent(new KeyboardEvent('keypress',{'key':'a'}));


我认为答案应该提到在js事件中调度的事实不会更新输入内容.
最新的Firefox不是现代的吗?

5> Plutor..:

你可以使用dispatchEvent():

function simulateKeyPress() {
  var evt = document.createEvent("KeyboardEvent");
  evt.initKeyboardEvent("keypress", true, true, window,
                    0, 0, 0, 0,
                    0, "e".charCodeAt(0))
  var body = document.body;
  var canceled = !body.dispatchEvent(evt);
  if(canceled) {
    // A handler called preventDefault
    alert("canceled");
  } else {
    // None of the handlers called preventDefault
    alert("not canceled");
  }
}

我没有对此进行测试,但它是根据dispatchEvent()文档中的代码改编的.您可能想要阅读它,以及createEvent()和initKeyEvent()的文档.


注意:仅Gecko浏览器支持此功能.

6> Alex Burtsev..:

您可以创建和分派键盘事件,它们将触发相应的已注册事件处理程序,但是如果调度到输入元素,它们将不会生成任何文本.

要完全模拟文本输入,您需要生成一系列键盘事件,并显式设置input元素的文本.事件序列取决于您想要模拟文本输入的彻底程度.

最简单的形式是:

$('input').val('123');
$('input').change();



7> Timo Tijhof..:

基于alex2k8的答案,这是一个修订版本,适用于jQuery支持的所有浏览器(问题在于缺少jQuery.event.trigger的参数,在使用该内部函数时很容易忘记).

// jQuery plugin. Called on a jQuery object, not directly.
jQuery.fn.simulateKeyPress = function (character) {
  // Internally calls jQuery.event.trigger with arguments (Event, data, elem).
  // That last argument, 'elem', is very important!
  jQuery(this).trigger({ type: 'keypress', which: character.charCodeAt(0) });
};

jQuery(function ($) {
  // Bind event handler
  $('body').keypress(function (e) {
    alert(String.fromCharCode(e.which));
    console.log(e);
  });
  // Simulate the key press
  $('body').simulateKeyPress('x');
});

你甚至可以进一步推动它,让它不仅模拟事件,而且实际插入角色(如果它是一个输入元素),但是在尝试这样做时有许多跨浏览器的问题.更好地使用像SendKeys这样更精细的插件.


不模拟硬件按键,只需调用binded按键功能.

8> Малъ Скрылев..:

在某些情况下,keypress事件无法提供所需的功能,通常情况下,事件是由两个因此触发的事件组合而来的keypress,并且后面的事件是keydown相同的键.所以只需逐个生成事件:

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



9> 小智..:

对于那些感兴趣的人,您可以实际上可靠地重新创建键盘输入事件.为了更改输入区域中的文本(移动游标,或通过输入字符移动页面),您必须密切关注DOM事件模型:http://www.w3.org/TR/DOM-Level-3-Events/ #h4_events-inputevents

该模型应该:

focus(在具有目标集的DOM上调度)

然后为每个角色:

keydown(在DOM上发送)

beforeinput(如果是textarea或输入,则在目标处调度)

keypress(在DOM上发送)

输入(如果是textarea或输入,则在目标处调度)

更改(如果选择,则在目标处调度)

keyup(在DOM上调度)

然后,可选择大多数:

模糊(使用目标集在DOM上调度)

这实际上通过javascript更改页面中的文本(不修改值语句)并适当地设置任何javascript侦听器/处理程序.如果你弄乱了序列javascript将不会以适当的顺序触发,输入框中的文本将不会改变,选择不会改变或光标不会移动到文本区域中的下一个空格.

不幸的是,代码是根据NDA为雇主编写的,因此我无法共享它,但它绝对可以,但您必须以正确的顺序为每个元素重新创建整个键输入"堆栈".


适用于JavaScript的NDA?真?,无论如何,对于你的算法错误的每个角色,模拟"输入"事件无论如何添加文本而不经历整个keydown,keyup事件或任何其他事件.问题是如何处理多个按键事件等,如按下"a"按钮并多次期待"aaaaaaa".
我试过这个但它似乎没有完全起作用:我可以触发Enter,Backspace或箭头键的事件,但不能触发字符.例如,虽然我密切关注您的事件顺序,但我无法通过此方法输入文本.

10> Ata Iravani..:

这种方法支持跨浏览器更改密钥代码的值. 资源

var $textBox = $("#myTextBox");

var press = jQuery.Event("keypress");
press.altGraphKey = false;
press.altKey = false;
press.bubbles = true;
press.cancelBubble = false;
press.cancelable = true;
press.charCode = 13;
press.clipboardData = undefined;
press.ctrlKey = false;
press.currentTarget = $textBox[0];
press.defaultPrevented = false;
press.detail = 0;
press.eventPhase = 2;
press.keyCode = 13;
press.keyIdentifier = "";
press.keyLocation = 0;
press.layerX = 0;
press.layerY = 0;
press.metaKey = false;
press.pageX = 0;
press.pageY = 0;
press.returnValue = true;
press.shiftKey = false;
press.srcElement = $textBox[0];
press.target = $textBox[0];
press.type = "keypress";
press.view = Window;
press.which = 13;

$textBox.trigger(press);



11> bortunac..:

只需使用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})

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有