我们在平时会用弹窗或者 toast 对用户进行提示,而弹窗是属于强提示类型的(需要用户点击等交互后弹窗才消失),提供的信息量也大,而 toast 提示则属于弱提示类型(无论用户有没有看到,反正我提示了),仅进行小小的提醒。 弹窗类型的交互通常可以多个弹窗叠加,用户关闭一个后,再看下一个;而 toast 提示通常在同一时间只显示一个,那么如果同时多个 toast 需要提示时,怎么办? 我们接下来把这两种方式都实现一下。 我们先来实现一个简单的 toast,然后再说如何控制多个 toast 的先后提示。 用 div 模拟一个 toast。 这里我们的重点是要创建一个 toast 所在的唯一的容器,然后给容器一个定位: 最后给一个总入口,把单个 toast 放在容器里: 可以查看 demo 效果:类 ant design 的 toast 提示。 上面的提示方式在 PC 端还可以,但是在移动端的小屏幕上,同时显示多个会显得比较拥挤,因此我们这里同时最多只显示一个 toast 提示,上一个消失之后,再展示下一个 toast 提示。 这里我们要对 然后通过一个方法和缓存来控制 toast 的显示: 可以点击链接查看 demo:同时最多只展示一个 toast 提示。 关于 toast 的设计还有很多要考虑的问题,这里我们也是探讨了如何控制多个 toast 的展示问题。
1. 先实现一个简单的 toast #
// 在浏览器上模拟toast提示
export const toast = (
text: string | number,
duration: number = 1800,
container: HTMLElement = document.body
): Promise
margin-top: 20px;
padding: 12px 20px;
border-radius: 5px;
background-color: rgba(255, 255, 255, 0.96);
color: #111111;
font-size: 16px;
line-height: 1.5;
white-space: nowrap;
text-align: center;`;
div && (div.innerHTML = text.toString());
container.appendChild(div);
return new Promise((resolve) => {
setTimeout(() => {
div && div.parentNode && div.parentNode.removeChild(div); // 固定时间后消失
toastInstance = false;
resolve();
}, duration);
});
};
2. 展示多个 toast 的方式 #
2.1 将多个 toast 都展示出来 #
let toastContainer: any = null;
export const getToastContainer = () => {
if (toastContainer) {
return toastContainer;
}
toastContainer = document.createElement('div');
toastContainer.style.cssText = `position: fixed;
top: 20px;
left: 50%;
transform: translate3d(-50%, 0, 0);
z-index: 9999;`;
document.body.appendChild(toastContainer);
return toastContainer;
};
const message = (text) => {
getToastContainer();
toast(text, 1800, toastContainer);
};
2.2 同时只显示一个 toast 提示 #
toast
稍微改造下:
+ let toastInstance = false;
const toast = (text, duration = 1800, container = document.body) => {
+ if (toastInstance) {
+ return;
+ }
+ toastInstance = true;
let div = document.createElement('div');
div.className = 'toast';
div.style.cssText = `position: fixed;
padding: 12px 20px;
border-radius: 5px;
+ top: 20px;
+ left: 50%;
+ transform: translate3d(-50%, 0, 0);
background-color: rgba(255, 255, 255, 0.96);
box-shadow: 0 0 2px #666666;
color: #111111;
font-size: 16px;
line-height: 1.5;
white-space: nowrap;
text-align: center;`;
div && (div.innerHTML = text.toString());
container.appendChild(div);
return new Promise((resolve) => {
setTimeout(() => {
div && div.parentNode && div.parentNode.removeChild(div); // 固定时间后消失
+ toastInstance = false;
resolve();
}, duration);
});
};
let toastList = []; // 后面的提示先缓存起来
const toastWaterFall = async (text) => {
if (toastInstance) {
toastList.push(text); // 若当前toast正在进行,则缓存
} else {
await toast(text); // 否则展示toast提示
if (toastList.length) {
while (toastList.length) {
await sleep(300); // 延迟一段时间
await toast(toastList.shift() + '');
}
}
}
};
3. 总结 #
版权属于:
加速器之家
作品采用:
《
署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
》许可协议授权
评论