用JavaScript完成页面自动操作
在之前的一篇《JavaScript实现按键精灵》中曾记录了几个事件对象,本文将会对它们进行一次实战,要完成的动作包括滚动、点击和翻页。
一、滚动
滚动是通过修改容器元素的scrollTop属性实现的,期间会进行一系列的计算,而每次滚动都会包含一个个小的偏移动作,为了让这些动作能有序进行,自定义了一个Promise,如下所示。
/**
* 简易Promise
*/
var Promise = {
fns: [],
then: function(fn) {
this.fns.push(fn);
return this;
},
resolve: function() {
if (this.fns.length == 0) return;
var fn = this.fns.splice(0, 1);
fn[0] && fn[0].call(this);
}
};
为了让滚动表现的更加顺滑,采用了requestAnimationFrame()方法,滚动的方向分为三种,分别是向上、向下或待机,如下所示。
/**
* 随机整数
*/
var Util = {
random: function(max) {
return Math.floor(Math.random() * max);
}
};
/**
* 随机滚动
* container 容器元素
*/
function scrollTopBottom(container) {
var num = Util.random(10);
for (var i = 0; i < num; i++) {
(function(count) {
Promise.then(function() {
var direction, //滚动方向
destination, //滚动的目标位置
current, //当前滚动距离
slide = 0; //滚动距离
destination = Util.random(2000);
current = container.scrollTop;
direction = Util.random(3);
(function moveInner() {
switch (direction) {
case 0: //向上滚动
current += 10;
break;
case 1: //向下滚动
current -= 10;
if (current < 0) current = 0;
break;
default: //保持原地
break;
}
slide += 10; //执行滚动
console.log(count, slide, current, destination);
container.scrollTop = current;
if (slide <= destination && current > 0) {
window.requestAnimationFrame(moveInner); //顺滑的滚动
} else {
Promise.resolve(); //执行下一个动作
}
})();
});
})(i);
}
Promise.resolve(); //开始滚动
}
滚动的容器元素多变,可能是body,也可能是根元素或者是其它元素,具体得视页面而定,示例页面采用的是根元素,如下所示。
/**
* document.documentElement
* document.body
*/
scrollTopBottom(document.documentElement);
等到的效果如下图所示。

虽然完成了自动滚动,但当前的代码无法精度控制,例如难以配置成第几秒向上或向下滚动,或者指定滚动到真实用户会停留的位置的时间。
二、点击
在触发点击事件时,需要指定一些元素。目前的坐标是随机生成的,每次会遍历元素,当坐标在元素范围内时,才派发事件,完成点击,如下所示。MouseEvent中的clientX、pageX等属性可参考《触屏touch事件记录》中的记录。
/**
* 点击
*/
function click() {
var links = document.querySelectorAll("img"), //指定要触发的元素
x = Util.random(window.outerWidth), //随机X坐标
y = Util.random(document.body.scrollHeight), //随机Y坐标
clientY = y > window.outerHeight ? (y - window.outerHeight) : y;
var event = new MouseEvent("click", {
bubbles: true, //能够冒泡
cancelable: true, //可以取消事件
view: window, //窗口
clientX: x,
clientY: clientY, //相对于视口的垂直偏移
pageX: x,
pageY: y //包含垂直滚动的偏移
});
[].forEach.call(links, function(value, key) {
var rect = value.getBoundingClientRect();
//判断当前坐标是否在元素范围内
if(x >= rect.left && x<=rect.right && y>=rect.top && y<=rect.bottom) {
console.log(x, y);
value.dispatchEvent(event); //派发事件
}
});
}
function runClick() {
for (var j = 0; j < 50; j++) {
(function(j) {
setTimeout(function() {
click(); //随意点击页面
}, 2000 * j); //不集中在一个时间执行
})(j);
}
}
虽然完成了自动点击,但还不够灵活。当要触发的动作不是由指定的元素触发的时,这段脚本就起不了作用,并且手机屏幕尺寸众多,难以精确的在某一指定区域内点击。
由于很依赖事件类型,因此当绑定的动作不在该事件中时,代码也会失效。如果要触发页面监测的请求,那么不得不先去翻源码,搜寻触发事件。
三、翻页
现在很多活动页面都是以全屏翻页的形式出现,通过touchstart、touchmove和touchend三个事件,就能模拟出手指滑动的效果,方向既可以是从下到上,也可以是从右往左,下面的代码采用了前者。使用柯里化的方式减少了touch()函数的参数,TouchEvent中的touches和targetTouches参数,也可以参考《触屏touch事件记录》中的记录。
/**
* 竖屏翻页
*/
var identifier = 0,
eventType = ["touchstart", "touchmove", "touchend"];
function slide(container) {
var x = Util.random(window.outerWidth),
y = 300,
currying = touch(container, x, y);
currying(eventType[0]);
currying(eventType[1]);
currying(eventType[2]);
}
function touch(container, x, y) {
var interval = 100; //滑动距离
return function(type) {
identifier++;
if (type == eventType[1]) { //touchmove事件更改Y坐标
y -= interval;
}
var t = new Touch({
identifier: identifier,
target: container,
clientX: x,
clientY: y,
pageX: x,
pageY: y
});
console.log(`${identifier}, ${type} x: ${x}, y: ${y}`);
var event = new TouchEvent(type, {
touches: [t],
targetTouches: [t]
});
container.dispatchEvent(event);
};
}
/**
* 假设滑动插件是swiper.js
* 那么取其容器作为slide()的参数传入
*/
setInterval(function() {
slide(document.querySelector(".swiper-container"));
}, 2000);
得到的效果如下图所示。

示例中使用的是swiper触屏滑动插件,当换成其他插件时,容器就需要跟着改变。
上述所有自动化操作都是基于DOM结构完成的,水能载舟亦能覆舟,无法跳出DOM的限制,就会导致一系列的问题,例如针对不同页面的结构要做单独的分析、动作精度难以控制、真实的用户轨迹难以模拟、代码不够灵活难以复用。
在实际情况中,还有很多复杂的动作(例如答题、填表单等),光靠上述这点代码是远远不够的,目前还做不到像按键精灵那样在屏幕上录制行为,这么简洁。
demo代码已上传至GitHub:
https://github.com/pwstrick/auto
用JavaScript完成页面自动操作的更多相关文章
- 学习笔记: JavaScript/JQuery 的cookie操作
转自:http://blog.csdn.net/barryhappy/archive/2011/04/27/6367994.aspx cookie是网页存储到用户硬盘上的一小段信息.最常见的作用是判断 ...
- javascript控制页面(含iframe进行页面跳转)跳转、刷新的方法汇总
一.JS方式的页面跳转1.window.location.href方式 <script language="JavaScript" type="text/ja ...
- 关于JavaScript中的delete操作
关于JavaScript中的delete操作 看到一道题,是这样的: (function(x){ delete x; return x; })(1); 1 null undefined Error 我 ...
- Javascript刷新页面大全
非模态刷新父页面:window.opener.location.reload(); 模态刷新父页面:window.dialogArguments.location.reload(); 先来看一个简单的 ...
- PHP 页面自动刷新可借助JS来实现,简单示例如下:
<?php echo "系统当前时间戳为:"; echo ""; echo time(); //<!--JS 页面自动刷新 --> echo ...
- JavaScript对SVG进行操作的相关技术
原文地址:http://www.ibm.com/developerworks/cn/xml/x-svgscript/ 本文主要介绍在 SVG 中通过编程实现动态操作 SVG 图像的知识. SVG ...
- VBS脚本和HTML DOM自动操作网页
VBS脚本和HTML DOM自动操作网页 2016-06-16 10:24 1068人阅读 评论(0) 收藏 举报 分类: Windows(42) 版权声明:本文为博主原创文章,未经博主允许不得转 ...
- 详解Grunt插件之LiveReload实现页面自动刷新(两种方案)
http://www.jb51.net/article/70415.htm 含Grunt系列教程 这篇文章主要通过两种方案详解Grunt插件之LiveReload实现页面自动刷新,需要的朋友可以 ...
- 方法总结:如何实现html页面自动刷新
使用场景: 1. 页面需要定时刷新,实时加载数据,需要实时查看监控数据(H5中的WebSocket和SSE可以实现局部刷新) 2. 一定时间之后跳转到指定页面(登录注册之类) 3. 前端开发使用伪数据 ...
随机推荐
- 洛谷$P5038\ [SCOI2012]$奇怪的游戏 二分+网络流
正解:二分+网络流 解题报告: 传送门$QwQ$ 这种什么,"同时增加",长得就挺网络流的$QwQ$?然后看到问至少加多少次,于是考虑加个二分呗?于是就大体确定了做题方向,用的网络 ...
- 菜鸟系列Fabric源码学习 — MVCC验证
Fabric 1.4 源码分析 MVCC验证 读本节文档之前建议先查看[Fabric 1.4 源码分析 committer记账节点]章节. 1. MVCC简介 Multi-Version Concur ...
- 2020年我国到底有多少程序员?现在学习java还来得及吗?
中国有多少程序员?现在还值得学java吗? 跪求关注,祝关注我的人都:身体健康,财源广进,福如东海,寿比南山,早上贵子,从不掉发! JAVA起于1995年,经过20多年的发展,JAVA如今已经发展成为 ...
- 洛谷P3413 SAC#1 - 萌数 题解 数位DP
题目链接:https://www.luogu.com.cn/problem/P3413 题目大意: 定义萌数指:满足"存在长度至少为2的回文子串"的数. 求区间 \([L,R]\) ...
- PTC热敏电阻的应用
PTC热敏电阻应用举例 PTC热敏电阻可用于计算机及其外部设备.移动电话.电池组.远程通讯和网络装备.变压器.工业控制设备.汽车及其它电子产品中,作为开关类的PTC陶瓷元件,具有开发功能.使电器设 ...
- echarts设置数据在轴线上显示
项目中遇到数据需要在右侧显示,如图,直接上代码: 1.需要在哪个轴上显示 就把那个轴写成一个数组 2.分别设置一下定位和数据即可(如下图红色部分) yAxis: [ { type: 'categor ...
- spring同时操作多数据库 多个mysql和mongoDB,不需切换数据源,同时操作mysql和mongodb
源码:https://github.com/haihai1172/spring-mysql-mongoDB 项目目录 1.环境搭建,java-sdk 1.8 具体怎么搭建,就不说了 2.配置jdbc. ...
- 基于Saltstack、Artifactory打造传统模式下持续部署平台
一.持续部署 1. 现状 由于没有建立标准的持续部署流程,导致了版本管理混乱,制品管理混乱,上线持续时间长,上线测试覆盖不全面,业务流量上升后故障较多,排查复杂.运维.测试.开发人员每次版本迭代的时候 ...
- HTTP1.1
读了一本图解http,总结一下子. 1 .重要的头部 1.TCP/IP 通信传输流 五层模型 先盗个图,重点说明每过一层都会加个头,头很重要啊!其中https 就是在传输层搞事,把本来明文的数据包 ...
- 2、Automapper安装及配置
一. 安装 我们安装是在 vs 中使用Nuget的方式进行安装 不过安装时需注意一件事情就是,版本问题,我示例使用的是.net framework 4.5.2,所以我安装AutoMapper的版本是7 ...