原生 js - showMessage 显示一个消息提示。
loading
参数
textOrOptions
: string | Object - 提示的文本内容或配置选项options
: Object - 配置选项text
: string - 提示的文本内容(当第一个参数为对象时使用)type
: string - 提示类型,可选值:'success'|'info'|'warning'|'error',默认'info'duration
: number - 显示时间,单位毫秒,默认 3000,设为 0 则不自动关闭showIcon
: boolean - 是否显示图标,默认 trueonClose
: Function - 关闭时的回调函数
使用示例
javascript
// 基础用法
showMessage('操作成功')
// 快捷方式调用
showMessage.success('保存成功')
showMessage.error('操作失败')
// 使用配置项
showMessage({
text: '这是一条消息提示',
type: 'info',
duration: 5000,
onClose: () => {
console.log('消息已关闭')
}
})
源码
源码
js
/**
* 显示一个消息提示
* @author chuxiao
* @param {string|Object} textOrOptions - 提示的文本内容或配置选项
* @param {Object} [options={}] - 配置选项
* @param {string} [options.text] - 提示的文本内容(当第一个参数为对象时使用)
* @param {string} [options.type='info'] - 提示类型,可选值:'success'|'info'|'warning'|'error'
* @param {number} [options.duration=3000] - 显示时间,单位毫秒,设为0则不自动关闭
* @param {boolean} [options.showIcon=true] - 是否显示图标
* @param {Function} [options.onClose] - 关闭时的回调函数
*
* @example
* // 基础用法-直接传文本
* showMessage('操作成功');
*
* // 快捷方式调用
* showMessage.success('保存成功');
* showMessage.error('操作失败');
*
* // 使用配置项
* showMessage({
* text: '这是一条消息提示',
* type: 'info',
* duration: 5000,
* onClose: () => {
* console.log('消息已关闭');
* }
* });
*/
function showMessage(textOrOptions, options = {}) {
let text, finalOptions
if (typeof textOrOptions === 'string') {
text = textOrOptions
finalOptions = options
} else {
text = textOrOptions.text || ''
finalOptions = textOrOptions
}
const { type = 'info', duration = 3000, showIcon = true, onClose = () => {} } = finalOptions
const iconColorMap = {
success: '#52c41a',
info: '#1677ff',
warning: '#faad14',
error: '#ff4d4f'
}
const backgroundColorMap = {
success: '#f6ffed',
info: '#e6f4ff',
warning: '#fffbe6',
error: '#fff2f0'
}
const borderColorMap = {
success: '#b7eb8f',
info: '#91caff',
warning: '#ffe58f',
error: '#ffccc7'
}
const textColorMap = {
success: '#52c41a',
info: '#1677ff',
warning: '#faad14',
error: '#ff4d4f'
}
const svgIcons = {
success: `<svg viewBox="0 0 1024 1024" width="16" height="16"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z" fill="${iconColorMap[type]}"/></svg>`,
info: `<svg viewBox="0 0 1024 1024" width="16" height="16"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm32 664c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272zm-32-344c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z" fill="${iconColorMap[type]}"/></svg>`,
warning: `<svg viewBox="0 0 1024 1024" width="16" height="16"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z" fill="${iconColorMap[type]}"/></svg>`,
error: `<svg viewBox="0 0 1024 1024" width="16" height="16"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359c-1.2-1.5-1.9-3.3-1.9-5.2 0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z" fill="${iconColorMap[type]}"/></svg>`
}
// 创建消息容器
let messageContainer = document.querySelector('.message-container')
if (!messageContainer) {
messageContainer = document.createElement('div')
messageContainer.className = 'message-container'
messageContainer.style.cssText = `
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
z-index: 1000;
pointer-events: none;
display: flex;
flex-direction: column;
align-items: center;
`
document.body.appendChild(messageContainer)
}
// 创建消息元素
const message = document.createElement('div')
message.style.cssText = `
background: ${backgroundColorMap[type]};
padding: 10px 16px;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 8px;
pointer-events: all;
animation: messageSlideIn 0.3s ease;
transition: all 0.3s ease;
opacity: 1;
transform: translateY(0);
border: 1px solid ${borderColorMap[type]};
max-width: 80vw;
`
// 添加图标
if (showIcon && svgIcons[type]) {
const iconContainer = document.createElement('div')
iconContainer.innerHTML = svgIcons[type]
iconContainer.style.cssText = `
flex-shrink: 0;
display: flex;
align-items: center;
`
message.appendChild(iconContainer)
}
// 添加文本
const content = document.createElement('span')
content.textContent = text
content.style.cssText = `
font-size: 14px;
color: ${textColorMap[type]};
line-height: 1.5;
word-wrap: break-word;
word-break: break-all;
`
message.appendChild(content)
// 添加样式
const style = document.createElement('style')
style.textContent = `
@keyframes messageSlideIn {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes messageSlideOut {
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-20px);
}
}
`
document.head.appendChild(style)
// 添加到容器
messageContainer.appendChild(message)
// 关闭消息的函数
const close = () => {
message.style.animation = 'messageSlideOut 0.3s ease forwards'
setTimeout(() => {
messageContainer.removeChild(message)
if (messageContainer.children.length === 0) {
document.body.removeChild(messageContainer)
document.head.removeChild(style)
}
onClose()
}, 300)
}
// 添加关闭按钮
if (duration === 0) {
const closeBtn = document.createElement('div')
closeBtn.innerHTML = '×'
closeBtn.style.cssText = `
margin-left: 8px;
cursor: pointer;
color: #00000073;
font-size: 12px;
flex-shrink: 0;
line-height: 1;
padding: 0 4px;
border-radius: 2px;
transition: all 0.3s;
`
closeBtn.onmouseover = () => {
closeBtn.style.backgroundColor = 'rgba(0, 0, 0, 0.06)'
}
closeBtn.onmouseout = () => {
closeBtn.style.backgroundColor = 'transparent'
}
closeBtn.onclick = close
message.appendChild(closeBtn)
}
// 自动关闭
if (duration > 0) {
setTimeout(close, duration)
}
}
// 添加快捷方式
;['success', 'info', 'warning', 'error'].forEach(type => {
showMessage[type] = (text, options = {}) => {
return showMessage(text, { ...options, type })
}
})