1. 程式人生 > >Web右下角彈出框提示,可疊加

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