详解用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 相关文章推荐
Expandable "Detail" Table Rows
Aug 29 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件打包下载
Sep 15 Javascript
jquery关于图形报表的运用实现代码
Jan 06 Javascript
表单元素的submit()方法和onsubmit事件应用概述
Feb 01 Javascript
jQuery中操控hidden、disable等无值属性的方法
Jan 06 Javascript
在Html中使用Requirejs进行模块化开发实例详解
Apr 15 Javascript
深入理解js generator数据类型
Aug 16 Javascript
利用jquery实现瀑布流3种案例
Sep 18 Javascript
angular ngClick阻止冒泡使用默认行为的方法
Nov 03 Javascript
关于js函数解释(包括内嵌,对象等)
Nov 20 Javascript
浅谈React + Webpack 构建打包优化
Jan 23 Javascript
JS document内容及样式操作完整示例
Jan 14 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表单递交控件名称含有点号(.)会被转化为下划线(_)的处理方法
2013/01/06 PHP
一个简单且很好用的php分页类
2013/10/26 PHP
PHP获取当前完整URL地址的函数
2014/12/21 PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
2017/07/03 PHP
laravel实现分页样式替换示例代码(增加首、尾页)
2017/09/22 PHP
IE不出现Flash激活框的小发现的js实现方法
2007/09/07 Javascript
javascript中的float运算精度实例分析
2010/08/21 Javascript
对setInterval在火狐和chrome切换标签产生奇怪的效果之探索,与解决方案!
2011/10/29 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
js新闻滚动 js如何实现新闻滚动效果
2013/01/07 Javascript
JavaScript+html5 canvas实现本地截图教程
2020/04/16 Javascript
javascript数组去重小结
2016/03/07 Javascript
js判断手机浏览器操作系统和微信浏览器的方法
2016/04/30 Javascript
ionic隐藏tabs的方法
2016/08/29 Javascript
详解Angular的双向数据绑定(MV-VM)
2016/12/26 Javascript
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
JavaScript引用类型Date常见用法实例分析
2018/08/08 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
2019/09/28 Javascript
JavaScript 空间坐标的使用
2020/08/19 Javascript
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
Python实现井字棋小游戏
2020/03/09 Python
python list等分并从等分的子集中随机选取一个数
2020/11/16 Python
Python 将代码转换为可执行文件脱离python环境运行(步骤详解)
2021/01/25 Python
css3中单位px,em,rem,vh,vw,vmin,vmax的区别及浏览器支持情况
2016/12/06 HTML / CSS
美国汽配连锁巨头Pep Boys官网:轮胎更换、汽车维修服务和汽车零部件
2017/01/14 全球购物
意大利奢侈品购物网站:Giglio
2018/01/05 全球购物
size?德国官方网站:英国伦敦的球鞋精品店
2018/03/17 全球购物
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
法律专业实习鉴定
2013/12/22 职场文书
管道维修工岗位职责
2013/12/27 职场文书
2014年幼儿园元旦活动方案
2014/02/13 职场文书
八项规定对照检查材料
2014/08/31 职场文书
党的群众路线教育实践活动心得体会(乡镇)
2014/11/03 职场文书
学校元旦晚会开场白
2015/05/29 职场文书
2016年小学植树节活动总结
2016/03/16 职场文书
Windows Server 2022 超融合部署(图文教程)
2022/06/25 Servers