用js代碼觸發dom事件的實現方案

背景

前端編寫測試用例時,在測試界面上的一些效果時,一般都但願可以模擬一些用戶操做,而模擬用戶操做最主要的方式就是用代碼觸發指定事件。一般一些元素上會自帶一些觸發事件的方法,例如click、focus等,可是若是是其餘的事件,例如mousedown、mouseup、mouseenter,這些事件怎麼模擬呢?javascript

思路

其實思路很簡單,web標準中定義了一系列API接口,其中dispatchEvent容許咱們向一個指定的事件目標派發一個事件,並且使用這個方法觸發的事件是能夠正常觸發咱們的標準事件處理規則的(包括事件捕獲和可選的冒泡過程),那麼這就很是強大了,咱們能夠基於此作不少事情了。前端

實現方法

大體流程相信你們都已經想到了,無外乎如下幾步操做:java

  1. 建立要觸發的事件實例
  2. 獲取要觸發事件的元素對象
  3. 調用元素對象的dispatchEvent方法,參數是目標事件實例
  4. 特殊事件要分析一下模擬方式,巧妙的實現

首先,建立事件實例

web標準提供了MouseEvent 接口,專指用戶與指針設備( 如鼠標 )交互時發生的事件。使用此接口的常見事件包括:click、dblclick 、mouseup、mousedown。
經過構造函數MouseEvent(typeArg, mouseEventInit),能夠生成一個新的MouseEvent對象。該構造函數接受兩個參數,第一個參數爲typeArg,用於指定事件的名稱,通常都是一個字符串。第二個參數爲mouseEventInit,能夠初始化 MouseEvent的字典,也就是指定一些該事件的屬性值,好比鼠標事件常見的screenX、screenY、clientX、clientY等屬性,同時,因爲MouseEvent是繼承於UIEvent,UIEvent又繼承於Event,因此mouseEventInit能夠包含UIEventInit和EventInit中的屬性。
總結一行代碼就是:web

const mouseEvent = new MouseEvent(typeArg, mouseEventInit);

這裏你們看本身實際須要,去指定哪些屬性的哪些值便可。chrome

這裏再說一句,不只是鼠標事件,還有不少其餘事件,只要瀏覽器支持,均可以使用的。具體參考:https://developer.mozilla.org...
這裏面列出的事件,理論上均可以本身模擬並觸發。瀏覽器

其次,就是在指定元素上觸發該事件

有了事件,那麼就能夠去調用對應元素上的dispatchEvent方法觸發了。這裏簡單,也就是一行代碼:函數

document.getElementById("id").dispatchEvent(mouseEvent);

最後,特殊事件或者場景,分解操做來模擬

有些特殊事件或者場景,其實能夠分析一波細節,而後分解成若干個事件連續觸發,便可巧妙的實現。
這裏舉個例子,點擊事件,其實本質是:觸發一次mousedown,同時在足夠短的時間內再觸發一次mouseup,那麼這樣便可間接實現一次click事件。即:單元測試

// 一段足夠短的時間內
mousedown+mouseup=click

這樣,其實在模擬一些特殊操做時,咱們也能夠實現了。好比,模擬用戶的鼠標拖拽多選操做,其本質就是:如今某個元素上觸發mousedown事件,而後執行mousemove事件,而後拖拽到某一個元素上時,觸發mouseup事件;即:測試

// 模擬用戶拖拽鼠標
(開始元素)mousedown+(截止元素)mouseup=一次鼠標拖拽操做

這裏細節能夠足夠多,看你實際場景按需模擬便可,好比鼠標移動過程當中,鼠標進入某個元素時,該元素還會觸發mouseenter事件,離開元素還會觸發mouseleave事件。那就是:spa

// 更精確的模擬用戶拖拽鼠標
(開始元素)mousedown+(中間元素)mouseenter+(中間元素)mouseleave+(截止元素)mouseup=一次鼠標拖拽操做

總之,細節能夠足夠多,可是夠你模擬出本次操做的基本測試點便可,別忘了,咱們的前提是模擬用戶操做,進而執行測試用例。

再進一步,你徹底能夠封裝一些常見的用戶操做,而後將方法暴露出來,在測試用例中引入,實現高度複用。

總結

總結下來呢,其實就是採用MouseEventdispatchEvent兩個web標準提供的接口,來經過代碼觸發事件,進而模擬用戶的操做,達到測試用例中,模擬用戶行爲的目的。但願對你有所幫助。

注意事項

這裏有些限制條件,須要你們注意下:

  1. 本文所說的方法,主要是用於自動化測試場景中的,正常開發項目中,不建議你們用這種方式觸發事件,這可能會致使你的代碼難以理解,影響代碼的可維護性。
  2. 本文中主要用到的這兩大接口,是有兼容性限制的,IE基本上是沒法使用的,可是,通常來說,使用這種方法的場景多數都是單元測試或者自動化測試的場景,這些場景下通常都會有模擬瀏覽器環境,並且用的最多的就是chrome的內核,因此基本上在測試場景下,這種方式是能夠放心使用的。
相關文章
相關標籤/搜索