• 由chrome剪贴板问题研究到了js模拟鼠标键盘事件


    写在前面

    最近公司在搞浏览器兼容的事情,所有浏览器兼容的问题不得不一个人包了。下面来说一下今天遇到的一个问题吧

    大家都知道IE下面如果要获得剪贴板里面的信息的话,代码应该如下所示

     window.clipboardData.getData("Text")

    可是在chrome下面就行不通了,chrome下面没有类似ie的这种方法,那应该怎么办呢,百度了一下,发现还真有办法。

    只要在HTML界面上放上一个text类型的控件,如下所示

     <textarea id="textArea" ></textarea>

    然后js代码这样写就可以了,不过要在body上绑定keydown事件,写上

    <body onkeydown="return cellkeydown(event)">
            function cellkeydown(event) {
                if (event.ctrlKey && event.keyCode == 86) {
                    var ss = document.getElementById("textArea");
                    ss.focus();
                    ss.select();
                    // 等50毫秒,keyPress事件发生了再去处理数据
                    setTimeout("dealwithData()", 50);
                }
            }
            function dealwithData(event) {
                var ss = document.getElementById("textArea");
                alert(ss.value);
                ss.blur();
    
            }

    把代码这样一写就发现在任何其它应用程序复制的信息,在当前运行的界面上只要按ctrl+v就可以把剪贴板里面的信息获得。

    哈哈,以为大功告成,却发现事件远没那么简单!

    事件没完没了了

    原来在原先的界面上,只有一个“粘贴”按钮,跟测试那边沟通,没法聊下去,不能按ctrl+v来获得剪贴板里面的信息,必须按按钮,不能改变用户之前的行为。好吧,既然这样,只能想想用js模拟键盘事件啦。

    找了好多一堆资料,总结了如下规则。

    Dom 事件模拟可以通过document上的createEvent()方法,有如下一些事件

    UIEvents:通用的UI 事件,鼠标事件键盘事件都是继承自UI事件,在DOM 3 级上使用的是 UIEvent。
    MouseEvents:通用的鼠标事件,在DOM 3 级上使用的是 MouseEvent。
    MutationEvents:通用的突变事件,在DOM 3 级上使用的是 MutationEvent。
    HTMLEvents:通用的HTML事件,在DOM3级上还没有等效的。

    键盘事件initKeyBoadEvent()方法初始化,初始化键盘事件的参数有以下几个:

    type (string) - 要触发的事件类型,例如“keydown”.
    bubbles (Boolean) — 代表事件是否应该冒泡. 
    cancelable (Boolean) — 代表事件是否可以被取消. 
    view (AbstractView) — 被授予事件的是图. 通常值为:document.defaultView.
    key (string) — 按下的键对应的code.
    location (integer) — 按下键所在的位置. 0 :默认键盘, 1 左侧位置, 2 右侧位置, 3 数字键盘区, 4 虚拟键盘区, or 5 游戏手柄.
    modifiers (string) — 一个有空格分开的修饰符列表.
    repeat (integer) — 一行中某个键被按下的次数.

    在FF下,允许你通过使用document.createEvent('KeyEvents'),这种方式来创建键盘事件,初始化的方法为initKeyEvent(),这个方法接受10个参数,
    type (string) — 要触发的事件类型,例如“keydown”.
    bubbles (Boolean) — 代表事件是否应该冒泡.
    cancelable (Boolean) — 代表事件是否可以被取消. 
    view (AbstractView) — 被授予事件的是图. 通常值为:document.defaultView.
    ctrlKey (Boolean) — 代表ctrol键是否按下. 默认 false.
    altKey (Boolean) — 代表alt键是否按下. 默认 false.
    shiftKey (Boolean) — 代表shift键是否按下. 默认 false.
    metaKey (Boolean) — 代表meta键是否按下. 默认 false.
    keyCode (integer) — 键按下或释放时键所对应的键码. 默认是0;
    charCode (integer) — 按下的键的字符所对应的ASCII code.是共keypress事件使用的 默认是0.

    具体API详细信息可以参考浅谈Javascript事件模拟

    琢磨了好久终于找到解决方案(可是还有瑕疵)

    具体解决方案还参考了如下网页键盘按键事件的fireEvent

    先把代码贴上,终于解决了js模拟事件了,也触发了ctrl+v,却发现获得的剪贴板里面的数据是空。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title>fireKeyEvent</title>
    
    </head>
    
    <body onkeydown="return cellkeydown(event)" id="mytest">
        <!--这里设置textarea不能为display为none  否则就粘贴不了信息-->
        <textarea id="textArea" style="0px;height:0px; overflow:hidden;margin:0px;padding:0px;"></textarea>
        <input type="button" id="btn1" value="fire" /><!--按钮在这模拟ctrl+v事件-->
    
        <script type="text/javascript">
            /*
            *@desc keypress事件
            */
            function cellkeydown(event) {            
                if ((event.ctrlKey && event.keyCode == 86) ) {      //如果用户按的是ctrl+v          
                    var ss = document.getElementById("textArea");
                    ss.focus();
                    ss.select();
                    // 等50毫秒,keyPress事件发生了再去处理数据
                    setTimeout("dealwithData()", 50);
                }
            }
            /*
            *@desc 处理数据
            */
            function dealwithData(event) {
                var ss = document.getElementById("textArea");
                alert(ss.value);//这里获得的是剪贴板里面的信息
                ss.blur();
            }
    
            function $(id) {
                return document.getElementById(id);
            }
            function addEvent(el, type, fn) {           
    
                if (document.addEventListener) {
                    el.addEventListener(type, fn, true);
                } else if (document.attachEvent) {
                    el.attachEvent("on" + type, fn);
                } else {
                    el["on" + type] = fn;
                }
            }
    
            /*
            *@desc 触发事件
            */
            function fireKeyEvent(el, evtType, keyCode) {
                var evtObj;
                if (document.createEvent) {
                    if (window.KeyEvent) {//firefox 浏览器下模拟事件
                        evtObj = document.createEvent('KeyEvents');
                        evtObj.initKeyEvent(evtType, true, true, window, true, false, false, false, keyCode, 0);
                    } else {//chrome 浏览器下模拟事件
                        evtObj = document.createEvent('UIEvents');
                        evtObj.initUIEvent(evtType, true, true, window, 1);
    
                        delete evtObj.keyCode;
                        if (typeof evtObj.keyCode === "undefined") {//为了模拟keycode
                            Object.defineProperty(evtObj, "keyCode", { value: keyCode });                       
                        } else {
                            evtObj.key = String.fromCharCode(keyCode);
                        }
    
                        if (typeof evtObj.ctrlKey === 'undefined') {//为了模拟ctrl键
                            Object.defineProperty(evtObj, "ctrlKey", { value: true });
                        } else {
                            evtObj.ctrlKey = true;
                        }
                    }
    
                    el.dispatchEvent(evtObj);
    
                } else if (document.createEventObject) {//IE 浏览器下模拟事件
                    evtObj = document.createEventObject();
                    evtObj.keyCode = keyCode
                    el.fireEvent('on' + evtType, evtObj);
                }
            }
            /*
            *@desc 绑定按键触发ctrl+v事件
            */
            addEvent($("btn1"), "click", function () {            
                fireKeyEvent($("mytest"), "keydown", 86);
            });
    
        </script>
    
    </body>
    </html>

    最后的问题

    搞了一下午,捣鼓出来怎样用js模拟事件触发,却发现即使触发了事件,可是却不能如按ctrl+v一样获得剪贴板里面的数据了。

    这究竟是怎么一回事,不知道有哪位大神可以告诉我原因!

    非常感谢哦!

  • 相关阅读:
    sql的优化
    使用Robo 3T访问MongoDB数据库
    在IDEA中用三个jar包链接MongoDB数据库——实现增删改查
    使用Robo 3T操作MongoDB数据库
    MongoDB 创建数据库
    mysql本地中127.0.0.1连接不上数据库怎么办
    IDEA-Maven的Dependencies中出现红色波浪线
    log4j2+slf4j+junit
    fastxml Jackson annotation使用小记
    我理解的互联网技术领域
  • 原文地址:https://www.cnblogs.com/liyunhua/p/4526556.html
Copyright © 2020-2023  润新知