类似QQ的提醒框设计方案

前一段时间一直在做OA,然后OA中有一个消息提醒的功能,开始的思路是用每隔一段时间访问数据库,看有没有新的消息,有新的消息的话,就用window.showModalDialog显示出来。但是最后发现有一点地方很不好,就是当我把OA最小化然后在其他的软件或者界面工作的时候,消息提示框弹出来之后就会自动回到OA的界面,这样用户体验会特别的不好。最后在网上找了很久,找到了一个还算可以的办法:用window.createPopup()来实现。我把它封装到了一个js文件中,代码如下:

//本JS文件用于弹出电脑短信提示框
//将HTML标签解密
function htmlDecode(value) {
if (value) {
return $('<div />').html(value).text();
} else {
return '';
}
}

//消息构造函数
function CLASS_MSN_MESSAGE(id, width, height, caption, title, message, target, action) {
this.id = id;
this.title = title;
this.caption = caption;
this.message = message;
this.target = target;
this.action = action;
this.width = width ? width : 200;
this.height = height ? height : 120;
this.timeout = 150;
this.speed = 20;
this.step = 1;
this.right = screen.width - 1;
this.bottom = screen.height;
this.left = this.right - this.width;
this.top = this.bottom - this.height;
this.timer = 0;
this.pause = false;
this.close = false;
this.autoHide = true;
}

//隐藏消息方法
CLASS_MSN_MESSAGE.prototype.hide = function () {
if (this.onunload()) {

var offset = this.height > this.bottom - this.top ? this.height : this.bottom - this.top;
var me = this;

if (this.timer > 0) {
window.clearInterval(me.timer);
}

var fun = function () {
if (me.pause == false || me.close) {
var x = me.left;
var y = 0;
var width = me.width;
var height = 0;
if (me.offset > 0) {
height = me.offset;
}

y = me.bottom - height;

if (y >= me.bottom) {
window.clearInterval(me.timer);
me.Pop.hide();
} else {
me.offset = me.offset - me.step;
}
me.Pop.show(x, y, width, height);
}
}

this.timer = window.setInterval(fun, this.speed)
}
}

//消息卸载事件,可以重写
CLASS_MSN_MESSAGE.prototype.onunload = function () {
return true;
}
//消息命令事件,要实现自己的连接,请重写它
CLASS_MSN_MESSAGE.prototype.oncommand = function () {
//this.close = true;
this.hide();
window.open("http://www.baidu.com");

}
//消息显示方法
CLASS_MSN_MESSAGE.prototype.show = function () {

var oPopup = window.createPopup(); //IE5.5+

this.Pop = oPopup;

var w = this.width;
var h = this.height;

var str = "<DIV style='BORDER-RIGHT: #455690 1px solid; BORDER-TOP: #a6b4cf 1px solid; Z-INDEX: 99999; LEFT: 0px; BORDER-LEFT: #a6b4cf 1px solid; WIDTH: " + w + "px; BORDER-BOTTOM: #455690 1px solid; POSITION: absolute; TOP: 0px; HEIGHT: " + h + "px; BACKGROUND-COLOR: #c9d3f3'>"
str += "<object id='myVoice' name='myVoice' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0' width='0' height='0'><param name='movie' value='../Flash/Sms.swf'><param name='quality' value='high'><embed src='Flash/Sms.swf' width='0' height='0' quality='high' pluginspage='http://www.macromedia.com/go/getflashplayer' type='application/x-shockwave-flash' wmode='transparent'></embed></object>";//一段声音提示(Flash文件)
str += "<TABLE style='BORDER-TOP: #ffffff 1px solid; BORDER-LEFT: #ffffff 1px solid' cellSpacing=0 cellPadding=0 width='100%' bgColor=#cfdef4 border=0>"
str += "<TR>"
str += "<TD style='FONT-SIZE: 12px;COLOR: #0f2c8c' width=30 height=24></TD>"
str += "<TD style='PADDING-LEFT: 4px; FONT-WEIGHT: normal; FONT-SIZE: 12px; COLOR: #1f336b; PADDING-TOP: 4px' valign=middle width='100%'>" + this.caption + "</TD>"
str += "<TD style='PADDING-RIGHT: 2px; PADDING-TOP: 2px' valign=middle align=right width=19>"
str += "<SPAN title=关闭 style='FONT-WEIGHT: bold; FONT-SIZE: 12px; CURSOR: hand; COLOR: red; MARGIN-RIGHT: 4px' id='btSysClose' >×</SPAN></TD>"
str += "</TR>"
str += "<TR>"
str += "<TD style='PADDING-RIGHT: 1px;PADDING-BOTTOM: 1px' colSpan=3 height=" + (h - 28) + ">"
str += "<DIV style='BORDER-RIGHT: #b9c9ef 1px solid; PADDING-RIGHT: 8px; BORDER-TOP: #728eb8 1px solid; PADDING-LEFT: 8px; FONT-SIZE: 12px; PADDING-BOTTOM: 8px; BORDER-LEFT: #728eb8 1px solid; WIDTH: 100%; COLOR: #1f336b; PADDING-TOP: 8px; BORDER-BOTTOM: #b9c9ef 1px solid; HEIGHT: 100%'>" + this.title + "<BR><BR>"
str += "<DIV style='WORD-BREAK: break-all' align=left>" + htmlDecode(this.message) + "</DIV>"
str += "</DIV>"
str += "</TD>"
str += "</TR>"
str += "</TABLE>"
str += "</DIV>"

oPopup.document.body.innerHTML = str;

//调用父窗口方法
oPopup.document["DoWork"] = DoWork;
oPopup.document["SetRead"] = SetRead;


this.offset = 0;
var me = this;

oPopup.document.body.onmouseover = function () { me.pause = true; }
oPopup.document.body.onmouseout = function () { me.pause = false; }

var fun = function () {
var x = me.left;
var y = 0;
var width = me.width;
var height = me.height;

if (me.offset > me.height) {
height = me.height;
} else {
height = me.offset;
}

y = me.bottom - me.offset;
if (y <= me.top) {
me.timeout--;
if (me.timeout == 0) {
window.clearInterval(me.timer);
if (me.autoHide) {
me.hide();
}
}
} else {
me.offset = me.offset + me.step;
}
me.Pop.show(x, y, width, height);

}

this.timer = window.setInterval(fun, this.speed)

 

var btClose = oPopup.document.getElementById("btSysClose");

btClose.onclick = function () {
me.close = true;
me.hide();
}
}
//设置速度方法
CLASS_MSN_MESSAGE.prototype.speed = function (s) {
var t = 20;
try {
t = praseInt(s);
} catch (e) { }
this.speed = t;
}
//设置步长方法
CLASS_MSN_MESSAGE.prototype.step = function (s) {
var t = 1;
try {
t = praseInt(s);
} catch (e) { }
this.step = t;
}

CLASS_MSN_MESSAGE.prototype.rect = function (left, right, top, bottom) {
try {
this.left = left != null ? left : this.right - this.width;
this.right = right != null ? right : this.left + this.width;
this.bottom = bottom != null ? (bottom > screen.height ? screen.height : bottom) : screen.height;
this.top = top != null ? top : this.bottom - this.height;
} catch (e) { }
}

最后调用的时候用这个语句:

//弹出消息框
var MSG1;
function ShowComputerMSG(msg) {
if (typeof (MSG1) != "undefined") {
MSG1.close = true;
MSG1.hide();
}
else {
var width = 300;
var height = 150;
if (msg.length > 200 && msg.length < 400) {
width = 400;
height = 180;
}
else if (msg.length > 400) {
width = 500;
height = 180;
}
MSG1 = new CLASS_MSN_MESSAGE("aa", width, height, "短消息提示:", "您有新的消息", decodeURI(msg));
MSG1.rect(null, null, null, screen.height - 50);
MSG1.speed = 20;
MSG1.step = 10;
MSG1.show();
}
}

这样最后的效果是:每隔一段时间,如果有新的消息就会给显示出来,提示框会在一定的时间内消失,如果鼠标放在提示框上面则会不消失,但当下一个提示框出来的时候,上一个提示框会自动消失,下面是效果图:

在这里我们可以看到可以点击查看进入查看界面,这就意味着要在提示窗口条用父页面的方法,在这里不可以直接调用父页面的方法,必须先注册才能使用,注册方法是在上面的JS文件中加入类似一下的语句:

//调用父窗口方法
oPopup.document["DoWork"] = DoWork;

比如说你要在提示框调用父页面上的DoWork方法,就这样写。

这样就实现了类似QQ消息的提示框了。不过在实际的过程中遇到了一个比较大的问题。因为我的系统中有两个地方需要消息提示,而且这两个地方是单独的。如果两个地方同时显示消息提示框的话,会出现问题:提示区不停的闪,什么消息都看不到,而且,如果在提示框中加入了语音提示的话,会不断的刷新页面。最后,我想了一个折中的办法,让两个消息提示框不在同一时间提示(不能完全做到)。一般在用户首次登陆进来的时候,两个提示框都会出来。我的解决办法是这样的:因为我的一个消息提示是5分钟提醒一次,一个是30秒钟提醒一次,第一次进入系统的时候,让30秒钟提示的消息框不显示。这样就可以很好的避开了(不过不能绝对的避开)。最后总算是勉强把功能实现了。

后话:

一、只能适应IE5.5以上浏览器。在其他浏览器中兼容性有问题...

二、我用的后台技术是Asp.NET做的,不停的刷新服务器来提取新的消息是一个很耗资源的操作,一直没找到更好的办法,希望有更好办法的童鞋能够分享分享。

三、写得不好的地方,欢迎大家批评和指正,不过不要进行人身攻击哦  亲...  

posted @ 2013-03-07 18:59  wadeflash  阅读(591)  评论(2编辑  收藏  举报