闲来无事,打发摸鱼时间,就想着做一个Message组件玩玩,目前就实现了以下功能点:
- 支持配置消失时间
- 支持success、info、warning、error 4种提示信息
- 其它都不需要了,做着玩的
下面就是代码实现,也不多,就100来行:
class Message {
constructor(config = {}) {
this.msgGobalContainer = null
this.init(config)
}
init(config) {
this.config = { ...this.defaultConfig(), ...config }
}
defaultConfig() {
return {
duration: 2000
}
}
createMsgGobalContainer() {
// 创建全局容器
const msgGobalContainer = document.createElement('div')
msgGobalContainer.classList.add('xyz-message')
this.msgGobalContainer = msgGobalContainer
}
createMsgContainer() {
const msgContainer = document.createElement('div')
msgContainer.classList.add('xyz-message-notice')
return msgContainer
}
createMsgWrap() {
const msgWrap = document.createElement('div')
msgWrap.classList.add('xyz-message-notice-content')
return msgWrap
}
createMsgText(msg) {
const msgText = document.createElement('span')
msgText.innerText = msg
return msgText
}
createMsgIcon(status = 'info') {
// 创建msg的icon标时
const icon = document.createElement('div')
icon.classList.add('xyz-message-icon', `xyz-message-icon-${status}`)
return icon
}
msgCombination(config) {
// 组装msg容器
const msgWrap = this.createMsgWrap()
const msgIcon = this.createMsgIcon(config.status)
const msgText = this.createMsgText(config.message)
const msgContainer = this.createMsgContainer()
msgWrap.appendChild(msgIcon)
msgWrap.appendChild(msgText)
msgContainer.appendChild(msgWrap)
return msgContainer
}
appendMsgToBody(msgContainer) {
if (!this.msgGobalContainer) {
this.createMsgGobalContainer()
document.body.appendChild(this.msgGobalContainer)
}
this.msgGobalContainer.appendChild(msgContainer)
this.delMsgContainer(msgContainer)
}
delMsgContainer(msgContainer) {
setTimeout(() => {
animation(msgContainer).leave(() => msgContainer.remove())
}, this.config.duration)
}
open(message, status) {
const msgContainer = this.msgCombination({
message,
status
})
animation(msgContainer).enter()
this.appendMsgToBody(msgContainer)
}
success(message) {
this.open(message, 'success')
}
info(message) {
this.open(message, 'info')
}
warning(message) {
this.open(message, 'warning')
}
error(message) {
this.open(message, 'error')
}
}
function animation(el) {
const name = 'xyz'
const transitionClass = {
enterClass: `${name}-enter`,
enterToClass: `${name}-enter-to`,
enterActiveClass: `${name}-enter-active`,
leaveClass: `${name}-leave`,
leaveToClass: `${name}-leave-to`,
leaveActiveClass: `${name}-leave-active`
}
const enter = (cb) => {
// 执行进入动画
el.classList.add(transitionClass.enterClass, transitionClass.enterToClass)
requestAnimationFrame(() => {
el.classList.add(transitionClass.enterActiveClass)
})
const transitionend = () => {
el.classList.remove(transitionClass.enterClass, transitionClass.enterToClass, transitionClass.enterActiveClass)
el.removeEventListener('transitionend', transitionend)
if (cb && typeof cb === 'function') cb() // 动画执行完的回调函数
}
el.addEventListener('transitionend', transitionend)
}
const leave = (cb) => {
// 执行离开动画
el.classList.add(transitionClass.leaveClass, transitionClass.leaveToClass)
requestAnimationFrame(() => {
el.classList.add(transitionClass.leaveActiveClass)
})
const transitionend = () => {
el.classList.remove(transitionClass.leaveClass, transitionClass.leaveToClass, transitionClass.leaveActiveClass)
el.removeEventListener('transitionend', transitionend)
if (cb && typeof cb === 'function') cb() // 动画执行完的回调函数
}
el.addEventListener('transitionend', transitionend)
}
return {
enter,
leave
}
}
这里动画部分的代码占了1/3,不然大概100行就完事了。接下来就是样式代码,也不多,写着玩的:
.xyz-message {
box-sizing: border-box;
margin: 0;
padding: 0;
color: #000000d9;
font-size: 14px;
line-height: 22px;
list-style: none;
position: fixed;
top: 0;
left: 0;
z-index: 1010;
width: 100%;
pointer-events: none;
}
.xyz-message-notice {
text-align: center;
margin-top: 20px;
}
.xyz-message-notice-content {
display: inline-block;
padding: 10px 20px;
background-color: #fff;
box-shadow: 0 2px 8px 1px #ddd;
}
.xyz-message-icon {
display: inline-block;
width: 10px;
height: 10px;
margin-right: 10px;
border-radius: 50%;
background-color: #0d71fcd9;
}
.xyz-message-icon-success {
background-color: #29fc0dd9;
}
.xyz-message-icon-info {
background-color: #0d71fcd9;
}
.xyz-message-icon-warning {
background-color: #fc890dd9;
}
.xyz-message-icon-error {
background-color: #eb1d07d9;
}
.xyz-enter {
opacity: 0;
transform: translateY(-20px);
}
.xyz-enter-to, .xyz-leave-to {
transition: all .3s ease;
}
.xyz-enter-active, .xyz-leave {
opacity: 1;
transform: translateY(0);
}
.xyz-leave-active {
opacity: 0;
height: 20px;
transform: translateY(-20px);
}
样式部分就很简单了,分2部分,1部分是定义Message容器位置与各种状态下的样式。另一部分就是定义下动画
最后就是使用它了,那就简单了,初始化下Message实例,放个按钮直接调用就完事了:
const message = new Message({
duration: 2000
})
const submitBtn = document.getElementById('submit')
submitBtn.addEventListener('click', (e) => {
message.success('提交成功')
})
这里就写了Message组件的简单实现,要求不高也能用,其实可以再在Message类上扩展其它方法、配置项属性。比如可以自定义icon、自定义内容区、loading异步等等。收工,下次摸鱼再写个弹框的。