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

相关推荐

  • 创业顾问的工作内容是什么(公司职业顾问的日常工作)

    创业奉行“两强相争勇者胜”的亮剑精神,创业是需要有决策力、执行力、专注聚焦,并谋求最佳效果的要素组合的,是需要整个团队形成合力,全力以赴去实现阶段性共同目标的事情。但在现实中的很多创业者,不管是性格上,还是思维方式与行动导向方面,都未必与创业所需要的特色相适应。 不管是对内管理交流还是对外业务拓展与形象传播,创业的核心都需要讲求简单而直接的传播。但现实中,很多创业者都不知所云。比如把原本简单的业务…

    2022年10月25日
    600
  • 织围巾怎么起针,适合初学者的起针方法

    单元宝针的织法好学,用处也很广泛。可以织毛衣、织毛裤、织围巾、织袜子等等。弹性大,穿着舒服。 工具/原料毛线 毛衣针 方法/步骤1 织单元宝针首先起针,起针的针数要自己决定,根据你要织的是什么衣物,而决定起多少针;我起了20针;(如下图) 方法/步骤2 第一排,第一针,因为是边,挑在右针上不织,将线绕到上边;(如下图) 方法/步骤3 第二针也挑了不织;(如下图) 方法/步骤4 第三针织下针。右针穿…

    2022年9月27日
    510
  • 网站版面如何设计,网站布局遵循的原则及要点

    在工作之余整理了几幅国外博物馆的网站版面设计,在每个版面中,点、线、面的运用个人觉得都非常好。 其中在字体的运用上,选择文字的风格和大小时,都会考虑浏览者的视觉感受。在颜色的选择上,色彩的感觉是主观的,每个版面的色彩都其自已的文化含义,并且都存在着视觉联系。 好了,话不多说,请朋友们欣赏、借鉴、学习! 01 02 03 04 05 06 07 08 09 10

    2022年8月18日
    540
  • 网络营销书籍有哪些,这五本必看的经典书籍推荐

    1《广告人手记》 叶茂中大概是早期对我所理解的品牌营销策划方面影响最多的一个人,作为策划界操盘数十亿品牌最多的策划人,堪称营销界的一面旗帜。正如书封面所言:他影响了中国广告界。而大师于2013年9月10日在他的微博忏悔:“我干营销干广告24年,最难过的是为推广产品,编了太多的概念,不乏忽悠,给社会传递不少负能量。惭愧至极,忏悔至极。从今天起,挑企业,挑产品。挖掘真正的好产品推荐给消费者,向社会输出…

    2022年5月20日
    870
  • 电脑绘画软件推荐(电脑绘画app排行)

    很多刚刚开始学习或刚工作的设计专业新人,遇到的棘手问题就是找不到趁手的设计软件,也不知道如何加强操作。这篇文章我就来给大家分享八个windows系统可用的八个热门绘图软件供大家挑选。 Pixso——一款国内出品的矢量设计软件 作为本土研发的设计软件,首先在中文语言和操作界面更适合国人,比国外的设计软件更好上手。除此之外,pixso在其他功能设置方面也很吸睛。 像Pixso可以在线设计,无需下载软件…

    2022年5月13日
    970
  • 什么品牌自行车质量好(2020年自行车十大品牌排行榜)

    自行车,又称脚踏车或单车,通常是二轮的小型陆上车辆。骑自行车的好处?自行车运动是一种最能改善人们心肺功能的耐力性有氧运动。骑自行车能减肥养生、改善体质、提高免疫、益寿延年已经得到全世界广泛公认。下面跟小编一起来看看全球十大顶级自行车品牌。 全球十大顶级自行车品牌排行榜 1、MARMOT土拨鼠 MARMOT中文名土拨鼠,俗称旱獭。MARMOT土拨鼠由美国高端自行车品牌CANNONDALE前任总裁等人…

    2022年10月27日
    450
  • 引流方式有哪些,11种线上引流方法推荐

    可以上传一些自己的干货视频到群文件,在这些视频中加上自己的联系方式,只要你的干货对观看的人有帮助,那么这些人就会主动加你为好友,而这些人还是精准好友,相比于手动加好友效果要好很多。 电子书 电子书引流一直都非常的火爆,很多人把一些比较有价值的文章或干货收集整理排版后制作成pdf电子书,再取一个非常诱惑人的标题。在电子书中留下自己的诱饵,如果这些阅读电子书后想获得这些诱饵赠品,他们也会主动加你为微信…

    2022年7月24日
    500
  • 淘宝省钱方法有哪些,淘宝买东西便宜窍门

    很多人觉得淘宝优惠卷是假的,其实不然。只是你找不到而已。当你在用原价买东西的时候,他们却拿着更低的价钱,买着同样的东西 我说我在淘宝可以不花钱买东西你信吗?当然不信,可我做到了 很多东西都是低价,或者是零撸。但是你要提前关注群里的消息,一般都会提前发,像我都是提前放购物车里,然后0点抢,因为很多人不知道,所以很好抢,有人想问方法,我就列出来吧 1首先你要加入一个撸单群,注意!不是普通意义上的发优惠…

    2022年6月4日
    660
  • 怎么弄淘宝网店(新手开网店的流程)

    做女装行业最要记住的一点就是:线上和线下的开店思路是一样的。 做服装如果纯粹通过阿里拿货,利润率薄。很多款式不一定能够做起来,需要挑到好款式+价格战没有打下来。所以需要不断找到这些产品。这种做法容易做不久,最好再结合一个特定人群定位选款。前期这样较麻烦,后期客户聚起来,有回头客。每个货先下单看质量,否则会骂死。服装小机会多,就是太累。 解决了货源的问题,我们再来看开一家网店的具体流程是什么样的? …

    2022年8月4日
    630
  • 微信平台推广方法,免费分享7个最有效的推广渠道

    目录 第一部分认识微信推广 一、微信推广相关定义 二、微信推广相关问题 1.微信为什么要"推广"? 2.从微信推广的角度看微信的多面性 3.微信如何做"推广"? 三、微信推广中个人号与公众号的选择 第二部分微信的推广方式与推广平台 第一节:线上平台推广 一、腾讯系平台推广 1.腾讯系之微信推广 2.腾讯系之QQ平台推广 二、百度系平台推广 三、阿里系平台推广 四、其他线上平台推广 第二节线下平台推…

    2022年9月5日
    1690

发表回复

登录后才能评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信