动画:
消息下滑出现
点击消息上移消失
消失时后面所有消息框上移滑动
实现:
seed消息个数
instances:[] 当前所有消息框实例数组
点击出现消息,且会在前面的消息之后顺序排列,每个消息出现都具有下滑动画,通过定位top和seed来进行排列,通过定时器100毫秒延迟添加类实现下滑动画
点击消息上移,点击添加类实现上移消失动画,通过遍历instances数组中当前点击之后的实例,修改top值,实现所有上移
自动消息:每次点击都会有个3秒定时器,执行当前消息框上移消失,之后的所有消息框上移
删除节点:每次点击都会有个定时器,3秒后删除节点
使用:
Message.show({msg:'提示内容'}) 会排列出现
Message.showOnce({msg:'提示内容'}) 只会出现一个
效果图:
代码示例:
使用:
import React,{useState,useEffect} from 'react'
import Message from './message/message'
function App(props){
const _click = function () {
Message.show({msg:'注意提示'});
}
return(
<div>
{/* <Message></Message> */}
<br/>
<button onClick={_click}>提示</button>
</div>
)
}
export default App
Message.jsx:
import React, { useState } from 'react'
import PropTypes from 'prop-types'
import './message.css'
let seed = 0; //当前个数
let instances = []; //当前节点数组
// 未完成:多次点击,高度累增加,然后依次消去,消去会向上移动
function App(props) {
}
App.showOnce = function (props) {
if (document.querySelector('.jf-message')) {
return;
}
let div = document.createElement('div');
div.style.overflow = 'hidden';
div.className = 'jf-message';
div.innerHTML = `<div class='jf-message-container'>
<div class='jf-message-layout'>
<div class='jf-message-icon'>
<i class='iconfont ${'icon-tishi'}'></i>
</div>
<div class='jf-message-text'>
<span>${props.msg}</span>
</div>
</div>
</div>`
document.body.appendChild(div);
App.handler(div);
if (seed < 0) {
seed = 0;
}
seed++;
instances.push(div);
App.move(div);
}
//待修改,高度自定义
App.show = function (props) {
let div = document.createElement('div');
div.style.overflow = 'hidden';
div.className = 'jf-message';
div.innerHTML = `<div class='jf-message-container'>
<div class='jf-message-layout'>
<div class='jf-message-icon'>
<i class='iconfont ${'icon-tishi'}'></i>
</div>
<div class='jf-message-text'>
<span>${props.msg}${seed}</span>
</div>
</div>
</div>`
document.body.appendChild(div);
if (seed < 0) {
seed = 0;
}
div.style.top = 20 + (div.offsetHeight+10) * seed + 'px';
App.handler(div);
App.move(div, seed);
seed++;
instances.push(div);
}
//事件处理函数
App.handler = function (dom) {
dom.onclick = () => {
seed--; //立即减少当前个数,避免删除后添加会因为seed改变不即使而留有空位
let index = instances.indexOf(dom);
dom.classList.remove('jf-message-show');
dom.hide = true;
for (let i = index+1; i < instances.length; i++) {
instances[i].style.top = instances[i].style.top.substring(0, instances[i].style.top.length - 2) - (dom.offsetHeight+10) + 'px';
}
}
}
//自动控制弹出、上移隐藏
App.move = function (msgf, index) {
App.pop(msgf);
App.hide(msgf);
App.remove(msgf);
}
//弹出
App.pop = function (dom) {
setTimeout(() => {
dom.classList.add('jf-message-show')
}, 100)
}
//上移隐藏
App.hide = function (dom) {
setTimeout(() => {
instances.splice(0, 1); //删除前一个节点(每次第一个)
if (dom.hide) //该节点已被删除等,已经做了将后面节点位移操作
{
return;
}
//前一个节点消失,移动后面节点上位
seed--;
dom.classList.remove('jf-message-show')
for (let i = 0; i < instances.length; i++) {
instances[i].style.top = instances[i].style.top.substring(0, instances[i].style.top.length - 2) - (dom.offsetHeight+10) + 'px';
}
}, 3000)
}
//删除节点
App.remove = function (dom) {
setTimeout(() => {
document.body.removeChild(dom);
}, 3010)
}
export default App;
Message.css:
.jf-message {
display: inline-block;
box-sizing: border-box;
min-width: 300px;
height: 48px;
/* border: solid 1px orange; */
border-radius: 5px;
background-color: #f0f9eb;
position: fixed;
left: 50%;
top: 20px;
bottom: 0;
z-index: 2000;
transform: translate(-50%, -100%);
transition: opacity 0.7s, transform 0.4s, top 0.3s;
overflow: hidden;
opacity: 0;
}
.jf-message-container {
height: 100%;
}
.jf-message-show {
opacity: 1;
transform: translate(-50%, 0%);
}
.jf-message-layout {
display: flex;
align-items: center;
height: 100%;
}
.jf-message-icon > i {
color: #67c28a;
font-size: 16px;
margin: 0 10px;
}
.jf-message-text {
font-size: 14px;
color: #67c28a;
}