Web右下角弹出框提示,可叠加

前言

一直想着对自己的平时学习以及工作做个总结与积累,无奈老夫实在惫懒。近几日因为工作上的一些事被刺激到了,感觉和打了鸡血一般:老夫要努力学习,勤奋向上。因为第一次写博客,可已经工作一年有余,所以记录的都是近年的工作学习上的一些心得,记录时间有点挨近,此事忽略即可。话不多说咱们进入正文。

正文

源码地址
就如标题所言,此文写的是实现一个可叠加的右下角弹出框,至多显示3个(当然可以不限制),且看效果图:

效果图

此功能为对artDialog 4.1.7进行一些扩展实现。不会的朋友可以参考下这个demo
为什么不用最新的版本呢?看源码嘛习惯于稍旧版本入手看。毕竟思想到了别的都好说嘛。


我们来个图看看几个好基友吧:


项目结构

skins为artDialog的一些资源(css、贴图之类的)
index.html为主界面
dialog.js为artDialog源码(当然这里添加了小小扩展)

思路

  1. 第一个新弹框出现时使用artDialog的position(left, top)方法重设其位置于右下角。


    示例图
  2. 第二个以及之后的新弹框出现时呢则先将新弹框置于屏幕之下然后之前的弹框位置逐个上移,上移的高度为新弹框的高度以及弹框之间的margin


    示例图
  3. 若发现现有的弹框已满三个,就将最旧的那个弹框给关闭即可。

根据以上思路我们开始撸代码
首先是我们拓展方法的框子,这里为此方法命名为msg,并将其付于artDialog对象上,此方法预留3个参数,分别为弹出框显示的内容(content)、多久之后关闭(time)、关闭之后的回调函数(_callback)

artDialog.msg = function(content, time, _callback) {
    
};

然后指定下弹框宽度、距离右边的距离、弹框显示以及关闭的时候动画时间,以及创建一个弹框,然后添加一个_getWindowSize方法用于计算页面宽度以及高度

// 保存弹框id用于获取具体弹框
var gMsgId = [];
artDialog.msg = function(content, time, _callback) {
    var msgWidth = 320;// 弹框宽度
    var rightMargin = 20;// 距离右边的距离
    var openDuration = 200;// 弹框显示的时候动画时间
    var closeDuration = 100;// 弹框关闭的时候动画时间
    // 创建一个弹框
    artDialog({
        title: false,
        lock: false,
        opacity: 0.1,
        width: msgWidth,
        fixed: true,
        resize: false,
        padding: 0,
        drag: false,
        init: function() {
            // 初始化时push弹框id到gMsgId
            gMsgId.push(this.config.id);
        },
        close: function() {
            if (_callback !== undefined) {
                _callback();
            }
            return false;
        }
    })
    .content('<div style="padding: 20px; border-radius: 0px; margin-bottom: 0px;">' + content + '</div>')
    .time(time ? time : 2);
    function _getWindowSize() {
        return {
            width: window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth),
            height: window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight)
        };
    }
}

根据思路图1可知重置弹框位置时需要计算需要减去多少个弹框的高度和。所以添加个_getMsgHeight方法。有个pos参数用于指定当前弹框在保存弹框的数组中的索引。
eg:新增弹框,之前已有2个弹框,所以目前俩个弹框,新弹框还在页面之下,如思路图2。此时若是重置新弹框,即pos为2的弹框,则需要计算其重置后的top值,很明显仅需要页面高度减去新弹框高度和一个弹框间距即可
可能这个方法还是看不懂,没关系先放放继续往下看即可

    function _getMsgHeight(pos) {
        var _height = 0;
        for (var i = gMsgId.length - 1; i >= pos; i--) {
            _height += art.dialog.list[gMsgId[i]].DOM.wrap[0].offsetHeight;
        }
        return _height;
    }

然后就是添加个_positionPrompt方法用于重置弹框的位置,因为弹框关闭、打开、以及网页resize时需要对原有弹框位置进行重置:

  • 弹框关闭时只需重置该弹框之上的弹框的位置,弹框之下的弹框保持不变
  • 新增弹框时,之前所有的弹框均需要往上移动新弹框高度加上垂直上弹框之间距离。这里有个注意点是:将新增弹框先置于屏幕之下,然后对所有弹框进行整体上移,就会有弹框平滑出现的效果,见思路图2
  • 网页resize时需要重置页面上所有弹框
    所以需要添加个type参数用于区分以上三种情况
    var _top = (_wsize.height - _getMsgHeight(i) - (l - i) * 10);
    这句代码配上_getMsgHeight方法的那个eg代入下是不是就恍然大悟了呢
    function _positionPrompt(type) {
        // 获取页面高度与宽度
        var _wsize = _getWindowSize();
        // 遍历弹框
        for (var i = 0, l = gMsgId.length; i < l; i++) {
            // 获取当前弹框的重置位置之后的top值,10为弹框间距
            var _top = (_wsize.height - _getMsgHeight(i) - (l - i) * 10);
            if (type === 'close') {
                // 根据弹框id获取到弹框DOM对象,然后使用jquery animate方法重置位置
                $(art.dialog.list[gMsgId[i]].DOM.wrap[0]).animate({
                    top: _top
                }, openDuration);
            } else if (type === 'open') {
                if (i === (l - 1)) {
                    // 若是新弹框则将其置于屏幕之下,即新弹框上边框与页面底部持平
                    art.dialog.list[gMsgId[i]].position(_wsize.width - msgWidth - rightMargin, _wsize.height);
                } else {
                    // 若不是新弹框则不改变高度
                    art.dialog.list[gMsgId[i]].position(_wsize.width - msgWidth - rightMargin, null);
                }
                // 根据弹框id获取到弹框DOM对象,然后使用jquery animate方法重置位置
                $(art.dialog.list[gMsgId[i]].DOM.wrap[0]).animate({
                    top: _top
                }, openDuration);
            } else if (type === 'resize') {
                // 若是页面resize,使用position方法重置位置
                art.dialog.list[gMsgId[i]].position(_wsize.width - msgWidth - rightMargin, _top);
            }
        }
        // 若是当前弹框数大于3则关闭最旧的那个弹框
        if (l > 3) {
            setTimeout(function(){
                art.dialog.list[gMsgId[0]].close();
            }, openDuration);
        }
    }

现在添加弹框关闭逻辑以及组装上面的方法

// 保存弹框id用于获取具体弹框
var gMsgId = [];
artDialog.msg = function(content, time, _callback) {
    var msgWidth = 320;// 弹框宽度
    var rightMargin = 20;// 距离右边的距离
    var openDuration = 200;// 弹框显示的时候动画时间
    var closeDuration = 100;// 弹框关闭的时候动画时间
    // 创建一个弹框
    artDialog({
        title: false,
        lock: false,
        opacity: 0.1,
        width: msgWidth,
        fixed: true,
        resize: false,
        padding: 0,
        drag: false,
        init: function() {
            gMsgId.push(this.config.id);
        },
        close: function() {
            if (_callback != undefined) {
                _callback();
            }
            // 计算被关闭的弹框在数组中的索引
            var _index = $.inArray(this.config.id, gMsgId);
            if (gMsgId.length > 3) {
                gMsgId.splice(_index, 1);
                return true;
            } else {
                // 去除数组中保存的被关闭的弹框id
                gMsgId.splice(_index, 1);
                if (_index) {
                    // 若被关闭的弹框不是最旧的,即最上面的那个,则本弹框关闭之后还需要调整其他弹框位置
                    $(art.dialog.list[this.config.id].DOM.wrap[0]).fadeOut(closeDuration, function() {
                        _positionPrompt('close');
                    });
                } else {
                    // 若被关闭的弹框是最旧的,即最上面的那个,则本弹框关闭即可
                    $(art.dialog.list[this.config.id].DOM.wrap[0]).fadeOut(closeDuration);
                }
            }
            return false;
        }
    })
    .content('<div style="padding: 20px; border-radius: 0px; margin-bottom: 0px;">' + content + '</div>')
    .time(time ? time : 2);
    // 新弹框需要触发open类型的位置重置
    _positionPrompt('open');
    // 绑定resize
    $(window).resize(function() {
        _positionPrompt('resize');
    });

撸个界面

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="http://demo.jb51.net/js/2011/artDialog/skins/default.css?4.1.7">
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        #open-btn {
            width: 100%;
            height: 50px;
            text-align: center;
            background: skyblue;
            border: 0;
            color: red;
            font-size: 21px;
        }
    </style>
</head>
<body>
    <button id="open-btn">Click</button>
</body>
<script src="https://cdn.bootcss.com/jquery/1.10.1/jquery.js"></script>
<script src="./dialog.js"></script>
<script type="text/javascript">
    function randomNum(min, max) {   
        var rang = max - min;   
        var rand = Math.random();   
        return(min + Math.round(rand * rang));   
    }   
    $(document).ready(function(){
        var roster = ['pz', 'sp', 'll', 'wx'];
        $("#open-btn").on('click', function(event) {
            event.stopPropagation();
            event.preventDefault();
            art.dialog.msg(roster[randomNum(0, 3)]);
        });
    });
</script>
</html>

结语

至此大功告成。初次写博客,功力有限。就想说,写个博客比写代码累多了。/(ㄒoㄒ)/~~

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,285评论 25 708
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 1,373评论 0 1
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,232评论 4 61
  • 1、按别人的指引,盲目的前进,可能会一步踏空,摔得惨痛! 2、一个诚实的敌人好过一个虚伪的朋友! 3、老师说,每个...
    幸运地狱火阅读 2,376评论 0 0
  • 雾松 频阳人 长宵入寒无晓光 天鸡迟报玉人妆 似银素裹一身洁 如雪梨花冰代香 靓婷存芳含春意 月夜伴星影成双 多...
    石川河女神阅读 220评论 2 1