首页 新闻 会员 周边

js 模拟键盘输入过程

0
悬赏园豆:50 [已解决问题] 解决于 2015-08-06 08:20

js 模拟键盘输入,能行不?
不是通过赋值 innerTest = "xxx",而是模拟实实在在的键盘输入过程

 

是不是要用到document.createEvent之类的。

 

(PS:我的场景是在WPF中的webbrowser中自动帮用户输入,但是用户要登陆的网站好像要捕捉到键盘输入才行,直接用innerTest = "xxx"或value="xxx"无法提交)

Ace8793的主页 Ace8793 | 初学一级 | 园豆:7
提问于:2015-08-05 09:21
< >
分享
最佳答案
2

你理解没错,是可以通过DOM创建本地事件来模拟一些用户的操作的,例如鼠标和按键 .

基本的用法就是:

//+ 返回一个键盘事件对象
var keyEventObject = document.createEvent("event_type_name");

//+ 初始化对象参数
keyEventObject.initKeyEvent( ..... 一系列参数 ..... )

//-> ps: 某些浏览器可能不支持initKeyEvent这种情况改用initKeyboardEvent

//+ 释放
document.dispatchEvent( keyEventObject );

 

某些主流库也支持鼠标和键盘的模拟,例如:jquery , yui,这是以前收藏的一段jquery的模拟键盘的代码,from  stackoverflow,自己也可以根据相关关键字搜索下应该可以得到不少有参考价值的东西的

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

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

  simulateKeyPress("e");
});

 

 

收获园豆:50
visonme | 小虾三级 |园豆:1674 | 2015-08-05 09:48

以上是基于js的,所以你必须让你的wpf-wb执行该js代码

如果是基于wPf模拟的那可以使用系统键盘操作相关API实现

visonme | 园豆:1674 (小虾三级) | 2015-08-05 09:52

如何调用?直接使用simulateKeyPress("e");?这样好像没效果

比如我想给email这个input输入字符 要怎么办?var i=document.getElementById('email');

Ace8793 | 园豆:7 (初学一级) | 2015-08-05 10:28

@visonme: WPF的sendKeys无法使用,winform中可以的

 

另外如何调用这段js

直接使用simulateKeyPress("e");?这样好像没效果

比如我想给email这个input输入字符 要怎么办?var i=document.getElementById('email');

Ace8793 | 园豆:7 (初学一级) | 2015-08-05 10:35

@Ace8793:  

首先我上面那段jquery的代码是比较早版本的,所以只做参考,这里帮你找了链接里面有demo你可以参考下:(注意下jquery版本)

http://stackoverflow.com/questions/3276794/jquery-or-pure-js-simulate-enter-key-pressed-for-testing

 

这是yui的模拟 鼠标键盘的一篇文章

http://yuilibrary.com/yui/docs/event/simulate.html

 

///+ 如果以上还不能很好的解决你的问题,你可以查看下jquery关联处理的代码,这是最直接的

///+ 以上给出的链接和code,我没有测试,所以不能确定能正常工作,如果还存在问题,可以@我,我会写个测试demo给你参考下

visonme | 园豆:1674 (小虾三级) | 2015-08-05 10:38

@Ace8793: 

sendkeys不能操作的话,考虑使用下面API组合

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
internal static extern int GetSystemMetrics(int int_0);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int MapVirtualKey(int int_0, int int_1);
[DllImport("user32.dll", SetLastError = true)]
internal static extern int SendInput(int int_0, ref Class6.Struct0 struct0_0, int int_1);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern short VkKeyScan(char char_0);    

 下面是我一个WPF project中的一段代码

        private static void sKeyBoardPress(Key keyc)
        {
            PermissionSet permissionSet = new PermissionSet(PermissionState.Unrestricted);
            permissionSet.Demand();

            //初始化sendInput需要的结构体
            INPUT sKeyInputStruct = //
            ==> 这里省略不知道多少字,主要就是实现结构体的初始化,按需
            ==> 这里需要注意的keyc 键值的映射转换使用到MapVirtualKey
            ==> 相关知识就百度或者上msdn查下吧,资料都是很多的
            //
           
            if (NativeKeyboard.SendInput(1, ref sKeyInputStruct, Marshal.SizeOf(sKeyInputStruct)) == 0)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
        }
visonme | 园豆:1674 (小虾三级) | 2015-08-05 10:48

@visonme: 首先感谢回答,然后还是我的继续问题吧,嘿嘿

在wpf中我添加了webbrowser控件,

<WebBrowser x:Name="wb"></WebBrowser>

 

然后添加了一个按钮并在按钮的clicked事件中用如下的方式注入js(经验证没问题)。现在问题是如何在JS中引用yui之类的库呢

后台代码如下

 mshtml.HTMLDocument htmlDoc = wb.Document as mshtml.HTMLDocument;
            var head = htmlDoc.getElementsByTagName("head").Cast<HTMLHeadElement>().First();
            var script = (IHTMLScriptElement)htmlDoc.createElement("script");
            //script.text = "alert('hello world')";//OK没问题,可以弹窗

            //script.text = "function simulateKeyPress(character) {jQuery.event.trigger({ type : 'keypress', which : character.charCodeAt(0) });} var i=document.getElementById('email'); $(function() {i.keypress(function(e) {alert(e.which);  }); simulateKeyPress('e');}); i.focus(); simulateKeyPress('e');"; //不行,

            //script.text = "var ev = document.createEvent('KeyboardEvent');ev.initKeyEvent('keydown', true, true, window, false, false, false, false, 13, 0);document.body.dispatchEvent(ev);alert('hello world')";//不行不支持createEvent

            script.text = "var e = jQuery.Event('keypress');e.which = 13; e.keyCode = 13;$('#email').trigger(e);alert('hello world');";//不行,貌似缺少东西

            head.appendChild((IHTMLDOMNode)script);

Ace8793 | 园豆:7 (初学一级) | 2015-08-05 10:51

@Ace8793: 

其实我不推荐你直接引用第三方库的,本身这些库功能很多对你都是无用的,仅仅为了一个功能而引入,这无疑给你自己程序添加了不必要的负担

这些都是开源的,我觉得你可以直接定位到他们源码,找到模拟键盘操作的代码,估计也就是十几行的代码了,直接勾出来就可以了

visonme | 园豆:1674 (小虾三级) | 2015-08-05 11:10

@Ace8793: 

这是在github上找的一份,你可以看看

https://github.com/eventualbuddha/keysim.js

摘取你自己所需要的核心代码就可以了

visonme | 园豆:1674 (小虾三级) | 2015-08-05 11:12

@visonme: 

keysim.js使用了很多es6的特性,所以需要做些更改不然无法直接在不支持es6的浏览器控件上使用.

 

这是yui处理模拟操作的js文件,也可以参考下

https://github.com/yui/yui3/blob/master/src/event-simulate/js/event-simulate.js

visonme | 园豆:1674 (小虾三级) | 2015-08-05 11:18

@visonme: 谢谢,不过js不是很看得懂啊= =

Ace8793 | 园豆:7 (初学一级) | 2015-08-05 11:20

@Ace8793: 

中午有时间给你写个demo吧,keysim用了很多es6的特性,所以不好看懂(export,class等),YUI还好,可以自己先尝试看看

visonme | 园豆:1674 (小虾三级) | 2015-08-05 11:22

@visonme: 能有demo就太好了,非常感谢,祝工作生活顺利

Ace8793 | 园豆:7 (初学一级) | 2015-08-05 11:24

@Ace8793: 

//模拟
   function simulateKeyPress(target,type , keycode , charcode  )
    {
        target.focus();
        var doc = target.ownerDocument;
        var Event = doc.defaultView.Event;

        //创建键盘事件对象
        var customEventObject = undefined ;
        try{
            try{

                customEventObject = new Event(type);
            }catch(e){
                customEventObject = doc.createEvent("HTMLEvents");
            }

            customEventObject.initEvent(type,true,true);
            customEventObject.shiftKey = false;
            customEventObject.altKey = false;
            customEventObject.metaKey = false;
            customEventObject.ctrlKey = false;
            customEventObject.keyCode = keycode;
            customEventObject.charCode = charcode;
            customEventObject.which = customEventObject.keyCode;
            // if( customEventObject.initKeyEvent ){
            //     customEventObject.initKeyEvent(type, true ,true,document.defaultView , false ,false ,false ,false ,0, parseInt('A',10) );

            // }else{
            //     console.log("------------ initKeyboardEvent---------------------");
            //     customEventObject.initKeyboardEvent(type,true ,true,document.defaultView , false ,false ,false ,false ,0, parseInt('A',10) );
            // }
        }catch(exception){
            console.log(exception);
            try{
                customEventObject = doc.createEvent('Events');
            }catch(uiException){
                customEventObject = doc.createEvent("UIEvents"); //or eventType = HtmlEvents
            }finally{
                customEventObject.initEvent(type,true,true);
                customEventObject.view = null;
                customEventObject.altKey = false;
                customEventObject.ctrlKey = false;
                customEventObject.shiftKey = false;
                customEventObject.metaKey = false;
                customEventObject.keyCode = keycode;
                customEventObject.charCode = charcode;
            }
        }
        
        target.dispatchEvent(customEventObject) 
    };

// test code 
// 随便写个html,放个input(type=text) ,然后监听该input的keydown或者keypress事件查看下是否被触发就可以了
var txtobject = document.getElementById("inputID");

    txtobject.addEventListener('keydown', function(e)
    {
        console.log("successful keydown");
        console.log( e.keyCode);
        console.log(e.charCode);
        txtobject.value = e.charCode;
    },false);
visonme | 园豆:1674 (小虾三级) | 2015-08-05 14:18

@visonme: 你好,我这样写你看对不对,控制台说

  1. Uncaught TypeError: Cannot call method 'addEventListener' of null HTMLPage1.html:63
    1. (anonymous function)HTMLPage1.html:63

<!DOCTYPE html>
<html>
<head>
    <title>123</title>
    <script>
        
    //模拟
        function simulateKeyPress(target, type, keycode, charcode) {
        target.focus();
        var doc = target.ownerDocument;
        var Event = doc.defaultView.Event;

        //创建键盘事件对象
        var customEventObject = undefined;
        try {
            try {

                customEventObject = new Event(type);
            } catch (e) {
                customEventObject = doc.createEvent("HTMLEvents");
            }

            customEventObject.initEvent(type, true, true);
            customEventObject.shiftKey = false;
            customEventObject.altKey = false;
            customEventObject.metaKey = false;
            customEventObject.ctrlKey = false;
            customEventObject.keyCode = keycode;
            customEventObject.charCode = charcode;
            customEventObject.which = customEventObject.keyCode;
            // if( customEventObject.initKeyEvent ){
            //     customEventObject.initKeyEvent(type, true ,true,document.defaultView , false ,false ,false ,false ,0, parseInt('A',10) );

            // }else{
            //     console.log("------------ initKeyboardEvent---------------------");
            //     customEventObject.initKeyboardEvent(type,true ,true,document.defaultView , false ,false ,false ,false ,0, parseInt('A',10) );
            // }
        } catch (exception) {
            console.log(exception);
            try {
                customEventObject = doc.createEvent('Events');
            } catch (uiException) {
                customEventObject = doc.createEvent("UIEvents"); //or eventType = HtmlEvents
            } finally {
                customEventObject.initEvent(type, true, true);
                customEventObject.view = null;
                customEventObject.altKey = false;
                customEventObject.ctrlKey = false;
                customEventObject.shiftKey = false;
                customEventObject.metaKey = false;
                customEventObject.keyCode = keycode;
                customEventObject.charCode = charcode;
            }
        }

        target.dispatchEvent(customEventObject)
    };

    // test code
    // 随便写个html,放个input(type=text) ,然后监听该input的keydown或者keypress事件查看下是否被触发就可以了
    var txtobject = document.getElementById("inputID");
    
    txtobject.addEventListener('keydown', function (e) {
        console.log("successful keydown");
        console.log(e.keyCode);
        console.log(e.charCode);
        txtobject.value = e.charCode;
    }, false);
    </script>

</head>
<body>
    <input type="text" id="inputID" />
</body>
</html>

 

  1. Uncaught TypeError: Cannot call method 'addEventListener' of null HTMLPage1.html:63
    1. (anonymous function)HTMLPage1.html:63
Ace8793 | 园豆:7 (初学一级) | 2015-08-05 14:47

@Ace8793: 

这个是错误是因为在测试脚本执行时候,你的input还没有创建呢,所以

你要把测试代码放到<input type='text' id='inputId" />后面,例如: 

<body>
   <input type="text" id='inputID' />
   <br />
   <input type="button" value="SimKeyPress" id="btn" onclick="onButtonClick();" />
   <script type="text/javascript">

       
    var txtobject = document.getElementById("inputID");

    txtobject.addEventListener('keydown', function(e)
    {
        console.log("successful keydown");
        console.log("receive: " + e.keyCode);
        console.log(e.charCode);
    },false);

   </script>
 </body>
visonme | 园豆:1674 (小虾三级) | 2015-08-05 15:05

@visonme: 按键盘可以获取事件了。但是我加了一个button调用simulateKeyPress方法:

    function test() {
        simulateKeyPress(txtobject, '105', '0');
    }

并绑定给button,点击button没效果

 <button onclick="test()" style="width:100px;height:30px"></button>

<!DOCTYPE html>
<html>
<head>
    <title>123</title>  
</head>
<body>
    <input type="text" id="inputID1" />

    <script>

    //模拟
    function simulateKeyPress(target, type, keycode, charcode) {
        target.focus();
        var doc = target.ownerDocument;
        var Event = doc.defaultView.Event;

        //创建键盘事件对象
        var customEventObject = undefined;
        try {
            try {

                customEventObject = new Event(type);
            } catch (e) {
                customEventObject = doc.createEvent("HTMLEvents");
            }

            customEventObject.initEvent(type, true, true);
            customEventObject.shiftKey = false;
            customEventObject.altKey = false;
            customEventObject.metaKey = false;
            customEventObject.ctrlKey = false;
            customEventObject.keyCode = keycode;
            customEventObject.charCode = charcode;
            customEventObject.which = customEventObject.keyCode;
            // if( customEventObject.initKeyEvent ){
            //     customEventObject.initKeyEvent(type, true ,true,document.defaultView , false ,false ,false ,false ,0, parseInt('A',10) );

            // }else{
            //     console.log("------------ initKeyboardEvent---------------------");
            //     customEventObject.initKeyboardEvent(type,true ,true,document.defaultView , false ,false ,false ,false ,0, parseInt('A',10) );
            // }
        } catch (exception) {
            console.log(exception);
            try {
                customEventObject = doc.createEvent('Events');
            } catch (uiException) {
                customEventObject = doc.createEvent("UIEvents"); //or eventType = HtmlEvents
            } finally {
                customEventObject.initEvent(type, true, true);
                customEventObject.view = null;
                customEventObject.altKey = false;
                customEventObject.ctrlKey = false;
                customEventObject.shiftKey = false;
                customEventObject.metaKey = false;
                customEventObject.keyCode = keycode;
                customEventObject.charCode = charcode;
            }
        }

        target.dispatchEvent(customEventObject)
    };

    // test code
    // 随便写个html,放个input(type=text) ,然后监听该input的keydown或者keypress事件查看下是否被触发就可以了
    var txtobject = document.getElementById("inputID1");
   
    txtobject.addEventListener('keydown', function (e) {
        console.log("successful keydown");
        console.log(e.keyCode);
        console.log(e.charCode);
        txtobject.value = e.charCode;
    }, false);
     function test() {
        simulateKeyPress(txtobject, '105', '0');
    }
    </script>
    <button onclick="test()" style="width:100px;height:30px"></button>
</body>
</html>

Ace8793 | 园豆:7 (初学一级) | 2015-08-05 16:59
其他回答(1)
0

好像不行啊??

雨中舞 | 园豆:204 (菜鸟二级) | 2016-12-06 22:11
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册