html div toast,React实现全局组件:Toast轻提示

Toast是常用的轻提示弹框,常用于页面loading和提示语弹窗。

本例基于React实现一个随时可调用且不随页面渲染的全局组件。

如何使用

首先引入

import Toast from './components/toast'

JSX中事件调用:

{ Toast.info('普通提示') }}>普通提示

JS中方法调用:

Toast.info('普通提示')

回调方法:

const hideLoading = Toast.loading('加载中...', 0, () => {

Toast.success('加载完成')

})

setTimeout(hideLoading, 2000)

调用规则:

3个参数:

content 提示内容 string(loading方法为可选)

duration 提示持续时间 number,单位ms(可选)

onClose 提示关闭时的回调函数(可选)

Toast.info("普通",2000)

Toast.success("成功",1000,() => {

console.log('回调方法')

}))

Toast.error("错误")

Toast.loading()

代码实现

目录结构:

bVbhhtk?w=101&h=90

index.js:对外export接口,设置默认的参数值,全局创建或销毁Toast的DIV。

toast.js:Toast具体显示的内容及多次调用Toast时的状态管理。

toast.css:Toast的样式,费话不多说。

index.js:

import React from 'react'

import ReactDOM from 'react-dom'

import Toast from './toast'

import './toast.css'

function createNotification() {

const div = document.createElement('div')

document.body.appendChild(div)

const notification = ReactDOM.render(, div)

return {

addNotice(notice) {

return notification.addNotice(notice)

},

destroy() {

ReactDOM.unmountComponentAtNode(div)

document.body.removeChild(div)

}

}

}

let notification

const notice = (type, content, duration = 2000, onClose) => {

if (!notification) notification = createNotification()

return notification.addNotice({ type, content, duration, onClose })

}

export default {

info(content, duration, onClose) {

return notice('info', content, duration, onClose)

},

success(content = '操作成功', duration, onClose) {

return notice('success', content, duration, onClose)

},

error(content, duration , onClose) {

return notice('error', content, duration, onClose)

},

loading(content = '加载中...', duration = 0, onClose) {

return notice('loading', content, duration, onClose)

}

}

toast.js:

import React, { Component } from 'react'

class ToastBox extends Component {

constructor() {

super()

this.transitionTime = 300

this.state = { notices: [] }

this.removeNotice = this.removeNotice.bind(this)

}

getNoticeKey() {

const { notices } = this.state

return `notice-${new Date().getTime()}-${notices.length}`

}

addNotice(notice) {

const { notices } = this.state

notice.key = this.getNoticeKey()

// notices.push(notice);//展示所有的提示

notices[0] = notice;//仅展示最后一个提示

this.setState({ notices })

if (notice.duration > 0) {

setTimeout(() => {

this.removeNotice(notice.key)

}, notice.duration)

}

return () => { this.removeNotice(notice.key) }

}

removeNotice(key) {

const { notices } = this.state

this.setState({

notices: notices.filter((notice) => {

if (notice.key === key) {

if (notice.onClose) setTimeout(notice.onClose, this.transitionTime)

return false

}

return true

})

})

}

render() {

const { notices } = this.state

const icons = {

info: 'toast_info',

success: 'toast_success',

error: 'toast_error',

loading: 'toast_loading'

}

return (

{

notices.map(notice => (

{notice.content}

))

}

)

}

}

export default ToastBox

toast.css:

.toast {

position: fixed;

left: 0;

top: 0;

z-index: 999;

display: flex;

flex-direction: column; }

.toast_bg {

position: fixed;

width: 100%;

height: 100%;

left: 0;

top: 0; }

.toast_box {

position: relative;

left: 50%;

top: 50%;

width: 2.8rem;

height: 2rem;

margin: -1rem -1.4rem;

background: rgba(0, 0, 0, 0.65);

border-radius: .1rem;

color: #fff; }

.toast_text {

position: absolute;

bottom: 16%;

text-align: center;

width: 90%;

margin: 0 5%;

height: .28rem;

overflow: hidden;

text-overflow: ellipsis;

white-space: nowrap; }

.toast_icon {

position: relative;

left: 50%;

top: 15%;

margin: -.4rem;

width: .8rem;

height: .8rem; }

.toast_loading {

-webkit-animation: loading 1s steps(12, end) infinite;

animation: loading 1s steps(12, end) infinite;

background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAM1BMVEUAAAD///+3leKCAAAAEHRSTlMAENCA8KAgsGDgQMCQUDBwhylaLQAAAL1JREFUOMu9U0kSwyAMK9jsS/T/1zZt2pgEZzq9RBeMZYRGDI/70bO5JptjrOAQVTonIJVK5bW2ma9A7VvpK8OdeQfbZectrDnyU+Oo0b68wGK0muDPdxpOciaizq5pkAgiIPAoew2rBVNYZoM2YHbZDNKz/2Ogam3ff5gMEL8wisfh2KKZiFiGWFkk1B7NSbhNQFy4M2+PghbODNsg7y8THM2njiy8gBgcaEUA9GgNJbxh6fJv+NxiFvYmPAFtCQZNK1qZIAAAAABJRU5ErkJggg==") no-repeat;

background-size: 100%; }

.toast_success {

background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAM1BMVEUAAAD///+3leKCAAAAEHRSTlMA8DAQ0GBP4LCggMBwIJBAIttdjAAAAINJREFUOMvdkUsOwyAMBbH5hUCauf9pK1SlohF438x2LPn52f09+8vUfiNb/gighj8FouEjYCUoQDXiBSD7pdcMiK7XC9wCFmlDO3T20Scgx287ne13pwDU89NOJ3g3maCmJDANqIGRtLj8oi1ed1GMdmcB7wXIYX8QdQZJiM5Em3smbyVICDCOrCqSAAAAAElFTkSuQmCC") no-repeat;

background-size: 100%; }

.toast_error {

background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAAMFBMVEUAAAD///87TQQwAAAAD3RSTlMA0BDAMODwUKBgsCCAQJClzVPvAAAA0UlEQVQoz2MgErAclv9o44Dgc8b/B4KvBTA+t/3XdgeWivjPG6ACbl8ngNXlp0AN+L8IwtD6DzFm2w+Y3v5sMGW/ACbA9Rms9ZsCTIApH2QR608GhoUKQJ4xA8P8AKCAP5CwF2JgUPwIlPwCFDj/AMRRYJIHCnL8AZkJ1AfkAcUYGNhBpso7MICUgBQw8H4EEv/B5ssDFYA4mAKYWjANfd+Aai3CYZ9BDoM63RDkdEGQ0zE9h+l9zADCDEIGt2/wQEZEwwVepGhgYEdEFGZUEgYAW05XI3jSsVwAAAAASUVORK5CYII=") no-repeat;

background-size: 100%; }

.toast_info {

background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgBAMAAACBVGfHAAAALVBMVEUAAAD///+hSKubAAAADnRSTlMA4CCAwKBAMJBg8NAQUNhWlbcAAAC+SURBVCjPYyASsLfse+1cgOBzyr0DgocXYHwmv4dtCkwZck8UoAJZDydA1C2H8NnexUAYR99BjNF6CtMbtwhM+QUACUUhIMH6BKz14QEgafcYSPDIgSxifMkAE2CYJwAk6gQQAozPgURfA0KAA0T6JSAE2ECm7lNACDC9BhLvGGACIA6GAFyLohBEC9xQqLeeQKwFA4i1EIfBAeNzuNMVhSBOx/AcpvcxAwgzCDEDGTMaGHhhEYWIShN4VBIGAPvRT5YzufhUAAAAAElFTkSuQmCC") no-repeat;

background-size: 100%; }

@-webkit-keyframes loading {

0% {

-webkit-transform: rotate3d(0, 0, 1, 0deg);

transform: rotate3d(0, 0, 1, 0deg); }

100% {

-webkit-transform: rotate3d(0, 0, 1, 360deg);

transform: rotate3d(0, 0, 1, 360deg); } }

@keyframes loading {

0% {

-webkit-transform: rotate3d(0, 0, 1, 0deg);

transform: rotate3d(0, 0, 1, 0deg); }

100% {

-webkit-transform: rotate3d(0, 0, 1, 360deg);

transform: rotate3d(0, 0, 1, 360deg); } }

应用例子:axios全局请求加loading特效

import axios from 'axios';

import Toast from '../routes/components/toast';

const mAxios = axios.create({

baseURL:"/api/h5/",

timeout: 10000,

withCredentials: true,

headers: {

'X-Requested-With': 'XMLHttpRequest',

'Content-Type': 'application/x-www-form-urlencoded'

},

})

window.ajaxNum = 0

mAxios.interceptors.request.use(config => {

window.ajaxNum ++

window.ToastLoding = Toast.loading()

return config

}, error => {

console.error(`error reject`)

return Promise.reject(error)

})

mAxios.interceptors.response.use(res => {

window.ajaxNum--

checkAjaxConnet()

let status = res.status

let data = res.data

if(status >= 200 && status < 400 && data.code === '0'){

return data.data

}

}, error => {

window.ajaxNum--

Toast.error('网络异常',3000)

return Promise.reject(error)

})

//所有请求完成之后才可以关闭弹窗,防止多次请求弹窗抖动

function checkAjaxConnet() {

if(window.ajaxNum < 1) {

setTimeout(window.ToastLoding)

}

}

export default mAxios;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值