用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的内核,因此基本上在测试场景下,这种方式是能够放心使用的。
相关文章
相关标签/搜索