详解用js代码触发dom事件的实现方案


Posted in Javascript onJune 10, 2020

背景

前端编写测试用例时,在测试界面上的一些效果时,通常都希望能够模拟一些用户操作,而模拟用户操作最主要的方式就是用代码触发指定事件。通常一些元素上会自带一些触发事件的方法,例如click、focus等,但是如果是其他的事件,例如mousedown、mouseup、mouseenter,这些事件怎么模拟呢?

思路

其实思路很简单,web标准中定义了一系列API接口,其中dispatchEvent允许我们向一个指定的事件目标派发一个事件,而且使用这个方法触发的事件是可以正常触发我们的标准事件处理规则的(包括事件捕获和可选的冒泡过程),那么这就非常强大了,我们可以基于此做很多事情了。

实现方法

大致流程相信大家都已经想到了,无外乎以下几步操作:

  • 创建要触发的事件实例
  • 获取要触发事件的元素对象
  • 调用元素对象的dispatchEvent方法,参数是目标事件实例
  • 特殊事件要分析一下模拟方式,巧妙的实现

首先,创建事件实例

web标准提供了MouseEvent 接口,专指用户与指针设备( 如鼠标 )交互时发生的事件。使用此接口的常见事件包括:click、dblclick 、mouseup、mousedown。

通过构造函数MouseEvent(typeArg, mouseEventInit),可以生成一个新的MouseEvent对象。该构造函数接受两个参数,第一个参数为typeArg,用于指定事件的名称,一般都是一个字符串。第二个参数为mouseEventInit,可以初始化 MouseEvent的字典,也就是指定一些该事件的属性值,比如鼠标事件常见的screenX、screenY、clientX、clientY等属性,同时,由于MouseEvent是继承于UIEvent,UIEvent又继承于Event,所以mouseEventInit可以包含UIEventInit和EventInit中的属性。

总结一行代码就是:

const mouseEvent = new MouseEvent(typeArg, mouseEventInit);

这里大家看自己实际需要,去指定哪些属性的哪些值即可。

这里再说一句,不仅是鼠标事件,还有很多其他事件,只要浏览器支持,都可以使用的。具体参考:https://developer.mozilla.org/zh-CN/docs/Web/API

这里面列出的事件,理论上都可以自己模拟并触发。

其次,就是在指定元素上触发该事件

有了事件,那么就可以去调用对应元素上的dispatchEvent方法触发了。这里简单,也就是一行代码:

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

最后,特殊事件或者场景,分解操作来模拟

有些特殊事件或者场景,其实可以分析一波细节,然后分解成若干个事件连续触发,即可巧妙的实现。
这里举个例子,点击事件,其实本质是:触发一次mousedown,同时在足够短的时间内再触发一次mouseup,那么这样即可间接实现一次click事件。即:

// 一段足够短的时间内
mousedown+mouseup=click

这样,其实在模拟一些特殊操作时,我们也可以实现了。比如,模拟用户的鼠标拖拽多选操作,其本质就是:现在某个元素上触发mousedown事件,然后执行mousemove事件,然后拖拽到某一个元素上时,触发mouseup事件;即:

// 模拟用户拖拽鼠标
(开始元素)mousedown+(截止元素)mouseup=一次鼠标拖拽操作

这里细节可以足够多,看你实际场景按需模拟即可,比如鼠标移动过程中,鼠标进入某个元素时,该元素还会触发mouseenter事件,离开元素还会触发mouseleave事件。那就是:

// 更精确的模拟用户拖拽鼠标
(开始元素)mousedown+(中间元素)mouseenter+(中间元素)mouseleave+(截止元素)mouseup=一次鼠标拖拽操作

总之,细节可以足够多,但是够你模拟出本次操作的基本测试点即可,别忘了,我们的前提是模拟用户操作,进而执行测试用例。

再进一步,你完全可以封装一些常见的用户操作,然后将方法暴露出来,在测试用例中引入,实现高度复用。

总结

总结下来呢,其实就是采用MouseEvent和dispatchEvent两个web标准提供的接口,来通过代码触发事件,进而模拟用户的操作,达到测试用例中,模拟用户行为的目的。希望对你有所帮助。

注意事项

这里有些限制条件,需要大家注意下:

  1. 本文所说的方法,主要是用于自动化测试场景中的,正常开发项目中,不建议大家用这种方式触发事件,这可能会导致你的代码难以理解,影响代码的可维护性。
  2. 本文中主要用到的这两大接口,是有兼容性限制的,IE基本上是无法使用的,但是,一般来讲,使用这种方法的场景多数都是单元测试或者自动化测试的场景,这些场景下一般都会有模拟浏览器环境,而且用的最多的就是chrome的内核,所以基本上在测试场景下,这种方式是可以放心使用的。

到此这篇关于详解用js代码触发dom事件的实现方案的文章就介绍到这了,更多相关js触发dom事件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
js 数组操作代码集锦
Apr 28 Javascript
JS取得绝对路径的实现代码
Jan 16 Javascript
基于JQuery实现图片上传预览与删除操作
May 24 Javascript
Bootstarp基本模版学习教程
Feb 01 Javascript
JS+html5制作简单音乐播放器
Sep 13 Javascript
w3c编程挑战_初级脚本算法实战篇
Jun 23 Javascript
JS使用正则表达式验证身份证号码
Jun 23 Javascript
Javascript之图片的延迟加载的实例详解
Jul 24 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
Aug 20 Javascript
JSON基本语法及与JavaScript的异同实例分析
Jan 04 Javascript
Javascript 解构赋值详情
Nov 17 Javascript
HTML+JS实现在线朗读器
Feb 15 Javascript
Vue中key的作用示例代码详解
Jun 10 #Javascript
使用JavaScript获取扫码枪扫描得到的条形码的思路代码详解
Jun 10 #Javascript
js 获取扫码枪输入数据的方法
Jun 10 #Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
Jun 10 #Javascript
使用 UniApp 实现小程序的微信登录功能
Jun 09 #Javascript
详解vue高级特性
Jun 09 #Javascript
vue实例的选项总结
Jun 09 #Javascript
You might like
十天学会php(1)
2006/10/09 PHP
用php来检测proxy
2006/10/09 PHP
用Zend Encode编写开发PHP程序
2010/02/21 PHP
深入php数据采集的详解
2013/06/02 PHP
深入array multisort排序原理的详解
2013/06/18 PHP
PHP+MYSQL中文乱码问题
2015/07/01 PHP
PHP实现用户异地登录提醒功能的方法【基于thinkPHP框架】
2018/03/15 PHP
laravel-admin解决表单select联动时,编辑默认没选上的问题
2019/09/30 PHP
PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解
2019/12/13 PHP
PHP获取类私有属性的3种方法
2020/09/10 PHP
使用jquery animate创建平滑滚动效果(可以是到顶部、到底部或指定地方)
2014/05/27 Javascript
Node.js 异步编程之 Callback介绍(一)
2015/03/30 Javascript
js表格排序实例分析(支持int,float,date,string四种数据类型)
2015/05/06 Javascript
js实现按钮颜色渐变动画效果
2015/08/20 Javascript
js浏览器html5表单验证
2016/10/17 Javascript
详解微信小程序开发—你期待的分享功能来了,微信小程序序新增5大功能
2016/12/23 Javascript
微信小程序开发(一) 微信登录流程详解
2017/01/11 Javascript
jQuery点击头像上传并预览图片
2017/02/23 Javascript
nodejs入门教程六:express模块用法示例
2017/04/24 NodeJs
Node.js使用orm2进行update操作时关联字段无法修改的解决方法
2017/06/13 Javascript
js中getter和setter用法实例分析
2018/08/14 Javascript
js中apply()和call()的区别与用法实例分析
2018/08/14 Javascript
纯异步nodejs文件夹(目录)复制功能
2019/09/03 NodeJs
[01:55]TI9显影之尘系列 - Evil Geniuses
2019/08/22 DOTA
查看Django和flask版本的方法
2018/05/14 Python
Python局部变量与全局变量区别原理解析
2020/07/14 Python
python3 中时间戳、时间、日期的转换和加减操作
2020/07/14 Python
Python同时处理多个异常的方法
2020/07/28 Python
运行Python编写的程序方法实例
2020/10/21 Python
ProBikeKit澳大利亚:自行车套件,跑步和铁人三项装备
2016/11/30 全球购物
租房协议书样本
2014/08/20 职场文书
婚前协议书范本两则
2014/10/16 职场文书
中层干部考核评语
2015/01/04 职场文书
门卫管理制度范本
2015/08/05 职场文书
先进个人主要事迹范文
2015/11/04 职场文书
Python+Appium自动化测试的实战
2021/06/30 Python