让title闪动起来:新消息提醒

  前些天,要实现一个功能。在后台,一些信息是要实时提醒给后台管理员。用的是通过ajax获取最新信息,然后在前台提示;原来系统自带的是弹出一个对话框,然后flash播放铃声;这种方式不是很友好,对话框弹出一会就消失了,这个页面不能最小化,不然是看不到的;另外播放铃声也得要求管理员带上耳机。
于是就想到了邮箱中来新邮件那种提示方式,闪动标题栏;
思路是:
 通过ajax访问后台,若有新消息,则将网页的title替换为 提示信息 ,并与空格来回切换;
例:【你有新消息】与【     】切换;
提示内容弄是动态的,所以替换文字的空格数目也是算出的。这里用全角的空格;
但是如果提示消息中有‘数字’等半角字符的话就会出现问题。
闪动时
【你有1条新消息】
【你有 条新消息】
全角的空格半角的1的宽度要宽的多。这样的话,闪动起来看着就不是很舒服;解决方法就是用全角的空格替换全角的字符,半角的空格替换半角的字符。
但是document.title=' ';不论半角空格有多少个,浏览器只显示一个。用 的话,它原样输出;
只能用var t=document.getElementsByTagName('title')[0];
获取title dom对象,通过 t.innerHTML=' '来修改;
问题解决;

但会这么顺利么,当然不会。我们可爱的ie在这个时候总会出来捣乱;
在ie浏览器下title的innerHTML是只读的不光是title,其它的如:COL, COLGROUP, FRAMESET, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TR的innerHTML属性是只读的);
如果强制赋值的话会出现“未知的运行时错误”;
目前我也没有找到很到的办法,只能加上try{}catch(e){}对它进行特殊处理了

以下是源码:

 1  
2 var flash_title={
3 doc:document,
4 timer:null,
5 is_flash:false,
6 o_title:document.title,
7 c_title:'',
8 ie:!-[1,],
9 msg :'有新消息',
10 flash : function(msg){
11
12 if(!this.is_flash){
13 this.o_title=this.doc.title;//保存原来的title
14 }
15 this.is_flash=true;
16 if(typeof(msg)=='undefined'){
17 msg=this.msg;
18 }
19 var th=this;
20 this.timer=setInterval(function(){th._flash(msg);},1000);
21 } ,
22 _flash : function(msg){
23 var re=new RegExp('【[\\s| ]+】');
24 this.c_title=this.doc.title;
25 var n=re.test(this.c_title)? ''+msg+'': ''+this.getSpace(msg)+'';
26 try{
27 /*
28 在ie下,下列元素table,thead,tfoot,tbody,tr,col,colgroup,html,title,style,frameset的innerHTML属性是只读的。注意没有td!
29 */
30 this.doc.getElementsByTagName('title')[0].innerHTML=n;
31 }catch(e){
32 n=n.replace(/ /g,' ');
33 this.doc.title=n;
34 }
35
36
37 },
38 clear : function (){
39 clearInterval(this.timer);
40 if(this.is_flash)// 如果正在闪
41 this.doc.title=this.o_title;//将title复原
42 this.is_flash=false;
43 },
44 getSpace : function (msg){
45 var n=msg.length;//console.log(n);
46 var s='';
47 var num=msg.match(/\w/g);
48 var n2=(num!=null)?num.length:0;//半角字符的个数
49 n=n-n2;
50 while(n2>0){
51 s=s+" ";
52 n2--;
53 };
54 while(n>0){
55 s=s+' ';
56 n--;
57 };
58
59 return s;
60 }
61 };


用法

开始闪动 falsh_title.falsh('您有2条新消息');

结束 :flash_title.clear();

结果:火狐,chrome没问题;ie当提示消息中有一个或没有半角字符时没问题
ps:现在写篇文章,一句话结尾是总是习惯用“;”结束,不知道这算不算是程序员职业病,哈哈;

后来看到双鱼座修改后代码,我又在原来的基础上修改了下

View Code
 1 var flash_title={
2 doc:document,
3 timer:null,
4 is_flash:false,
5 o_title:'',
6 ie:!-[1,],//传说中最短判断ie浏览器的代码,但它的true或false 与title 的innerHTML 是否是只读的 并没有必然关系
7 //(主要因为有其他基于ie核心的浏览器存在,如搜狗,遨游等)
8 msg:'有新消息',
9 message:null,
10 flash : function(msg){
11
12 if(this.is_flash){
13 this.clear();//先停止
14 }else{
15 this.o_title=this.doc.title;//保存原来的title
16 }
17 this.is_flash=true;
18 if(typeof(msg)=='undefined'){
19 msg=this.msg;
20 }
21 try{
22 this.doc.getElementsByTagName('title')[0].innerHTML=this.o_title;
23 }catch(e){
24 this.ie=true;
25 }
26 this.message=[msg,this.getSpace(msg)];
27
28 var th=this;
29 this.timer=setInterval(function(){th._flash(msg);},1000);
30 } ,
31 _flash : function(msg){
32 this.index=(!this.index)?1:0;
33 var n=''+this.message[this.index]+'';
34 if(!this.ie){
35 this.doc.getElementsByTagName('title')[0].innerHTML=n;
36 }else{
37 this.doc.title=n;
38 }
39 },
40 clear : function (){
41 clearInterval(this.timer);
42 if(this.is_flash)// 如果正在闪
43 this.doc.title=this.o_title;//将title复原
44 this.is_flash=false;
45 },
46 getSpace : function (msg){
47 var n=msg.length;//console.log(n);
48 var s='';
49 var num=msg.match(/\w/g);
50 var n2=(num!=null)?num.length:0;//半角字符的个数
51 n=n-n2;
52 var space=this.ie?' ':' ';
53 while(n2>0){
54 s=s+space;
55 n2--;
56 };
57 while(n>0){
58 s=s+' ';//全角空格
59 n--;
60 };
61 return s;
62 }
63 };

再后来,我突然想起了我以前曾想到的一种思路,一个全角字符两个半角字符的空。而恰好,浏览器(document.title='半角空格')最多只能显示一个半角空格。

所以又出现了第三个版本,测试结果:所有的浏览器基本都没问题。(之所以说是基本,因为有些浏览器在特定状态下会对汉字加粗,对英文字符不加粗)

View Code
 1 var flash_title={
2 doc:document,
3 timer:null,
4 is_flash:false,
5 o_title:'',
6 msg:'有新消息',
7 message:null,
8 flash : function(msg){
9
10 if(this.is_flash){
11 this.clear();//先停止
12 }else{
13 this.o_title=this.doc.title;//保存原来的title
14 }
15 this.is_flash=true;
16 if(typeof(msg)=='undefined'){
17 msg=this.msg;
18 }
19 this.message=[msg,this.getSpace(msg)];
20 var th=this;
21 this.timer=setInterval(function(){th._flash(msg);},1000);
22 } ,
23 _flash : function(msg){
24 this.index=(!this.index)?1:0;
25 this.doc.title=''+this.message[this.index]+'';
26 },
27 clear : function (){
28 clearInterval(this.timer);
29 if(this.is_flash)// 如果正在闪
30 this.doc.title=this.o_title;//将title复原
31 this.is_flash=false;
32 },
33 getSpace : function (msg){
34 var n=msg.length;
35 var s='';
36 var num=msg.match(/\w/g);
37 var n2=(num!=null)?num.length:0;//半角字符的个数
38 n=n-n2; //全角字符个数
39 var t=parseInt(n2/2);
40 if(t>0){//两个半角替换为一个全角
41 n=n+t;
42 }
43 s=(n2%2)?' ':'';//如果半角字符个数为奇数
44 while(n>0){
45 s=s+' ';//全角空格
46 n--;
47 };
48 return s;
49 }
50 };
51
52 flash_title.flash();//默认提示
53 setTimeout(function(){ flash_title.flash('您有3条新消息');},5000);
54 setTimeout(function(){ flash_title.flash('您有30条新消息');},15000);
55 setTimeout(function(){ flash_title.clear();},25000);//停止

存在flash_title.doc 主要是考虑到ifame的情况,如在iframe使窗口标题闪动,就可以这样写

 flash_title.doc=parent.document;
flash_title.flash(
''+result.new_orders+'个新订单');
flash_title.flash();

最后想说的是,有些功能能自己写的做好自己亲自动手写一下(如果有时间的话,哈哈)。往往能从此过程中学习到很多以前不知道的东西;

posted on 2011-07-16 17:27  倪浩  阅读(4627)  评论(15编辑  收藏  举报

导航