由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="width: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一樣獲得剪貼板里面的數據了。

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

非常感謝哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM