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ㄒ)/~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容

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