首页 > 代码库 > 自行扩展 FineUIMvc 通知对话框(多个并排显示不重叠,支持最新的显示在最上方)

自行扩展 FineUIMvc 通知对话框(多个并排显示不重叠,支持最新的显示在最上方)

声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版。

这篇文章我们将改造 FineUIMvc 默认的通知对话框,使得同时显示多个也不会重叠。并提前出一个公共的JS文件,供大家使用。

FineUIMvc 的通知对话框

FineUIMvc默认的通知对话框通过 F.notify 来显示,可以在页面上的 9 个位置显示,分别对应于属性:

  1. PosotionX = Left,  PositionY = Top
  2. PosotionX = Left,  PositionY = Center
  3. PosotionX = Left,  PositionY = Bottom
  4. PosotionX = Center,  PositionY = Top
  5. PosotionX = Center,  PositionY = Center
  6. PosotionX = Center,  PositionY = Bottom
  7. PosotionX = Right,  PositionY = Top
  8. PosotionX = Right,  PositionY = Center
  9. PosotionX = Right,  PositionY = Bottom

我们有专门的示例页面来演示相应的效果:

http://fineui.com/demo_mvc/#/demo_mvc/Message/Notify

 

美中不足的时,如果同时有多个通知对话框时,就会出现重叠,如下所示:

技术分享

 

自定义通知对话框分组

为了解决这个问题,我们需要对 F.notify 进行一个简单的封装,得到的效果如下图所示:

技术分享

调用这个封装好的函数非常简单,来看下这个页面的实现代码:

@(F.Button()    .Text("弹出通知对话框(多次点击)")    .ID("btnOperation1")    .Listener("click", "onOperation1Click"))
<script src="http://www.mamicode.com/~/res/js/notify_group.js"></script><script type="text/javascript">    var _orderNumber = 0;    function onOperation1Click(event) {        // 创建一个消息对话框实例        var displayTime = 2000 + Math.random() * 10000;        var allMessageIcons = [‘information‘, ‘warning‘, ‘question‘, ‘error‘, ‘success‘];        showNotifyGroup({            message: ‘这是第 <strong>‘ + _orderNumber + ‘</strong> 条提示信息,显示‘ + Math.floor(displayTime / 1000) + ‘秒‘,            messageIcon: allMessageIcons[_orderNumber % allMessageIcons.length],            header: false,            displayMilliseconds: displayTime        });        _orderNumber++;    }</script>

这里面实际执行的函数就是 showNotifyGroup,需要传入的参数如下:

1. message:显示的消息正文

2. messgeIcon:消息正文前面的图标

3. displayMilliseconds:显示的毫秒数(然后会自动消失)

 

其实,我们可以传入 F.notify 的任何参数,因为 showNotifyGroup 内部也是对 F.notify 的调用,只不过做了一定的扩展。

 

下面就来看下 showNotifyGroup 函数的具体实现:

// 通知对话框分组(function () {    // _notifySpace: 消息框之间的间距    // _notifies: 存放当前正在显示的对话框列表    var _orderNumber = 1, _notifySpace = 5, _notifies = [];    // 对话框关闭处理函数    function onNotifyHide() {        var notify = this;        var notifyHeight = notify.el.outerHeight(true) + _notifySpace;        var notifyIndex = $.inArray(notify, _notifies);        _notifies.splice(notifyIndex, 1);        var count = _notifies.length;        if (count) {            for (var i = notifyIndex; i < count; i++) {                var item = _notifies[i];                item.top -= notifyHeight;                item.el.animate({                    ‘top‘: item.top                });            }            // 按照 notify.top 重新排序            _notifies.sort(function (a, b) {                return a.top - b.top;            });        }    }    // 获取对话框元素的top属性    function calcNotifyTop() {        var top = _notifySpace;        if (_notifies.length) {            var lastNotify = _notifies[_notifies.length - 1];            top += lastNotify.top + lastNotify.el.outerHeight(true);        }        return top;    }    // 公开方法    window.showNotifyGroup = function (options) {        // 创建一个消息对话框实例        $.extend(options, {            top: calcNotifyTop(),            positionX: ‘right‘,            listeners: {                hide: onNotifyHide            }        });        _notifies.push(F.notify(options));    }})();

 

首先看下公开的 showNotifyGroup 方法的实现,需要传入 F.notify 的有三个参数:

1. top:消息框左上角的垂直坐标,由于最新的在最后面显示,所以每次都要计算这个位置

2. posotionX:固定为 right,也就是在页面右侧显示

3. hide:消息框隐藏时的处理函数,里面主要是 3 个处理:

------3.1:从消息框队列中删除需要隐藏的消息框

------3.2:改变正在显示的所有消息框的 top 属性

------3.3:按照 top 由小到大的顺序排序

 

自定义通知对话框分组(最新的显示在最上方)

上面实现的效果是最新的显示在最下方,代码还比较简洁。而如果要求最新的显示在最上方,则面临对动画效果的控制:

1. 显示新消息框时,需要将现有的所有消息框下移,并且等到大家都完成下移动作后,再显示新消息框

2. 显示新消息框时,有可能正在进行下移动画效果,并且上一个消息框还没显示(正在等动画完成),此时需要立即终止所有动画,并显示上一个消息框,之后再处理新的消息框

3. 某个消息框隐藏时,也有可能正在进行下移动画,此时也要做相同的处理

 

所以,虽然封装的代码逻辑复杂了,不过调用方法依然没变,效果也是很赞的:

技术分享

 

这个示例的调用代码很简单,和上例相比,只多了一个 true 的参数:

<script src="http://www.mamicode.com/~/res/js/notify_group.js"></script><script type="text/javascript">    var _orderNumber = 0;    function onOperation1Click(event) {        // 创建一个消息对话框实例        var displayTime = 2000 + Math.random() * 10000;        var allMessageIcons = [‘information‘, ‘warning‘, ‘question‘, ‘error‘, ‘success‘];        showNotifyGroup({            message: ‘这是第 <strong>‘ + _orderNumber + ‘</strong> 条提示信息,显示‘ + Math.floor(displayTime / 1000) + ‘秒‘,            messageIcon: allMessageIcons[_orderNumber % allMessageIcons.length],            header: false,            displayMilliseconds: displayTime        }, true);        _orderNumber++;    }</script>

 

 

现在来看下完整的 notify_group.js 的代码:

// 通知对话框分组(function () {    // _notifySpace: 消息框之间的间距    // _notifies: 存放当前正在显示的对话框列表    var _orderNumber = 1, _notifySpace = 5, _notifies = [];    // 对话框关闭处理函数    function onNotifyHide() {        // 先清空之前尚未完成的动画        clearNotifiesAnimation();        var notify = this;        var notifyHeight = notify.el.outerHeight(true) + _notifySpace;        var notifyIndex = $.inArray(notify, _notifies);        _notifies.splice(notifyIndex, 1);        var count = _notifies.length;        if (count) {            for (var i = notifyIndex; i < count; i++) {                var item = _notifies[i];                item.top -= notifyHeight;                item.el.animate({                    ‘top‘: item.top                });            }            // 按照 notify.top 重新排序            _notifies.sort(function (a, b) {                return a.top - b.top;            });        }    }    // 所有对话框下移    function moveNotifiesDown(newNotify, fn) {        // 先清空之前尚未完成的动画        clearNotifiesAnimation();        var count = _notifies.length, finished = 0;        if (!count) {            fn.apply(window);            return;        }        var notifyHeight = newNotify.el.outerHeight(true) + _notifySpace;        for (var i = 0; i < count; i++) {            var item = _notifies[i];            item.top += notifyHeight;            item.el.animate({                ‘top‘: item.top            }, function () {                // 动画完成后执行的函数                finished++;                if (finished >= count) {                    fn.apply(window);                }            });        }    }    // 停止动画,并回调    function clearNotifiesAnimation() {        var count = _notifies.length;        if (count) {            for (var i = 0; i < count; i++) {                var item = _notifies[i];                var itemEl = item.el;                if (itemEl.is(":animated")) {                    itemEl.stop(false, true);                }            }        }    }    // 获取对话框元素的top属性    function calcNotifyTop() {        var top = _notifySpace;        if (_notifies.length) {            var lastNotify = _notifies[_notifies.length - 1];            top += lastNotify.top + lastNotify.el.outerHeight(true);        }        return top;    }    // 公开方法    window.showNotifyGroup = function (options, newestOnTop) {        // 创建一个消息对话框实例        $.extend(options, {            positionX: ‘right‘,            listeners: {                hide: onNotifyHide            }        });        if (newestOnTop) {            // 最新的显示在最上方,需要先隐藏,等 moveNotifiesDown 之后再显示            options.hidden = true;            options.top = _notifySpace;        } else {            options.top = calcNotifyTop();        }        var notify = F.notify(options);        if (newestOnTop) {            moveNotifiesDown(notify, function () {                notify.show();            });            _notifies.splice(0, 0, notify);        } else {            _notifies.push(notify);        }    }})();

 

如果你也想要这样的效果,很简单,把 notify_group.js 丢到你的项目中,直接调用 showNotifyGroup 函数即可!

 

小结

虽然本篇讲的是 FineUIMvc ,其实是对内部 JavaScript 代码的一个简单扩展和封装,由此可见 FineUIMvc 前端库的灵活性。我们可以直接把 notify_group.js 丢到项目中,调用 showNotifyGroup 函数即可实现上述效果。你也可以自行扩展来在页面的不同地方显示通知对话框,实现更复杂的动画效果。

 

《FineUIMvc随笔》目录:http://www.cnblogs.com/sanshi/p/6473592.html 

 

自行扩展 FineUIMvc 通知对话框(多个并排显示不重叠,支持最新的显示在最上方)