【React.js 队列弹窗】

使用方式:

	import Demo from "./components/demo/demo.jsx";
	/**
	* 注册弹窗 
	* @param {*} enumComKey 弹窗类名Key
	* @param {*} components 弹窗
	*/
    registerWin("Demo", Demo)
	/**
	* 展示弹窗
	* @param {*} enumComKey 弹窗类名
 	* @param {*} data 数据 默认{}
 	* @param {*} immediateShow 插队 默认false
 	* @param {*} clickGrayClose 点击灰色背景 默认false
 	* @param {*} animation 动画 默认syn_zoom
	*/
	 showWin("Demo", this.props.data, true,false,'syn_zoom')

	/**
	* 弹窗demo
	* @param {*} closeWin 如何关闭弹窗
	*/
	'use strict';
	import React, { Component } from 'react';
	class Demo extends Component {
	  constructor(props) {
	    super(props);
	  }
	  render() {
	    return (
	      <div className="demo" onClick={()=>this.props.closeWin()}></div>
	    );
	  }
	}
	export default Demo;

代码:

import React, {
    Component
} from 'react';
import ReactDOM from "react-dom";


//默认的弹窗动画,注意命名syn_防止和其他className重名
const syn_zoom = `
.syn_zoom {
    animation: syn_zoom 0.3s linear 0s 1;
}
@keyframes syn_zoom {
    0% {
      -webkit-transform: scale(0);
      transform: scale(0);
    }
  
    66% {
      -webkit-transform: scale(1.1);
      transform: scale(1.1)
    }
  
    100% {
      -webkit-transform: scale(1);
      transform: scale(1)
    }
}`

const syn_fade_in = `
.syn_fade_in {
    animation: syn_fade_in 0.3s linear 0s 1;
}
@keyframes syn_fade_in {
    0% {
       opacity:0;
    }
  
    100% {
      opacity:1;
    }
}
`


const anis = [syn_zoom, syn_fade_in]



export const PopCtrl = (function () {
    function PopCtrl() {
        //弹窗注册Map
        this._popMap = new Map()
        // 存储所有弹出的弹窗
        this._wins = []
        //最外层div
        this.m = null
        //弹窗灰蒙层
        this.b = null
        //当前的弹窗
        this._nowWin = null
        //已显示被插队的弹窗
        this._hideWins = []
        //已显示被插队的弹窗dom
        this._hideDomWins = []
    }

    PopCtrl.getInstance = function () {
        if (PopCtrl.ins == null) {
            PopCtrl.ins = new PopCtrl()
            //初始化弹窗蒙层
            PopCtrl.ins.createWinBg()
            //添加默认动画配置    
            PopCtrl.ins.addAni(anis)
        }
        return PopCtrl.ins
    }

    PopCtrl.prototype.createWinBg = function () {
        this.m = document.createElement('div');
        this.b = document.createElement('div');
        this.m.appendChild(this.b)
        this.m.style.cssText = 'z-index:1999'
        this.b.style.cssText = 'z-index:1999;width:750px; height:1624px; background:#000; position:fixed; left:0; top:0; opacity:0.6;'
        document.body.appendChild(this.m);
        //默认隐藏
        this.m.style.display = "none"

        this.b.addEventListener("click", (...arg) => {
            this.closeWin(...arg)
        }, this)
    }

    PopCtrl.prototype.addAni = function (anis) {
        // 创建style标签
        const style = document.createElement('style');
        // 将 keyframes样式写入style内
        anis.forEach(ani => style.innerHTML += ani)
        // 将style样式存放到head标签
        document.getElementsByTagName('head')[0].appendChild(style);
    }


    PopCtrl.prototype.registerWin = function (key, T) {
        this._popMap.set(key, T)
    }

    PopCtrl.prototype.insertWin = function (enumComKey, data = {}, immediateShow = false, clickGrayClose = false, animation = "syn_zoom") {
        const T = this._popMap.get(enumComKey)
        if (!T) {
            console.error(enumComKey + " 弹窗未配置")
            return
        }
        //显示蒙层
        this.m.style.display = ""
        const win = {
            T,
            data,
            clickGrayClose,
            animation
        }

        if (!immediateShow) {
            //把弹窗放入,只显示第一个
            this._wins.push(win)
            if (!this._nowWin) {
                this.showWin()
            }
        } else {
            if (this._nowWin) {
                this.m.removeChild(this.n)
                this._hideDomWins.push(this.n)
                this._hideWins.push(this._nowWin)
                this._nowWin = null
            }

            //插队
            this._wins.unshift(win)
            this.showWin()
        }
    }


    PopCtrl.prototype.showWin = function () {
        this._nowWin = this._wins.shift()
        if (this._nowWin) {
            //弹窗渲染div
            this.n = document.createElement('div');
            //点击灰色区域关闭
            if (this._nowWin.clickGrayClose) {
                this.n.style.pointerEvents = "none"
                this.b.style.pointerEvents = ""
            } else {
                this.b.style.pointerEvents = "none"
            }
            this.n.style.width = '100%'
            this.n.style.height = '100%'
            this.n.style.zIndex = 1999
            this.n.style.top = 0
            this.n.style.position = "fixed"
            //弹窗动画 防止className重复
            this.n.className = this._nowWin.animation
            this.m.appendChild(this.n)

            document.body.style.overflowY = "hidden"
            document.body.style.position = "fixed"


            const T = < this._nowWin.T closeWin = {
                (...arg) => {
                    this.closeWin(...arg)
                }
            }
            data = {
                this._nowWin.data
            }
            />
            ReactDOM.render(T, this.n);
        }
    }


    PopCtrl.prototype.resumeWin = function () {
        this.m.appendChild(this.n)

        document.body.style.overflowY = "hidden"
        document.body.style.position = "fixed"


        const T = < this._nowWin.T closeWin = {
            (...arg) => {
                this.closeWin(...arg)
            }
        }
        data = {
            this._nowWin.data
        }
        />
        ReactDOM.render(T, this.n);
    }

    PopCtrl.prototype.closeWin = function (cb) {
        this._nowWin = null
        //整个移除,执行回调
        this.m.removeChild(this.n)

        if (this._hideDomWins.length > 0) {
            this.n = this._hideDomWins.pop()
            this._nowWin = this._hideWins.pop()
            this.resumeWin()
            return
        }


        if (typeof cb == 'function') {
            try {
                cb()
            } catch (error) {
                console.log(error)
            }
        }

        if (this._wins.length == 0 && !this._nowWin) {
            document.body.style.overflowY = "auto"
            document.body.style.position = ""
        }

        //存在弹下一个,并且没有弹下一个,否则隐藏蒙层
        this._wins[0] ? !this._nowWin && this.showWin() : !this._nowWin && (this.m.style.display = "none");
        if (this.m.style.display == "none") {
         //全部关闭的回调
        }
    }

    return PopCtrl

}())


/**
 * 显示弹窗
 * @param {*} enumComKey 弹窗类名
 * @param {*} data 数据 默认{}
 * @param {*} immediateShow 插队 默认false
 * @param {*} clickGrayClose 点击灰色背景 默认false
 * @param {*} animation 动画 默认syn_zoom
 */
export const showWin = (...arg) => {
    PopCtrl.getInstance().insertWin(...arg)
}


/**
 * 注册弹窗
 * @param {*} T 弹窗组件
 */
export const registerWin = (key, T) => {
    PopCtrl.getInstance().registerWin(key, T)
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个通用的Android端弹窗管理框架,内部维护弹窗优先级队列 具备弹窗管理扩展功能 整合Dialog,PoupoWindow,悬浮Widget,透明Webview,Toast,SnackBar,无需再为繁琐的业务弹窗逻辑所困扰如何添加依赖只需要两行代码轻松接入//add this to your repositories  maven { url 'https://www.jitpack.io' } //add this to your dependencies implementation 'com.github.MrCodeSniper:PopLayer:2.0.0'具体如何使用1.根据策略创建对应的弹窗view//Dialog形式 PopLayerView  mLayerView = new PopLayerView(this,R.layout.common_dialog_upgrade_app); //透明Webview形式 PopLayerView mLayerView = new PopLayerView(this,LayerConfig.redPocketScheme);2.开始装配弹窗配置Popi mUpgradePopi1 = new Popi.Builder()                 .setmPopId(4)//弹窗的唯一标识 当id发生改变 视为新的弹窗                 .setmPriority(2)//优先级这里不具体划分对应的范围 值越小优先级越高                 .setmCancelType(TRIGGER_CANCEL)//弹窗消失的类型分为 TRIGGER_CANCEL(触摸消失) COUNTDOWN_CANCEL (延时消失)                 .setMaxShowTimeLength(5)//最长显示时间(S)                 .setMaxShowCount(5)//最大显示次数                 .setmBeginDate(1548858028)//开始时间 2019-01-30 22:20:28                 .setmEndDate(1548944428)//结束时间 2019-01-31 22:20:28                 .setLayerView(mLayerView)//弹窗View                 .build();3.纳入弹窗管理//纳入弹窗管理 PopManager.getInstance().pushToQueue(mUpgradePopi); //开始显示弹窗 PopManager.getInstance().showNextPopi();效果预览未来的计划逐步统一 其他类型的弹窗 希望能提供给大家一个较为全面的应对业务需求的弹窗管理框架版本记录V1方案版本号LOG进度更新V1.0.0项目开源,完成弹窗管理与Dialog形式扩展Dialog策略扩展完成V1.0.1修复Dialog策略无法获取dialog实体bugDialog策略优化V1.0.2修复activity摧毁造成的弹窗异常 bugDialog策略优化V1.0.3优化了弹窗的使用更加方便快捷框架使用优化V2方案版本号LOG进度更新V2.0.0正式加入透明Webview弹窗策略扩展透明Webview策略扩展完成作者介绍Hello 我叫lalala,如果您喜欢这个项目 请给个star 能follow我那真是太好了!!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值