13.6 模擬事件【JavaScript高級程式設計第三版】

来源:http://www.cnblogs.com/itzhoubao/archive/2017/05/17/6866021.html
-Advertisement-
Play Games

事件,就是網頁中某個特別值得關註的瞬間。事件經常由用戶操作或通過其他瀏覽器功能來觸發。 但很少有人知道,也可以使用JavaScript 在任意時刻來觸發特定的事件,而此時的事件就如同瀏覽器創建的事件一樣。也就是說,這些事件該冒泡還會冒泡,而且照樣能夠導致瀏覽器執行已經指定的處理它們的事件處理程式。在 ...


事件,就是網頁中某個特別值得關註的瞬間。事件經常由用戶操作或通過其他瀏覽器功能來觸發。
但很少有人知道,也可以使用JavaScript 在任意時刻來觸發特定的事件,而此時的事件就如同瀏覽器創建的事件一樣。也就是說,這些事件該冒泡還會冒泡,而且照樣能夠導致瀏覽器執行已經指定的處理它們的事件處理程式。在測試Web 應用程式,模擬觸發事件是一種極其有用的技術。DOM2 級規範為此規定了模擬特定事件的方式,IE9、Opera、Firefox、Chrome 和Safari 都支持這種方式。IE 有它自己模擬事件的方式。

13.6.1 DOM中的事件模擬

可以在document 對象上使用createEvent()方法創建event 對象。這個方法接收一個參數,即表示要創建的事件類型的字元串。在DOM2 級中,所有這些字元串都使用英文複數形式,而在DOM3級中都變成了單數。這個字元串可以是下列幾字元串之一。

  • UIEvents:一般化的UI 事件。滑鼠事件和鍵盤事件都繼承自UI 事件。DOM3 級中是UIEvent。
  • MouseEvents:一般化的滑鼠事件。DOM3 級中是MouseEvent。
  • MutationEvents:一般化的DOM 變動事件。DOM3 級中是MutationEvent。
  • HTMLEvents:一般化的HTML 事件。沒有對應的DOM3 級事件(HTML 事件被分散到其他類別中)。

要註意的是,“DOM2 級事件”並沒有專門規定鍵盤事件,後來的“DOM3 級事件”中才正式將其作為一種事件給出規定。IE9 是目前唯一支持DOM3 級鍵盤事件的瀏覽器。不過,在其他瀏覽器中,在現有方法的基礎上,可以通過幾種方式來模擬鍵盤事件。
在創建了event 對象之後,還需要使用與事件有關的信息對其進行初始化。每種類型的event 對象都有一個特殊的方法,為它傳入適當的數據就可以初始化該event 對象。不同類型的這個方法的名字也不相同,具體要取決於createEvent()中使用的參數。
模擬事件的最後一步就是觸發事件。這一步需要使用dispatchEvent()方法,所有支持事件的DOM 節點都支持這個方法。調用dispatchEvent()方法時,需要傳入一個參數,即表示要觸發事件的event 對象。觸發事件之後,該事件就躋身“官方事件”之列了,因而能夠照樣冒泡並引發相應事件處理程式的執行。

1. 模擬滑鼠事件

創建新的滑鼠事件對象併為其指定必要的信息,就可以模擬滑鼠事件。創建滑鼠事件對象的方法是為createEvent()傳入字元串"MouseEvents"。返回的對象有一個名為initMouseEvent()方法,用於指定與該滑鼠事件有關的信息。這個方法接收15 個參數,分別與滑鼠事件中每個典型的屬性一一對應;這些參數的含義如下。

  • type(字元串):表示要觸發的事件類型,例如"click"。
  • bubbles(布爾值):表示事件是否應該冒泡。為精確地模擬滑鼠事件,應該把這個參數設置為true。
  • cancelable(布爾值):表示事件是否可以取消。為精確地模擬滑鼠事件,應該把這個參數設置為true。
  • view(AbstractView):與事件關聯的視圖。這個參數幾乎總是要設置為document.defaultView。
  • detail(整數):與事件有關的詳細信息。這個值一般只有事件處理程式使用,但通常都設置為0。
  • screenX(整數):事件相對於屏幕的X 坐標。
  • screenY(整數):事件相對於屏幕的Y 坐標。
  • clientX(整數):事件相對於視口的X 坐標。
  • clientY(整數):事件想對於視口的Y 坐標。
  • ctrlKey(布爾值):表示是否按下了Ctrl 鍵。預設值為false。
  • altKey(布爾值):表示是否按下了Alt 鍵。預設值為false。
  • shiftKey(布爾值):表示是否按下了Shift 鍵。預設值為false。
  • metaKey(布爾值):表示是否按下了Meta 鍵。預設值為false。
  • button(整數):表示按下了哪一個滑鼠鍵。預設值為0。
  • relatedTarget(對象):表示與事件相關的對象。這個參數只在模擬mouseover 或mouseout時使用。

顯而易見,initMouseEvent()方法的這些參數是與滑鼠事件的event 對象所包含的屬性一一對應的。其中,前4 個參數對正確地激發事件至關重要,因為瀏覽器要用到這些參數;而剩下的所有參數只有在事件處理程式中才會用到。當把event 對象傳給dispatchEvent()方法時,這個對象的target屬性會自動設置。下麵,我們就通過一個例子來瞭解如何模擬對按鈕的單擊事件。

var btn = document.getElementById("myBtn");
//創建事件對象
var event = document.createEvent("MouseEvents");
//初始化事件對象
event.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0,
false, false, false, false, 0, null);
//觸發事件
btn.dispatchEvent(event);

運行一下
在相容DOM的瀏覽器中,也可以通過相同的方式來模擬其他滑鼠事件(例如dblclick)。

2. 模擬鍵盤事件

前面曾經提到過,“DOM2 級事件”中沒有就鍵盤事件作出規定,因此模擬鍵盤事件並沒有現成的思路可循。“DOM2 級事件”的草案中本來包含了鍵盤事件,但在定稿之前又被刪除了;Firefox 根據其草案實現了鍵盤事件。需要提請大家註意的是,“DOM3 級事件”中的鍵盤事件與曾包含在“DOM2 級事件”草案中的鍵盤事件有很大區別。
DOM3 級規定,調用createEvent()並傳入"KeyboardEvent"就可以創建一個鍵盤事件。返回的事件對象會包含一個initKeyEvent()方法,這個方法接收下列參數。

  • type(字元串):表示要觸發的事件類型,如"keydown"。
  • bubbles(布爾值):表示事件是否應該冒泡。為精確模擬滑鼠事件,應該設置為true。
  • cancelable(布爾值):表示事件是否可以取消。為精確模擬滑鼠事件,應該設置為true。
  • view (AbstractView ):與事件關聯的視圖。這個參數幾乎總是要設置為document.defaultView。
  • key(布爾值):表示按下的鍵的鍵碼。
  • location(整數):表示按下了哪裡的鍵。0 表示預設的主鍵盤,1 表示左,2 表示右,3 表示數字鍵盤,4 表示移動設備(即虛擬鍵盤),5 表示手柄。
  • modifiers(字元串):空格分隔的修改鍵列表,如"Shift"。
  • repeat(整數):在一行中按了這個鍵多少次。

由於DOM3級不提倡使用keypress 事件,因此只能利用這種技術來模擬keydown 和keyup 事件。

var textbox = document.getElementById("myTextbox"),
event;
//以DOM3 級方式創建事件對象
if (document.implementation.hasFeature("KeyboardEvents", "3.0")) {
	event = document.createEvent("KeyboardEvent");
	//初始化事件對象
	event.initKeyboardEvent("keydown", true, true, document.defaultView, "a", 0, "Shift", 0);
}
//觸發事件
textbox.dispatchEvent(event);

運行一下
這個例子模擬的是按住Shift 的同時又按下A 鍵。在使用document.createEvent
("KeyboardEvent")之前,應該先檢測瀏覽器是否支持DOM3 級事件;其他瀏覽器返回一個非標準的KeyboardEvent 對象。
在Firefox 中,調用createEvent()並傳入"KeyEvents"就可以創建一個鍵盤事件。返回的事件對象會包含一個initKeyEvent()方法,這個方法接受下列10 個參數。

  • type(字元串):表示要觸發的事件類型,如"keydown"。
  • bubbles(布爾值):表示事件是否應該冒泡。為精確模擬滑鼠事件,應該設置為true。
  • cancelable(布爾值):表示事件是否可以取消。為精確模擬滑鼠事件,應該設置為true。
  • view(AbstractView):與事件關聯的視圖。這個參數幾乎總是要設置為document.default-View。
  • ctrlKey(布爾值):表示是否按下了Ctrl 鍵。預設值為false。
  • altKey(布爾值):表示是否按下了Alt 鍵。預設值為false。
  • shiftKey(布爾值):表示是否按下了Shift 鍵。預設值為false。
  • metaKey(布爾值):表示是否按下了Meta 鍵。預設值為false。
  • keyCode(整數):被按下或釋放的鍵的鍵碼。這個參數對keydown 和keyup 事件有用,預設值為0。
  • charCode(整數):通過按鍵生成的字元的ASCII 編碼。這個參數對keypress 事件有用,預設值為0。

將創建的event 對象傳入到dispatchEvent()方法就可以觸發鍵盤事件,如下麵的例子所示。

//只適用於Firefox
var textbox = document.getElementById("myTextbox")
//創建事件對象
var event = document.createEvent("KeyEvents");
//初始化事件對象
event.initKeyEvent("keypress", true, true, document.defaultView, false, false,
false, false, 65, 65);
//觸發事件
textbox.dispatchEvent(event);

運行一下
在Firefox 中運行上面的代碼,會在指定的文本框中輸入字母A。同樣,也可以依此模擬keyup 和keydown 事件。
在其他瀏覽器中,則需要創建一個通用的事件,然後再向事件對象中添加鍵盤事件特有的信息。
例如:

var textbox = document.getElementById("myTextbox");
//創建事件對象
var event = document.createEvent("Events");
//初始化事件對象
event.initEvent(type, bubbles, cancelable);
event.view = document.defaultView;
event.altKey = false;
event.ctrlKey = false;
event.shiftKey = false;
event.metaKey = false;
event.keyCode = 65;
event.charCode = 65;
//觸發事件
textbox.dispatchEvent(event);

以上代碼首先創建了一個通用事件,然後調用initEvent()對其進行初始化,最後又為其添加了鍵盤事件的具體信息。在此必須要使用通用事件,而不能使用UI 事件,因為UI 事件不允許向event對象中再添加新屬性(Safari 除外)。像這樣模擬事件雖然會觸發鍵盤事件,但卻不會向文本框中寫入文本,這是由於無法精確模擬鍵盤事件所造成的。

3. 模擬其他事件

雖然滑鼠事件和鍵盤事件是在瀏覽器中最經常模擬的事件,但有時候同樣需要模擬變動事件和HTML 事件。要模擬變動事件, 可以使用createEvent("MutationEvents") 創建一個包含initMutationEvent() 方法的變動事件對象。這個方法接受的參數包括: type 、bubbles 、cancelable、relatedNode、preValue、newValue、attrName 和attrChange。下麵來看一個模擬變動事件的例子。

var event = document.createEvent("MutationEvents");
event.initMutationEvent("DOMNodeInserted", true, false, someNode, "","","",0);
targ et.dispatchEvent(event);

以上代碼模擬了DOMNodeInserted 事件。其他變動事件也都可以照這個樣子來模擬,只要改一改參數就可以了。
要模擬HTML 事件,同樣需要先創建一個event 對象——通過createEvent("HTMLEvents"),然後再使用這個對象的initEvent()方法來初始化它即可,如下麵的例子所示。

var event = document.createEvent("HTMLEvents");
event.initEvent("focus", true, false);
targ et.dispatchEvent(event);

這個例子展示瞭如何在給定目標上模擬focus 事件。模擬其他HTML 事件的方法也是這樣。

瀏覽器中很少使用變動事件和HTML 事件,因為使用它們會受到一些限制。

4. 自定義DOM 事件

DOM3 級還定義了“自定義事件”。自定義事件不是由DOM 原生觸發的,它的目的是讓開發人員創建自己的事件。要創建新的自定義事件,可以調用createEvent("CustomEvent")。返回的對象有一個名為initCustomEvent()的方法,接收如下4 個參數。

  • type(字元串):觸發的事件類型,例如"keydown"。
  • bubbles(布爾值):表示事件是否應該冒泡。
  • cancelable(布爾值):表示事件是否可以取消。
  • detail(對象):任意值,保存在event 對象的detail 屬性中。

可以像分派其他事件一樣在DOM 中分派創建的自定義事件對象。例如:

var div = document.getElementById("myDiv"),
event;
EventUtil.addHandler(div, "myevent",
function(event) {
	alert("DIV: " + event.detail);
});
EventUtil.addHandler(document, "myevent",
function(event) {
	alert("DOCUMENT: " + event.detail);
});
if (document.implementation.hasFeature("CustomEvents", "3.0")) {
	event = document.createEvent("CustomEvent");
	event.initCustomEvent("myevent", true, false, "Hello world!");
	div.dispatchEvent(event);
}

運行一下
這個例子創建了一個冒泡事件"myevent"。而event.detail 的值被設置成了一個簡單的字元串,然後在<div>元素和document 上偵聽這個事件。因為initCustomEvent()方法已經指定這個事件應該冒泡,所以瀏覽器會負責將事件向上冒泡到document。
支持自定義DOM事件的瀏覽器有IE9+和Firefox 6+。

13.6.2 IE中的事件模擬

在IE8 及之前版本中模擬事件與在DOM中模擬事件的思路相似:先創建event 對象,然後為其指定相應的信息,然後再使用該對象來觸發事件。當然,IE 在實現每個步驟時都採用了不一樣的方式。
調用document.createEventObject()方法可以在IE 中創建event 對象。但與DOM方式不同的是,這個方法不接受參數,結果會返回一個通用的event 對象。然後,你必須手工為這個對象添加所有必要的信息(沒有方法來輔助完成這一步驟)。最後一步就是在目標上調用fireEvent()方法,這個方法接受兩個參數:事件處理程式的名稱和event 對象。在調用fireEvent()方法時,會自動為event 對象添加srcElement 和type 屬性;其他屬性則都是必須通過手工添加的。換句話說,模擬任何IE 支持的事件都採用相同的模式。例如,下麵的代碼模擬了在一個按鈕上觸發click 事件過程。

var btn = document.getElementById("myBtn");
//創建事件對象
var event = document.createEventObject();
//初始化事件對象
event.screenX = 100;
event.screenY = 0;
event.clientX = 0;
event.clientY = 0;
event.ctrlKey = false;
event.altKey = false;
event.shiftKey = false;
event.button = 0;
//觸發事件
btn.fireEvent("onclick", event);

運行一下
這個例子先創建了一個event 對象,然後又用一些信息對其進行了初始化。註意,這裡可以為對象隨意添加屬性,不會有任何限制——即使添加的屬性IE8 及更早版本並不支持也無所謂。在此添加的屬性對事件沒有什麼影響,因為只有事件處理程式才會用到它們。
採用相同的模式也可以模擬觸發keypress 事件,如下麵的例子所示。

var textbox = document.getElementById("myTextbox");
//創建事件對象
var event = document.createEventObject();
//初始化事件對象
event.altKey = false;
event.ctrlKey = false;
event.shiftKey = false;
event.keyCode = 65;
//觸發事件
textbox.fireEvent("onkeypress", event);

運行一下
由於滑鼠事件、鍵盤事件以及其他事件的event 對象並沒有什麼不同,所以可以使用通用對象來觸發任何類型的事件。不過,正如在DOM中模擬鍵盤事件一樣,運行這個例子也不會因模擬了keypress而在文本框中看到任何字元,即使觸發了事件處理程式也沒有用。

下載離線版教程:http://www.shouce.ren/api/view/a/15218


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • java 企業網站源碼 前後臺都有 靜態模版引擎, 代碼生成器大大提高開發效率 前臺: 支持兩套模版, 可以在後臺切換 系統介紹: 1.網站後臺採用主流的 SSM 框架 jsp JSTL,網站後臺採用freemaker靜態化模版引擎生成html 2.因為是生成的html,所以訪問速度快,輕便,對服務 ...
  • 前言: 隨著業務的擴大,用戶的增多,訪問量的增加,單機模式已經不能支撐,從而出現了從單機模式->垂直應用模式->集群模式,集群模式誕生了,伴隨著一堆問題也油然而生,Master怎麼選舉,機器故障及時移除集群,添加機器瞭如何及時的感應到,Zookeeper不僅能維護當前的集群服務狀態,還能及時的選出m ...
  • 修改所有圖片或者元素的顏色為黑白 (100% 灰度) ...
  • 思路: 使用 mousemover 事件來監測是否有用戶操作頁面,寫一個定時器間隔特定時間檢測是否長時間未操作頁面,如果是,退出; 具體時間代碼如下(js):var lastTime = new Date().getTime(); var currentTime = new Date().getTi ...
  • html 手機web超出屏幕寬度的內容不換行,並產生橫向滾動條 white-space: nowrap;overflow-x: scroll; white-space: nowrap;overflow-x: scroll; ...
  • Vue.js 使用了基於 HTML 的模版語法,允許開發者聲明式地將 DOM 綁定至底層 Vue 實例的數據。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循規範的瀏覽器和 HTML 解析器解析。 在底層的實現上, Vue 將模板編譯成虛擬 DOM 渲染函數。結合響應系統,在應用狀態改 ...
  • 英文原文:http://net.tutsplus.com/tutorials/html-css-techniques/sass-vs-less-vs-stylus-a-preprocessor-shootout 原文鏈接:http://www.w3cplus.com/css/sass-vs-less ...
  • 講述js中的on事件與addEventListener的用法與不同 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...