asp.net 实现QQ在线聊天程序中javascript的窗口注册机制

  2010年已经到了,已经好久没写博客了,在新年的起始该在园子里说点东西了。

  前段时间给公司做了一个类似QQ的Asp.net在线聊天程序,与服务器之间的通讯是通过前台页面的定时器到服务器上的临时消息目录中取得相关信息来实现的,消息结构XML,为了避免对服务器造成太大的压力就只开了一个定时器,也没敢多开,程序完成后由于测试条件限制只在少的可怜的几台机器上测试了一下,效果还算可以吧,目前能实现发送文字,图片,文件查看历史记录,网络硬盘等基本功能,由于聊天窗口是嵌套在公司主框架里面的所以得实现聊天主窗体和聊天窗体以及一些其他窗体之间指针的引用问题,避免某个聊天窗口被打开多次,或者聊天窗口而主窗口也不知道的问题,下面介绍下程序中用javascript实现的窗口机制:

  看其他人的程序是很困难的,所以先介绍下例子实现的效果:首先创建一个MainFrm.htm窗体(启动窗体) ,用它打开a.htm窗口,a.htm窗体只能打开一个,在a.htm窗体中可以打开b.htm和c.htm,当然b.htm和c.htm窗口也只能打开一个,然后当MainFrm.htm关闭时让a.htm,b.hml和c.htm也跟着关闭,或者a.htm关闭时让b.htm和c.htm也关闭

     1、MainFrm窗体

   为了方便应用,我对数组方法进行扩展,添加了add,remove,clear三个方法

ExpandedBlockStart.gif 代码
if  ( ! Array.prototype.add) {
    Array.prototype.add 
=  function() {
        var startLength 
=   this .length;
        
for  (var i  =   0 ; i  <  arguments.length; i ++ )
            
this [startLength  +  i]  =  arguments[i];
        
return   this .length;
    };
}
if  ( ! Array.prototype.remove) {
    Array.prototype.remove 
=  function(index) {
        
if (index >= 0   &&  index < this .length)
        {
            
this .splice(index, 1 );
        }
    };
}

if  ( ! Array.prototype.clear) {
    Array.prototype.clear 
=  function() {
        
this .splice( 0 , this .length);
    };

   定义一个存放注册窗口的缓存数组

// 已注册的窗口数组
var g_oWindowArray = new  Array();

  为子窗体提供注册函数,并定义一个删除注册函数通过窗体ID找到注册窗体的函数

ExpandedBlockStart.gif 代码
// 注册窗口
function RegisterWindow()
{
    
for  (var i  =   0 ; i  <  arguments.length; i ++ )
    {
        var oWin
= arguments[i];
        g_oWindowArray.add(oWin);
    }
}

// 删除注册窗口
function UnregisterWindow()
{
    
// 从数组中删除
     for  (var i  =   0 ; i  <  arguments.length; i ++ )
    {
        var tmpOWin 
=  arguments[i];
        
for (var i = 0 ;i < g_oWindowArray.length;i ++ )
        {
            
if (g_oWindowArray[i] == tmpOWin)
            {
                tmpOWin.close();
                g_oWindowArray.remove(i);
            }
        }
    }
}

// 通过用户ID找到注册过的窗口对象
function FindRegisterWindowById(strID)
{
    
for (var i = 0 ;i < g_oWindowArray.length;i ++ )
    {
        var oWin
= g_oWindowArray[i];
        
if (oWin.GetFrmID() == strID)
        {
            
return  oWin;
        }
    }
    
return   null ;
}

  每个子窗体都必须实现的接口函数,这里只提供一个返回窗体标示ID的函数和取得MainFrm窗体指针的函数

// 返回窗体惟一标志ID
function GetFrmID()
{
    
return   "" ;
}
// 取得主窗体指针
function GetOpener()
{
  
return  window;
}

  当主窗体关闭时,关闭所有子窗体,主窗体关闭时执行的函数

ExpandedBlockStart.gif 代码
// 窗体关闭时候执行的函数
window.onunload  =  function()
{
    
try
    {
        
for (var i = 0 ;i < g_oWindowArray.length;i ++ )
        {
            var oWin 
=  g_oWindowArray[i];
            
if (oWin)
                oWin.parent.close();
        }
    }
    
catch (e)
    {
        alert(
" 窗口注销时出错! " + e.message + " \n\n 错误说明 :  " + e.description  +  e.message);
        window.close();
    }
}

  打开a.htm

ExpandedBlockStart.gif 代码
// 打开窗口
function ShowMain()
{
    var oWin 
=  FindRegisterWindowById( " aFrm " );
    
    
if (oWin == null )
    {
        var strURL
= ' a.htm ' ;
  
        var oWin 
=  window.open(strURL);
    }
    
else
        oWin.focus();
        
    
return  oWin;
}

  MainFrm的Html代码

< body >
  
< input type = " button "  value = " 打开窗体 "  style = " height:50px;width:100px "  onclick = " ShowMain(); " />
</ body >


  2、a.htm窗体 

 

 

  a.htm中首先要实现MainFrm窗口定义的接口,由于要实现能关闭b.htm和c.htm所以包括了一个数组的add扩展方法(没有将数组扩展写成js文件)和一个窗口关闭时执行的方法,当然的包括窗口的注册了,代码不一一介绍,页面整体代码如下:

ExpandedBlockStart.gif 代码
< html >
< script >
// 数组方法扩展
if  ( ! Array.prototype.add) { 
    Array.prototype.add 
=  function() { 
        var startLength 
=   this .length; 
        
for  (var i  =   0 ; i  <  arguments.length; i ++
            
this [startLength  +  i]  =  arguments[i]; 
        
return   this .length; 
    }; 
}
var winOpener 
=  window.opener.GetOpener();
var g_ChildWinArr 
=   new  Array();
/// //接口定义方法部分 /// /
    
// 取得当前窗体ID
function GetFrmID()
{
    
return   " aFrm " ;
}

// 取得主窗体指针
function GetOpener()
{
  
return  winOpener;
}

//

// 关闭窗口时候取消注册
window.onunload  =  function()
{
   
try
   {
       winOpener.UnregisterWindow(window);
       
       
for (var i = 0 ;i - g_ChildWinArr.length;i ++ )
       {
         var oWin 
=  winOpener.FindRegisterWindowById(g_ChildWinArr[i]);      
         
if (oWin != null )
         {
            winOpener.UnregisterWindow(oWin);
         }
      }
   }
   
catch (e)
   {}
}

// 向主页面注册窗体对象 
winOpener.RegisterWindow(window);

function ShowOneFrm(strURL,strName)
{
  
try
  {
    var oWin 
=  winOpener.FindRegisterWindowById(strName);
          
    
if (oWin == null )
    {
       oWin 
=  window.open(strURL);
       g_ChildWinArr.add(strName);
    }
    
else
       oWin.focus();
   }
   
catch (e)
   {
      alert(strName 
+ " 窗口消息注册过程中出错! " + e.message + " \n\n 错误说明 :  " + e.description  +  e.message);
   }
}

</ script >
< body >
  
< input type = " button "  value = " 打开a窗体 "  style = " height:25px;width:50px "  onclick = " ShowOneFrm('c.htm','cFrm'); " />< br />
  
< input type = " button "  value = " 打开b窗体 "  style = " height:25px;width:50px "  onclick = " ShowOneFrm('b.htm','bFrm'); " />
</ body >

</ html >

  3、b.htm和c.htm窗体

  这两个窗体的不用实现再关闭它的子窗体了所以不包含一些数组扩展函数和窗体关闭执行的函数等,只实现窗口注册和接口定义就行了

   b.htm代码如下:

ExpandedBlockStart.gif 代码
< html >
< script >
var winOpener 
=  window.opener.GetOpener();
/// //接口定义方法部分 /// /
    
// 取得当前窗体ID
function GetFrmID()
{
    
return   " bFrm " ;
}

// 取得主窗体指针
function GetOpener()
{
  
return  winOpener;
}

// 向主页面注册窗体对象 
winOpener.RegisterWindow(window);

// 注销窗体
window.onunload  =  function()
{
   
try
   {
       winOpener.UnregisterWindow(window);
   }
   
catch (e)
   {}
}

</ script >
< body >
< p > 我是B窗体 </ p >

</ body >

</ html >

  c.htm代码如下:

ExpandedBlockStart.gif 代码
< html >
< script >
var winOpener 
=  window.opener.GetOpener();
/// //接口定义方法部分 /// /
    
// 取得当前窗体ID
function GetFrmID()
{
    
return   " cFrm " ;
}

// 取得主窗体指针
function GetOpener()
{
  
return  winOpener;
}

// 向主页面注册窗体对象 
winOpener.RegisterWindow(window);

// 注销窗体
window.onunload  =  function()
{
   
try
   {
       winOpener.UnregisterWindow(window);
   }
   
catch (e)
   {}
}

</ script >
< body >
< p > 我是A窗体 </ p >

</ body >

</ html >


   好了以上就是javascript 实现窗口注册的机制了,如果用于Web聊天的话就要多定义几个接口方法了,比如说:GetChatUserID()(获得当前聊天用户ID)、OnMessage(strMessageID,strMessageXML)(聊天窗口获得消息后的事件)等,不过我感觉要是网速过慢或者登录人过多的时候有可能会出现窗口的注册出现问题,这些就只能通过对错误的捕捉然后重新打开来实现了。

 

附件:

MainFrm窗体代码

a.htm

b.htm

c.htm

 

 

转载于:https://www.cnblogs.com/wtf_net110/archive/2010/01/02/javascript_RegisterFrm.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值