工作中遇到一个需求,就是控制用户进入应用时自动打开弹窗的展示顺序。
需求和现状
用户进入应用时会展示一系列的弹窗,这些弹窗的展示内容以及展示与否取决于进入应用时的一系列请求结果。由于接口请求返回数据的时间不确定,所以依赖不同接口的弹窗之间的展示顺序也不确定,且多个弹窗会出现叠加展示的问题,用户体验很不好。
产品需求就是希望弹窗的展示顺序可控,并且同时只展示一个弹窗。
解决方案
解决思路是这样:
封装一个中间层,所有的弹窗不直接展示出来,而是把展示的处理函数统一放在中间层的数据中,等待所有依赖接口都请求完成,也就是弹窗数据都加入到中间层之后,再按照既定顺序依次执行弹窗的展示函数。
依照这个思路,我封装了一个 PopControl 的类,针对上面几点分别暴露了下面几个 api:
- popControl.reset(),用来重置依赖接口状态和弹窗数据
- popControl.load(key),用来标记该接口已经请求完成
- popControl.push(key, callback, startDelay = 100, endDelay = 100, repeatPushShow = true),用来把弹窗插入到弹窗队列中
- popControl.next(key),用来标记该弹窗已展示完成
项目 github 地址:前往
使用
具体使用的时候,需要先实例化出来一个 popControl,构造函数接收两个参数,第一个参数所有弹窗的 key 组成的数组 popKeys(按照展示顺序排序),第二个参数是所有依赖接口的 key 组成的数组。
然后在接口请求成功之后 load 对应的 key,把依赖该接口的弹窗展示函数 push 进 popControl 中,直到所有的接口都 load 完成,popControl 就会按照 popKeys 的顺序依次展示弹窗。每个弹窗展示完成之后要调用 popControl.next(key),标记当前弹窗已经展示完成,方便展示下一个弹窗。
示例代码如下:
import PopControl from "popControl"
const popKeys = ["pop1", "pop2", "pop3"];
const interfaces = ["ajaxSignin", "ajaxUseInfo"];
const popControl = new PopControl(popKeys, interfaces);
request("/ajaxSignin").then(() => {
// 把依赖这个接口的弹窗展示函数 push 进弹窗队列
popControl.push("pop1", () => {
// 展示 pop1 的操作
this.showPop1 = true;
})
popControl.push("pop2", () => {
// 展示 pop2 的操作
this.showPop2 = true;
})
popControl.load("ajaxSignin);
})
request("/ajaxUseInfo").then(() => {
// 把依赖这个接口的弹窗展示函数 push 进弹窗队列
popControl.push("pop3", () => {
// 展示 pop3 的操作
this.showPop3 = true;
})
popControl.load("ajaxUseInfo);
})
function pop1Close() {
this.showPop1 = false;
// 标记 pop1 已经展示完成,可以展示下一个弹窗
popControl.next("pop1");
}
function pop2Close() {
this.showPop2 = false;
// 标记 pop2 已经展示完成,可以展示下一个弹窗
popControl.next("pop2");
}
function pop3Close() {
this.showPop3 = false;
// 标记 pop3 已经展示完成,可以展示下一个弹窗
popControl.next("pop3");
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。