寫在前面
最近公司在搞瀏覽器相容的事情,所有瀏覽器相容的問題不得不一個人包了。下面來說一下今天遇到的一個問題吧
大家都知道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一樣獲得剪貼簿裡面的資料了。
這究竟是怎麼一回事,不知道有哪位大神可以告訴我原因!
非常感謝哦!