js弹出框自定义(js实现弹出框的插件)

今天给小伙伴们分享一个全新开发的React自定义对话框最近RLayer。 rlayer基于react.js开发的PC桌面端交互式弹出框组件。融合了Dialog、Message、Notification、ActionSheet、Toast、Popover、Popconfirm等多种功能。 看名称就能联想到前端界有名的弹窗layer.js,其实在设计开发之初就有借鉴layer插件实现思想。 功能 提供…

今日给小伙伴们共享一个全新升级研发的React自定义提示框近期RLayer。

超赞 React.js 桌面端自定义弹窗组件RLayer

rlayer 根据react.js开发设计的PC桌面端互动式弹出框组件。结合了Dialog、Message、Notification、ActionSheet、Toast、Popover、Popconfirm等各种作用。

超赞 React.js 桌面端自定义弹窗组件RLayer

看名字就能想到到前面界知名的弹窗layer.js,实际上在开发设计之初就会有参考layer软件完成观念。

超赞 React.js 桌面端自定义弹窗组件RLayer

作用

  • 给予函数公式式启用方式 rlayer({…})
  • 12 弹窗种类 (toast | footer | actionsheet | actionsheetPicker | android/ios | contextmenu | drawer | iframe | message | notify | popover)
  • 7 种弹窗动漫 (scaleIn | fadeIn | footer | fadeInUp | fadeInDown | fadeInLeft | fadeInRight)

引进组件

在必须应用组件的网页页面引进rlayer组件。

// 引入弹窗组件RLayer
import rlayer from \'./components/rlayer\'

迅速应用

引进后就可以根据函数公式rlayer({…})来启用就可以。

适用超出30 个主要参数随意配搭,迅速完成个性定制化的各种各样实际效果。

// msg信息
const showMsg = () => {
    rlayer({
        content: \"这也是一条msg系统消息\",
        shadeClose: false,
        xclose: false,
        time: 2
    })
}

// confirm了解框
const showConfirm = () => {
    let $el = rlayer({
        title: \'询问文章标题\',
        content: \"<div style=\'color:#0070f3;padding:30px;\'>确定框(这儿是确定框信息提示,这儿确定框信息提示,这儿是确定框信息提示)</div>\",
        shadeClose: false,
        zIndex: 1001,
        lockScroll: false,
        resize: true,
        dragOut: true,
        btns: [
            {
                text: \'撤销\',
                click: () => {
                    $el.close()
                }
            },
            {
                text: \'明确\',
                style: {color: \'#61dafb\'},
                click: () => {
                    handleInfo()
                }
            }
        ]
    })
}
超赞 React.js 桌面端自定义弹窗组件RLayer
超赞 React.js 桌面端自定义弹窗组件RLayer
超赞 React.js 桌面端自定义弹窗组件RLayer
超赞 React.js 桌面端自定义弹窗组件RLayer
超赞 React.js 桌面端自定义弹窗组件RLayer
超赞 React.js 桌面端自定义弹窗组件RLayer

RLayer弹窗模版

class RLayerComponent extends React.Component {
    // ...

    render() {
        let opt = this.state

        return (
            <>
            <div className={domUtils.classNames(\'rui._layer\', {\'rui__layer-closed\': opt.closeCls})} id={opt.id} style={{display: opt.opened?\'block\':\'none\'}}>
                {/* 蒙板 */}
                { opt.shade && <div className=\"rlayer._overlay\" onClick={this.shadeClicked} style={{opacity: opt.opacity}}></div> }
                {/* 文本框 */}
                <div className={domUtils.classNames(\'rlayer._wrap\', opt.anim&&\'anim-\' opt.anim, opt.type&&\'popui__\' opt.type, opt.drawer&&\'popui._drawer-\' opt.drawer, opt.xclose&&\'rlayer-closable\', opt.tipArrow)} style={{...opt.layerStyle}}>
                { opt.title && <div className=\'rlayer._wrap-tit\' dangerouslySetInnerHTML={{__html: opt.title}}></div> }
                { opt.type == \'toast\' && opt.icon ? <div className={domUtils.classNames(\'rlayer._toast-icon\', \'rlayer__toast-\' opt.icon)} dangerouslySetInnerHTML={{._html: opt.toastIcon[opt.icon]}}></div> : null }
                <div className=\'rlayer__wrap-cntbox\'>
                    { opt.content ? 
                    <>
                        {
                        opt.type == \'iframe\' ? 
                        (
                            <iframe scrolling=\'auto\' allowtransparency=\'true\' frameBorder=\'0\' src={opt.content}></iframe>
                        )
                        : 
                        (opt.type == \'message\' || opt.type == \'notify\' || opt.type == \'popover\') ? 
                        (
                            <div className=\'rlayer._wrap-cnt\'>
                            { opt.icon && <i className={domUtils.classNames(\'rlayer-msg__icon\', opt.icon)} dangerouslySetInnerHTML={{._html: opt.messageIcon[opt.icon]}}></i> }
                            <div className=\'rlayer-msg__group\'>
                                { opt.title && <div className=\'rlayer-msg._title\' dangerouslySetInnerHTML={{__html: opt.title}}></div> }
                                { typeof opt.content == \'string\' ? 
                                <div className=\'rlayer-msg._content\' dangerouslySetInnerHTML={{__html: opt.content}}></div>
                                :
                                <div className=\'rlayer-msg._content\'>{opt.content}</div>
                                }
                            </div>
                            </div>
                        )
                        : 
                        (
                            typeof opt.content == \'string\' ? 
                            (<div className=\'rlayer__wrap-cnt\' dangerouslySetInnerHTML={{._html: opt.content}}></div>)
                            :
                            opt.content
                        )
                        }
                    </>
                    :
                    null
                    }
                </div>
                {/* btns */}
                { opt.btns && <div className=\'rlayer__wrap-btns\'>
                    {
                        opt.btns.map((btn, index) => {
                            return <span className={domUtils.classNames(\'btn\', {\'btn-disabled\': btn.disabled})} key={index} style={{...btn.style}} dangerouslySetInnerHTML={{._html: btn.text}} onClick={this.btnClicked.bind(this, index)}></span>
                        })
                    }
                    </div>
                }
                { opt.xclose && <span className={domUtils.classNames(\'rlayer._xclose\', !opt.maximize&&opt.xposition)} style={{color: opt.xcolor}} onClick={this.close}></span> }
                { opt.maximize && <span className=\'rlayer__maximize\' onClick={this.maximizeClicked}></span> }
                { opt.resize && <span className=\'rlayer._resize\'></span> }
                </div>
                {/* 修补拖动卡屏 */}
                <div className=\'rlayer._dragfix\'></div>
            </div>
            </>
        )
    }
}

默认设置参数配置

class RLayerComponent extends React.Component {
    /**
     * 弹出框默认配备
     */
    static defaultProps = {
        // 主要参数
        id: \'\',                       // {string} 操纵弹层唯一标志,同样id共享资源一个案例
        title: \'\',                    // {string} 文章标题
        content: \'\',              // {string|element} 內容(适用字符串数组或部件)
        type: \'\',                   // {string} 弹窗种类
        layerStyle: \'\',          // {object} 自定弹窗款式
        icon: \'\',                  // {string} Toast标志(loading|success|fail)
        shade: true,           // {bool} 是不是表明遮罩层
        shadeClose: true,    // {bool} 是不是点一下遮罩层关掉弹窗
        lockScroll: true,       // {bool} 是不是弹窗表明时将body翻转锁住
        opacity: \'\',                // {number|string} 遮罩层清晰度
        xclose: true,             // {bool} 是不是表明关闭图标
        xposition: \'right\',     // {string} 关闭图标部位(top|right|bottom|left)
        xcolor: \'#333\',         // {string} 关闭图标色调
        anim: \'scaleIn\',        // {string} 弹窗动漫
        position: \'auto\',      // {string|array} 弹窗部位
        drawer: \'\',               // {string} 抽屉柜弹窗(top|right|bottom|left)
        follow: null,            // {string|array} 追随精准定位弹窗
        time: 0,                  // {number} 弹框全自动关掉分秒(1|2|3...)
        zIndex: 8090,        // {number} 弹窗重叠
        topmost: false,      // {bool} 是不是顶置现阶段弹窗
        area: \'auto\',           // {string|array} 弹框高宽
        maxWidth: 375,    // {number} 弹窗较大总宽(仅有当area:\'auto\'时设置才合理)
        maximize: false,     // {bool} 是不是表明利润最大化按键
        fullscreen: false,      // {bool} 是不是全屏幕弹窗
        fixed: true,                  // {bool} 是不是固定不动弹窗
        drag: \'.rlayer._wrap-tit\',    // {string|bool} 拖动原素
        dragOut: false,               // {bool} 是不是容许拖动到电脑浏览器外
        lockAxis: null,         // {string} 限定拖动方位可选: v 竖直、h 水准,默认设置不限定
        resize: false,           // {bool} 是不是容许拉申弹窗
        btns: null,              // {array} 弹框按键(主要参数:text|style|disabled|click)

        // 事情
        success: null,         // {func} 层弹出来后调整
        end: null,              // {func} 层消毁后调整
    }
	// ...
}
/**
 * ReactJs|Next.js弹出框部件RLayer
 */
import React from \'react\'
import ReactDOM from \'react-dom\'

// 引入操作类
import domUtils from \'./utils/dom\'

let $index = 0, $lockCount = 0, $timer = {}

class RLayerComponent extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            // ...
        }

        this.closeTimer = null
    }

    componentDidMount() {
        window.addEventListener(\'resize\', this.autopos, false)
    }
    componentWillUnmount() {
        window.removeEventListener(\'resize\', this.autopos, false)
        clearTimeout(this.closeTimer)
    }

    /**
     * 打开弹框
     */
    open = (options) => {
        options.id = options.id || `rlayer-${domUtils.generateId()}`

        this.setState({
            ...this.props, ...options, opened: true,
        }, () => {
            const { success } = this.state
            typeof success === \'function\' && success.call(this)

            this.auto()
            this.callback()
        })
    }

    /**
     * 关掉弹框
     */
    close = () => {
        const { opened, time, end, remove, rlayerOpts, action } = this.state
        if(!opened) return

        this.setState({ closeCls: true })
        clearTimeout(this.closeTimer)
        this.closeTimer = setTimeout(() => {
            this.setState({
                closeCls: false,
                opened: false,
            })
            if(rlayerOpts.lockScroll) {
                $lockCount--
                if(!$lockCount) {
                    document.body.style.paddingRight = \'\'
                    document.body.classList.remove(\'rc-overflow-hidden\')
                }
            }
            if(time) {
                $index--
            }
            if(action == \'update\') {
                document.body.style.paddingRight = \'\'
                document.body.classList.remove(\'rc-overflow-hidden\')
            }
            rlayerOpts.isBodyOverflow && (document.body.style.overflow = \'\')
            remove()
            typeof end === \'function\' && end.call(this)
        }, 200);
    }

    // 弹框部位
    auto = () => {
        // ...
    }

    autopos = () => {
        const { opened, id, fixed, follow, position } = this.state
        if(!opened) return
        let oL, oT
        let dom = document.querySelector(\'#\'   id)
        let rlayero = dom.querySelector(\'.rlayer._wrap\')

        if(!fixed || follow) {
            rlayero.style.position = \'absolute\'
        }

        let area = [domUtils.client(\'width\'), domUtils.client(\'height\'), rlayero.offsetWidth, rlayero.offsetHeight]

        oL = (area[0] - area[2]) / 2
        oT = (area[1] - area[3]) / 2

        if(follow) {
            this.offset()
        } else {
            typeof position === \'object\' ? (
                oL = parseFloat(position[0]) || 0, oT = parseFloat(position[1]) || 0
            ) : (
                position == \'t\' ? oT = 0 : 
                position == \'r\' ? oL = area[0] - area[2] : 
                position == \'b\' ? oT = area[1] - area[3] : 
                position == \'l\' ? oL = 0 : 
                position == \'lt\' ? (oL = 0, oT = 0) : 
                position == \'rt\' ? (oL = area[0] - area[2], oT = 0) : 
                position == \'lb\' ? (oL = 0, oT = area[1] - area[3]) :
                position == \'rb\' ? (oL = area[0] - area[2], oT = area[1] - area[3]) : 
                null
            )

            rlayero.style.left = parseFloat(fixed ? oL : domUtils.scroll(\'left\')   oL)   \'px\'
            rlayero.style.top = parseFloat(fixed ? oT : domUtils.scroll(\'top\')   oT)   \'px\'
        }
    }

    // 追随原素精准定位
    offset = () => {
        const { id, follow } = this.state
        let oW, oH, pS
        let dom = document.querySelector(\'#\'   id)
        let rlayero = dom.querySelector(\'.rlayer._wrap\')

        oW = rlayero.offsetWidth
        oH = rlayero.offsetHeight
        pS = domUtils.getFollowRect(follow, oW, oH)

        this.setState({ tipArrow: pS[2] })

        rlayero.style.left = pS[0]   \'px\'
        rlayero.style.top = pS[1]   \'px\'
    }

    // 利润最大化弹框
    full = () => {
        // ...
    }

    // 修复弹框
    restore = () => {
        const { id, maximize, rlayerOpts } = this.state
        let dom = document.querySelector(\'#\'   id)
        let rlayero = dom.querySelector(\'.rlayer._wrap\')
        let otit = dom.querySelector(\'.rlayer__wrap-tit\')
        let ocnt = dom.querySelector(\'.rlayer._wrap-cntbox\')
        let obtn = dom.querySelector(\'.rlayer__wrap-btns\')
        let omax = dom.querySelector(\'.rlayer._maximize\')

        let t = otit ? otit.offsetHeight : 0
        let b = obtn ? obtn.offsetHeight : 0

        if(!rlayerOpts.lockScroll) {
            rlayerOpts.isBodyOverflow = false
            this.setState({rlayerOpts})
            document.body.style.overflow = \'\'
        }

        maximize && omax.classList.remove(\'maximized\')

        rlayero.style.left = parseFloat(rlayerOpts.rect[0])   \'px\'
        rlayero.style.top = parseFloat(rlayerOpts.rect[1])   \'px\'
        rlayero.style.width = parseFloat(rlayerOpts.rect[2])   \'px\'
        rlayero.style.height = parseFloat(rlayerOpts.rect[3])   \'px\'
        ocnt.style.height = parseFloat(rlayerOpts.rect[3] - t - b)   \'px\'
    }

    // 拖动|放缩弹窗
    move = () => {
        // ...
    }

    // 事故处理
    callback = () => {
        const { time } = this.state
        // 倒数计时关掉弹窗
        if(time) {
            $index  
            // 避免反复记数
            if($timer[$index] != null) clearTimeout($timer[$index])
            $timer[$index] = setTimeout(() => {
                this.close()
            }, parseInt(time) * 1000);
        }
    }

    // 点一下利润最大化按键
    maximizeClicked = (e) => {
        let o = e.target
        if(o.classList.contains(\'maximized\')) {
            // 修复
            this.restore()
        } else {
            // 利润最大化
            this.full()
        }
    }

    // 点一下遮罩层
    shadeClicked = () => {
        if(this.state.shadeClose) {
            this.close()
        }
    }

    // 按键事情
    btnClicked = (index, e) => {
        let btn = this.state.btns[index]
        if(!btn.disabled) {
            typeof btn.click === \'function\' && btn.click(e)
        }
    }
}
超赞 React.js 桌面端自定义弹窗组件RLayer
超赞 React.js 桌面端自定义弹窗组件RLayer

好啦,以上便是根据React.js完成PC端弹出框部件,期待对我们有些协助哈!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年5月6日 下午6:45
下一篇 2022年5月6日 下午6:46

相关推荐

  • seo怎么做外链,seo增加外链的技巧

    当网站建好并优化好之后,也应采用一些方法来推广网站,增加网站的反向链接数,有了反向链接,搜索引擎才能更快地找到你的站点并收录,如何增加外链对网站优化和关键词排名来讲非常的重要,可以提高网站的权重,获得好的排名,也可以带来不错的流量,因此对一个站长来讲,必须掌握一些如何增加外链技巧和原则。 网站优化推广必须掌握的增加外链技巧和原则 一、增加外链的技巧 1、做友情连接,如果是单向连接那更好,就是别人的…

    2022年8月12日
    540
  • 2019年车市怎么样(2019年车市图解)

    随着2020年新年钟声的敲响,2019年车市终于落下了大幕。看过之前每个月销量总结的读者一定记得,2019年每个月的销量都伴随着同比下滑。自然而然,2019年全年也是继2018年之后,中国车市首次出现连续两年下滑,不管风光也好还是落寞也罢,下面我们就用10张表格来对2019年车市做一个总结。 1.2019年中国汽车产销分别完成2572.1万辆和2576.9万辆,产销量分别下降7.5%和8.2%,产…

    2022年5月2日
    880
  • 男版t恤有哪些款式(2020年流行男士t恤)

    说到夏天穿的最多的单品,那一定是T恤,几乎每个人的衣橱里有不下20件不同款式的Tee。一件舒适的白T,是夏天的必不可少的万能单品,可单穿、可叠穿,可以与各种单品搭配。 一件T恤款式简单,颜色多变,随便怎么穿都可以,但是你是否会遇到洗后领口松垮、机洗两次就变形或者越洗越大等种种问题,让一件T恤活不过夏季。 今天小编就教你几招,让你夏日买T恤不踩雷。 NO.1关于材质 某宝购物时经常会看到商家的广告语…

    2022年9月25日
    680
  • 富士镜头推荐(最实用切值得购买的富士镜头有哪些)

    2019年中,富士发布了新镜头XF16-80mmF4ROISWR,这支镜头已经是富士X系统下的第三支标准变焦镜头了。考虑到之前富士推出的两枚标准变焦镜头XF16-55mmF2.8RLMWR与XF18-55mmF2.8-4RLMOIS也一直颇受好评,那么我们在这三支标准镜头里该怎么选择呢?今天我们就来简单测试一下这三支镜头的画质表现,希望能给大家在选择时提供一些帮助。 首先我们把这三支镜头的规格参数…

    2022年8月25日
    2530
  • 游戏准星辅助器制作(游戏辅助软件大全)

    为什么有人愿意花费大几千去买一款专业的游戏手机?毫无疑问,这类机型确实拥有更顶级的硬件配置,更炫酷的外观设计,但在我看来不仅如此,游戏手机之所以能吸引众多玩家,更多的是它考虑到了玩家的真正需求,各厂商系统内置的“游戏助手”便是其中一项体现。作为重度手游玩家的我,在上半年的“新机潮”中,经过多方对比选择了ROG游戏手机5。新机入手至今用了也有将近一个多月的时间了,今天抽空给大家分享一波,该机系统内置…

    2022年5月12日
    870
  • 欧莱雅隔离霜哪款好用(4款持久防晒防水的防晒霜)

    夏天似乎离我们越来越近了,防晒也成为了必不可少的功课!当然,防晒隔离一年四季都不能少,更何况春天的紫外线照射程度并不亚于夏天,紫外线中的UVA更是无处不在,所以这一期的测评魔方君选择了口碑和性价比都不错的欧莱雅防晒修护隔离露! 欧莱雅多重修护隔离露是欧莱雅UVPerfect系列中的产品,SPF50+,PA++++,除了持久防晒,还能够抵御色斑及光老化,其中水漾保湿精华和长线隔离乳也属于隔离露的产品…

    2022年9月28日
    900
  • 笔记本内存条推荐哪个品牌好,十款值得购买的笔记本内存条

    为了辅助电脑的核心工作,完成存储和读取的功能,内存条是电脑装机中举足轻重的存在。现在选购内存的话,一般也是选择最新的DDR4规格。但是现在市场下,有哪些不同品牌的内存条值得选购呢?下面就来根据慢慢买的排行榜,了解一下现在的各个品牌都有什么值得买的内存条吧~ 金士顿 推荐型号:金士顿(Kingston)DDR426668GB骇客神条Fury雷电系列 品牌点评:金士顿科技结合了内存行业广泛、严格的测试…

    2022年9月7日
    3590
  • 熊猫直播为什么凉了,揭秘其破产背后缘由

    据网友爆料,熊猫直播官网已经无法打开,经小编验证后发现确实如此。 3月7日晚22时,熊猫直播创始团队成员兼首席运营官张菊元在内部工作群中发长消息称,在2017年5月获得B轮10亿人民币融资后,至今没有外部资金注入,在资金缺口无法解决情况下做出了遣散员工的决定。这在业界看来释放了一个信号——公司“凉了”。 3月8日,@熊猫直播官微发文称,“熊猫直播主站流浪计划,第一阶段开启。工程师请逐渐断开与母星连…

    2022年5月27日
    850
  • icloud怎么备份通讯录,其实方法非常简单不会的朋友赶紧过来看看

    最近经常会有苹果用户咨询小编关于苹果手机怎么复制通讯录的问题,确实因为苹果系统的限制,我们无法像安卓用户那样通过复制到SIM卡的方式来复制和备份通讯录。那么苹果手机怎么备份通讯录呢? 其实,苹果用户可以通过苹果公司的一款备份工具来完成iPhone通讯录的备份工作:iCloud。那么如何通过iCloud备份iPhone通讯录? 方法其实非常简单,我们打开手机【设置】-【iCloud】-【备份】,开启…

    2022年8月23日
    1390
  • 马云有多少亿人民币,2019年中国首富排名

    马云目前资产3092亿人民币,美元449亿 2019年排名 1杰夫·贝佐斯1118亿美元亚马逊美国 2比尔·盖茨1032亿美元微软美国 3伯纳德·阿诺特962亿美元LVMH法国 4沃伦•巴菲特790亿美元伯克希尔-哈撒韦公司美国 5阿曼西奥·奥特加681亿美元Zara西班牙 6马克·扎克伯格674亿美元Facebook美国 7拉里·埃里森646亿美元甲骨文软件美国 8迈克尔·布隆伯格562亿美元彭…

    2022年6月13日
    1030

发表回复

登录后才能评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信