大家都知道每个系统都不可能是没有bug的,那么当用户使用的时候,我们现在的处理方式有哪些呢?
1、这个问题刚好在后端接口级别,那一般我们后端代码中,比如本博客中也有很多讲解,就是使用springboot全局的errorhandler(@ControllerAdvice + @ExceptionHandler)来进行捕获,并发送邮件给开发。
2、如果这个问题在前端的javascript层,那我们一般通过前端的异常监控系统,将前端的error,上报到前端异常监控系统来让开发定位。
3、样式移动了,功能不对?那这个怎么办呢?
本文针对第三种情况,引出我们需要做一个知乎一样的反馈功能。
知乎的反馈功能体验:www.zhihu.com, 在右下角的位置,大家可以先体验一下。
一、分析
我们看下面的截图,主要是点击反馈,弹出一个模态框,然后这个模态框,会针对当前的屏幕进行截图,然后我们同时可以针对截图的图片,进行标注,比如圈起来有bug的地方。如下图:
我们看了功能大概如此了,那我们要解决的技术问题,模态框和输入框(就不介绍了)
主要介绍我们的大头:就是那个截取当前用户访问的屏幕,同时支持能圈起来的功能
二、原理
大概就是如何将dom元素变成对应的图片,然后针对图片能做图片的标记。
这个时候,我们首先想到有没有类似的库,能解决我们的问题,搜索后,在npmjs.com网站上,找到了dom-to-image 这个库,大概就是能将dom元素变成canvas
然后下一步对于图片的标记,我们原本知识就是在canvas上进行最简单的操作,也就是我们的图片标记功能。
三、实战
本地我建一个demo的功能,总体建一个index.html和app.js文件即可,然后打包工具,也不想太复杂,直接使用parcel即可。
所以第一步:
mkdir feedback
cd feedback第二步:执行npm init和安装对应的dom-to-image的包:
npm init npm i dom-to-image --save-dev
第三步:新建一个index.html和app.js
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>反馈功能测试</title>
</head>
<body>
<div>
<h1>登鹳雀楼</h1>
<p>唐代:王之涣</p>
<p>白日依山尽,黄河入海流。</p>
<p>欲穷千里目,更上一层楼。</p>
</div>
<button id="feedback">反馈</button>
<div>
<canvas id="csv"></canvas>
</div>
<script src="./app.js"></script>
</body>
</html>app.js:
import domtoimage from 'dom-to-image';
/* 监听对应的反馈按钮的事件 */
document
.getElementById ('feedback')
.addEventListener ('click', function (event) {
var node = document.getElementsByTagName ('body')[0];
var csv = document.getElementById ('csv');
var pos = {
x: 0,
y: 0,
};
var ctx = null;
domtoimage
.toPng (node)
.then (function (dataUrl) {
var img = new Image ();
img.src = dataUrl;
img.onload = () => {
ctx = csv.getContext ('2d');
csv.width = document
.getElementsByTagName ('body')[0]
.getBoundingClientRect ().width;
csv.height = document
.getElementsByTagName ('body')[0]
.getBoundingClientRect ().height;
ctx.drawImage (img, 0, 0);
};
})
.catch (function (error) {
console.error ('oops, something went wrong!', error);
});
});然后我们使用parcel来运行我们的代码:(这个是一个类似webpack的打包一样的工具)
parcel index.html
然后console里面会提示我们打开网站:
⏳ Building...
Server running at http://localhost:1234
✨ Built in 8ms.然后我们打开网站 http://localhost:1234,看到下面的图:
然后点击反馈按钮,会看到下面这样:
这时候,我们基本截图的功能就好了,然后我们再实现绘画的功能:
绘图基本就是canvas的代码,我们主要监听几个事件:mousemove, mousedown, mouseenter,这三个事件。
代码最终修改后如下:
import domtoimage from 'dom-to-image';
/* 监听对应的反馈按钮的事件 */
document
.getElementById ('feedback')
.addEventListener ('click', function (event) {
var node = document.getElementsByTagName ('body')[0];
var csv = document.getElementById ('csv');
var pos = {
x: 0,
y: 0,
};
var ctx = null;
function draw (e) {
if (e.buttons !== 1) return;
ctx.beginPath ();
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.strokeStyle = 'red';
ctx.moveTo (pos.x, pos.y); // from
setPosition (e);
ctx.lineTo (pos.x, pos.y); // to
ctx.stroke (); // draw it!
}
function setPosition (e) {
pos.x = e.clientX - csv.getBoundingClientRect ().left;
pos.y = e.clientY - csv.getBoundingClientRect ().top;
}
domtoimage
.toPng (node)
.then (function (dataUrl) {
var img = new Image ();
img.src = dataUrl;
img.onload = () => {
ctx = csv.getContext ('2d');
csv.width = document
.getElementsByTagName ('body')[0]
.getBoundingClientRect ().width;
csv.height = document
.getElementsByTagName ('body')[0]
.getBoundingClientRect ().height;
ctx.drawImage (img, 0, 0);
csv.addEventListener ('mousemove', draw.bind (this));
csv.addEventListener ('mousedown', setPosition.bind (this));
csv.addEventListener ('mouseenter', setPosition.bind (this));
};
})
.catch (function (error) {
console.error ('oops, something went wrong!', error);
});
});最终我们查看我们的效果:
上图中,比如我们发现这个唐诗的作者不对,那我们可以给系统管理员进行反馈拉。
代码放在github上: github.com/stone-jin/f…
四、总结
我们看到标题中有个(一),说明肯定实际使用中有一些代码需要修改啦,那这个我们后面系列篇中带来我们来做一个模态框的反馈模块,还有可能小伙伴实际用的时候,会发现为什么我这种情况下图片出不来,我这种情况下字体图标出不来,这个canvas的图片,我怎么传到服务器端,传上去的图片为什么像素这么低,怎么来处理。
那我们看到知乎已经挺好的了,所以这个就是后面,我补下后面的模态框的篇,问题篇,然后讲解下dom-to-image这些的内容了,仅仅这样肯定也是不够的。
希望最终能达到这样的目的,能带领各位小伙伴一起完成下面的目标:
事业部的所有的管理系统,前端调用我们的前端npm包,后端使用@EnableFeedback这个注解,A系统想要对接,经过上面两个步骤即可。同时可以在反馈中心进行参数配置,那是不是解决了事业部下面,所有管理后台或者产品的反馈功能了,作者慢慢写,欢迎关注我。