Ajax开发页面聊天系统

豆豆网   技术应用频道   2008年05月08日    社区交流

内容摘要:不知大家有没有用过新浪的Woocall,如果没有用过也没有关系,现在就去试用一下http://Woocall.sina.com.cn,大家是不是感觉很酷,那么大家想不想自己开发一个,如果有这个打算的话,就随懒羊一起来吧。

  不知大家有没有用过新浪的Woocall,如果没有用过也没有关系,现在就去试用一下http://woocall.sina.com.cn/,大家是不是感觉很酷,那么大家想不想自己开发一个,如果有这个打算的话,就随懒羊一起来吧。

  一、系统功能概述

  本系统主要包括两个界面,一个是最小化时的界面(图一),另一个为聊天(还原)时的界面(图二)。

Ajax开发页面聊天系统

  图一

Ajax开发页面聊天系统

  图二

  主要实现功能有:

  1、 在线访客统计

  2、 呢称修改功能

  3、 信息发送功能

  4、 信息接收功能

  5、 聊天记录保存功能(IE)

  测试环境:IE6.0 Firefox 2.0.0.4

  三、界面效果及位置的实现

Ajax开发页面聊天系统

  上图为模拟网页页面的效果图,首先我们先看看上面标号文字的具体含义:

  1.   document.documentElement.clientWidth

  网页可见宽度,包括间隙,但不包括边框与滚动条

  2.   document.documentElement.clientHeight

  网页可见高度,包括间隙,但不包括边框与滚动条

  3.   document.documentElement.scrollLeft

  横向滚动条离左边距的距离

  4.   document.documentElement.scrollTop

  纵向滚动条离上边距的距离

  5.   页面聊天系统所显示的区域,主要参数

  宽度:document.getElementById("页面聊天系统ID"). offsetWidth

  高度:document.getElementById("页面聊天系统ID").offsetHeight

  左边距:document.getElementById("页面聊天系统ID").style.left

  上边距:document.getElementById("页面聊天系统ID").style.top

  由于我们要将页面聊天系统定位在页面的右下角,因此我们要做如下的算法:

  左边距:document.getElementById("页面聊天系统ID").style.left=(document.documentElement.clientWidth+ document.documentElement.scrollLeft- document.getElementById("页面聊天系统ID").offsetHeight)+ "px"

  上边距:document.getElementById("页面聊天系统ID").style.top= (document.documentElement.clientHeight + document.documentElement.scrollTop

  - document.getElementById("页面聊天系统ID").style.top)+"px"

  当网页触发以下事件时必须对位置进行重新设置:

  1.   window.onresize

  当窗口发生变化时触发

  2.window.onscroll

  当窗口滚动条滚动条触发

  代码如下:

window.onload = getMsg; //页面加载时触发
window.onresize = resizeDiv; //页面大小发生变化时触发
window.onscroll= resizeDiv; //滚动条滚动时时触发
var divWidth,divHeight,docHeight,docWidth,objTimer,i = 0,nc,frompage,objTimerout,objTimeronline;
function getMsg() //定位页面聊天系统位置
{
******//此处星号为下文所用到函数
  try{
  divHeight = parseInt(document.getElementById("eMsg").offsetHeight,10);
  divWidth = parseInt(document.getElementById("eMsg").offsetWidth,10);
  docWidth = document.documentElement.clientWidth;
  docHeight = document.documentElement.clientHeight;
  document.getElementById("eMsg").style.top =(parseInt(document.documentElement.scrollTop,10) + docHeight + 10)+"px";
  document.getElementById("eMsg").style.left =(parseInt(document.documentElement.scrollLeft,10) + docWidth - divWidth)+"px";
  document.getElementById("eMsg").style.visibility="visible" ;
  objTimer = window.setInterval("moveDiv()",10) ; 
  }
  catch(e){}
}
function resizeDiv()
{
  try{
  divHeight = parseInt(document.getElementById("eMsg").offsetHeight,10);
  divWidth = parseInt(document.getElementById("eMsg").offsetWidth,10);
document.getElementById("eMsg").style.top =(document.documentElement.clientHeight - divHeight + parseInt(document.documentElement.scrollTop,10))+"px";
  document.getElementById("eMsg").style.left = (parseInt(document.documentElement.scrollLeft,10) + document.documentElement.clientWidth - divWidth)+"px";
  }
  catch(e){}
}
function moveDiv()
{ try
  {
  if(parseInt(document.getElementById("eMsg").style.top,10) <= (docHeight - divHeight + parseInt(document.documentElement.scrollTop,10)))
  {
  window.clearInterval(objTimer);
  objTimer = window.setInterval("resizeDiv()",1);
  }
  divTop = (parseInt(document.getElementById("eMsg").style.top,10))+"px";
  document.getElementById("eMsg").style.top =( divTop - 1 )+"px";
  }
  catch(e){}
}

  备注:

  objTimer = window.setInterval("resizeDiv()",1)

  含义:每隔1毫秒运行一次resizeDiv()函数

  window.clearInterval(objTimer)

  含义:停止setInterval所运行的函数

  objTimeronline=window.setTimeout("OnlineNum()",2000) ;

  含义:隔2000毫秒运行一次OnlineNum()函数

  window.clearTimeout(objTimerout);

  含义:停止运行OnlineNum()函数

  是不是你会觉得这两个函数有点一样,其实不然。setInterval是每隔多少运行一次函数A,而setTimeout是隔了多少秒后运行一次函数A,而函数A中必须再一次指定运行函数A,当然你也可以再函数A中运行函数B,但setInterval却不可以。 我个人觉得setTimeout更自由、更随意。

  四、Ajax原理

  Ajax为“Asynchronous JavaScript + XML”的简称,主要是通过JavaScript对象中的XmlHttpRequest向服务器提出请求,并根据处理的结果更新页面。这样的更新不会使整个页面全部更新,而是根据用户的需要对某个区域进行局部更新,而且在更新的同时不影响其它区域的浏览。

  以下为Ajax部分的源码,为了方便大家使用,只需明白如何调用即可,关于本节代码的详细介绍,在《asp+ajax打造无刷新新闻评论系统》一文中已经叙述过。

  Xml.js

/*创建并返回XmlHttp对象开始*/
var xhr;
function getXHR()
{
   try {
      xhr=new ActiveXObject("Msxml2.XMLHTTP");
   } catch (e) {     
      try {
          xhr=new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {        
          xhr=false;
      }
   }
   if(!xhr&&typeof XMLHttpRequest!='undefined')
   {
      xhr=new XMLHttpRequest();
   }  
   return xhr;
}
function openXHR(method,url,callback)
{
   getXHR();
   xhr.open(method,url);
   xhr.onreadystatechange=function()
   {
      if(xhr.readyState!=4)return;
      callback(xhr);    
   }
   xhr.send(null);
}
function loadXML(method,url,callback)
{
   getXHR();
   xhr.open(method,url);
   xhr.setRequestHeader("Content-Type","text/xml");
   xhr.setRequestHeader("Content-Type","GBK");
   xhr.onreadystatechange=function()
   {
      if(xhr.readyState!=4)return;
      callback(xhr);
   }
   xhr.send(null);
}

  loadXML(“http方法”,”URL地址”,”function”)

  function为loadXML成功调用后所返回的处理函数,本函数默认参数为xmlDOM

  例:假使我们要请求一个list.asp页面,请求成功后返回setList(xmlDom),采用返回函数主要是为了方便移植与重复使用,我们可以根据不同的请求设置不同的返回处理,而不必要去考虑xmlHttp是如何实现的。

  五、数据库规划

  Chatroom表——存储聊天记录

字段名idncfrompagedateandtimechatmsg
说明编号呢称来源页时间聊天内容
类型自动编号文本文本日期/时间文本
长度2050200

  Msg表——存储提示信息

字段名idmsgfrompage
说明编号信息内容来源页
类型自动编号文本文本
长度20050

  online表——存储当前在线访客

字段名idncfrompage
说明编号呢称来源页
类型自动编号文本文本
长度2050

  六、系统登陆

  页面聊天系统是让在同一个页面上的网友可以相互聊天,而不是所有进入系统的网友,这就要求我们必须在进入系统时先对网页URL进行判别,其次是生成一个唯一的呢称,最后提交给服务器处理程序进行处理;为了兼容Firefox,我们还必须对浏览器进行判别,根据不同的浏览器作出不同的处理。

  1、 来源页URL判别

  frompage=window.location.href;

  2、 获得浏览器类型

  b=navigator.appName;

  3、 根据当前时间生成呢称

function rndName() //获得默认呢称
{
    var date=new Date(); //建立一个日期对象
    mo=String(date.getMonth());//获得当前月份
    d=String(date.getDate());//获得当前日期
    h=String(date.getHours());//获得当前小时
    mi=String(date.getMinutes());//获得当前分钟
    s=String(date.getSeconds());//获得当前秒数
nc="ly"+mo+d+h+mi+s; //生成呢称
}

  4、 提交服务器

function login()
{  
    loadXML("get","login.asp?frompage="+frompage+"a&b="+b+"&nc="+nc+"a",loginOk);
}
function loginOk()
{  
OnlineNum();
}

  5、 服务器处理程序

  Login.asp

<% Response.Charset="gb2312" %>
<% Session.CodePage=936 %>
<!--#include file="conn.asp"-->
<%
Response.addHeader "pragma", "no-cache"
Response.addHeader "cache-control", "private"
Response.CacheControl = "no-cache"
if instr(b,"Netscape") then '如是Firefox则对编码进行转换,下同
frompage= StreamToStr(request("frompage"))
nc= StreamToStr(request("nc"))
else
nc=del1(request("nc"))
frompage=del1(request("frompage"))
end if
set rs=server.CreateObject("adodb.recordset") '如果服务器不存在此页与呢称,则添加
sql="select * from online where frompage='"&frompage&"' and nc='"&nc&"'"
rs.open sql,conn,1,3
if rs.bof and rs.eof then
rs.addnew
rs("frompage")=frompage
rs("nc")=nc
rs.update
set rsx=server.CreateObject("adodb.recordset")  '添加提示信息
sql="select * from msg where frompage='"&frompage&"'"
rsx.open sql,conn,1,3
rsx.addnew
rsx("frompage")=frompage
rsx("msg")=nc&"进入系统"
rsx.update
rsx.close
end if
rs.close
set rs=nothing
conn.close
set conn=nothing
%>

  七、在线访客统计

  客户端:

function OnlineNum()
{
   if(objTimeronline)
   {
   loadXML("get","online.asp?frompage="+frompage+"a&b="+b,OnlineNumOk);
   }
   objTimeronline=window.setTimeout("OnlineNum()",2000) ;
}
function OnlineNumOk(xmlDom) 
{
   if(document.getElementById("minmain"))
   {
document.getElementById("minmain").innerHTML=xmlDom.responseText;
   }
   }

  服务端程序:online.asp

<% Response.Charset="gb2312" %>
<% Session.CodePage=936 %>
<!--#include file="conn.asp"-->
<%
Response.addHeader "pragma", "no-cache"
Response.addHeader "cache-control", "private"
Response.CacheControl = "no-cache"
b=request("b")
if instr(b,"Netscape") then
frompage=StreamToStr(request("frompage"))
else
frompage=del1(request("frompage"))
end if
set rs=server.CreateObject("adodb.recordset")
sql="select * from online where frompage='"&frompage&"'"
rs.open sql,conn,1,3
if not rs.bof or not rs.eof then
onlinenum=rs.recordcount
end if
rs.close
set rs=nothing
conn.close
set conn=nothing
response.write("在线"&onlinenum&"人")
%>

  八、呢称修改功能

  为了聊天方便,有时系统自动生成的呢称并不能直观明了,这就要求我们对系统进行呢称修改,呢称修改必须注意的是当系统中存在同一呢称时,将会提示呢称重复,而且无法修改。

  客户端:

function modifyNc()
{
   if(objTimeronline) window.clearTimeout( objTimeronline)
   var newnc=document.getElementById("nc").value
   loadXML("get","modifync.asp?frompage="+frompage+"a&b="+b+"&nc="+nc+"a&newnc="+newnc+"a",modifyNcOk);
   }
function modifyNcOk(xmlDom) 
{
   if(xmlDom.responseText=="提示:改名成功")
   {
   nc=document.getElementById("nc").value;
   }
   OnlineNum();
   document.getElementById("minmain").innerHTML=xmlDom.responseText;
}

  服务器端:modifync.asp

<% Response.Charset="gb2312" %>
<% Session.CodePage=936 %>
<!--#include file="conn.asp"-->
<%
Response.addHeader "pragma", "no-cache"
Response.addHeader "cache-control", "private"
Response.CacheControl = "no-cache"
b=request("b")
if instr(b,"Netscape") then
nc=trim(StreamToStr(request("nc")))
newnc=trim(StreamToStr(request("newnc")))
frompage=trim(StreamToStr(request("frompage")))
else
nc=del1(trim(request("nc")))
newnc=del1(trim(request("newnc")))
frompage=del1(trim(request("frompage")))
end if
set rs=server.CreateObject("adodb.recordset")
sql="select * from online where frompage='"&frompage&"' and nc='"&newnc&"'"
rs.open sql,conn,1,1
if rs.bof and rs.eof then
conn.execute "update online set nc='"&newnc&"' where nc='"&nc&"' and frompage='"&frompage&"'"
conn.execute "update chatroom set nc='"&newnc&"' where nc='"&nc&"' and frompage='"&frompage&"'" '更新聊天记录中的呢称
session(newnc)=session(nc) '控制获得旧呢称的聊天记录
set rsx=server.CreateObject("adodb.recordset")  '添加信息提示
sql="select * from msg where frompage='"&frompage&"'"
rsx.open sql,conn,1,3
rsx.addnew
rsx("frompage")=frompage
rsx("msg")=nc&"改名为"&newnc
rsx.update
rsx.close
response.Write("提示:改名成功")
else
response.Write("提示:呢称已存在")
end if
rs.close
set rs=nothing
conn.close
set conn=nothing
%>

  九、信息发送功能

  客户端:

function sendMessage() 
{
   var fscontent=document.getElementById("fscontent").value;
   if(fscontent=="")
   {
      alert("内容不可为空!");
      return false;
   }
   document.getElementById("minmain").innerHTML="正在发送…";
  
      document.getElementById("fscontent").value="";
loadXML("get","sendmessage.asp?frompage="+frompage+"a&nc="+nc+"a&b="+b+"&fscontent="+fscontent+"a",sendMessageOk);
}
function sendMessageOk(xmlDom) 
{
   document.getElementById("minmain").innerHTML=xmlDom.responseText;  
}

  服务器端:sendMessage.asp

<% Response.Charset="gb2312" %>
<% Session.CodePage=936 %>
<!--#include file="conn.asp"-->
<%
Response.addHeader "pragma", "no-cache"
Response.addHeader "cache-control", "private"
Response.CacheControl = "no-cache"
b=request("b")
if instr(b,"Netscape") then
frompage=StreamToStr(trim(request("frompage")))
nc=StreamToStr(trim(request("nc")))
fscontent=StreamToStr(trim(request("fscontent")))
else
frompage=del1(trim(request("frompage")))
nc=del1(trim(request("nc")))
fscontent=del1(trim(request("fscontent")))
end if
set rs=server.CreateObject("adodb.recordset")
sql="select * from chatroom"
rs.open sql,conn,1,3
rs.addnew
rs("frompage")=frompage
rs("nc")=nc
rs("dateandtime")=now()
rs("chatmsg")=fscontent
rs.update
rs.close
set rs=nothing
response.Write("提示:发送成功!")
%>

  为了方便发送信息,在输入信息的文本框中添加按键事件onkeydown="keypress();"

function keypress()  //按键为alt+s
{     
   var keycode = event.keyCode?event.keyCode:event.which?event.which:event.charCode;
   if((keycode==83)&&(event.altKey)){
   sendMessage();}
}

  十、 信息接收功能

  客户端:

function getChat() //获得聊天信息
{
if(document.getElementById("chatmain").contentWindow.document.body)
{     loadXML("GET","getChat.asp?frompage="+frompage+"a&b="+b+"&nc="+nc+"a",getChatOk);
}
 objTimerout=window.setTimeout("getChat()",1000);
}
function getChatOk(xmlDom)
{
   var cont="";
   var chatinfo=xmlDom.responseXML.getElementsByTagName("chatinfo");   
   var len=chatinfo.length;
   for(var i=0;i<len;i++)
   {
      var nc=chatinfo[i].childNodes[0].firstChild.data;
      var msgcont=chatinfo[i].childNodes[1].firstChild.data;
      var msgdate=chatinfo[i].childNodes[2].firstChild.data;
   cont+="<div class="msg"><div class="msgnc">"+nc+":</div><div class="msgcont">"+msgcont+" ["+msgdate+"]</div></div>";
   }
   if(document.getElementById("chatmain").contentWindow.document.body)
{     document.getElementById("chatmain").contentWindow.document.body.innerHTML="<div id="authorInfo" class="chatroom"><font color="#ff0000">欢迎使用懒羊页面聊天系统v1.0<br/>开发人:懒羊<br/>开发时间:2007-6-22<br/>------------------------------------<br/></font></div>"+cont;
   document.getElementById("chatmain").contentWindow.document.body.scrollTop=document.getElementById("chatmain").contentWindow.document.body.scrollHeight;
}
var msginfo=xmlDom.responseXML.getElementsByTagName("msginfo");
if(document.getElementById("tsinfomain")&&msginfo[0])
{ 
document.getElementById("tsinfomain").value= msginfo[0].firstChild.data;
}
}

  服务器端:getchat.asp

<% Response.Charset="gb2312" %>
<% Session.CodePage=936 %>
<!--#include file="conn.asp"-->
<%
b=request("b")
if instr(b,"Netscape") then
nc=StreamToStr(request("nc"))
frompage=StreamToStr(request("frompage"))
Response.write("<?xml version=""1.0"" encoding=""UTF-8""?>")
else
nc=del1(request("nc"))
frompage=del1(request("frompage"))
Response.write("<?xml version=""1.0"" encoding=""gb2312""?>")
end if
Response.ContentType = "text/XML"
Response.expires = 0
Response.expiresabsolute = Now() - 1
Response.addHeader "pragma", "no-cache"
Response.addHeader "cache-control", "private"
Response.CacheControl = "no-cache"
if session(nc)="" then
session(nc)=now() '获得当前时间
end if
set rs=server.CreateObject("adodb.recordset")
sql="select * from chatroom where frompage='"&frompage&"' and datediff('s','"&session(nc)&"',dateandtime)>0"
rs.open sql,conn,1,1
if not rs.bof or not rs.eof then
do while not rs.eof
content=content&"<chatinfo><nc>"&rs("nc")&"</nc><msgcont>"&rs("chatmsg")&"</msgcont><msgdate>"&formatdatetime(rs("dateandtime"),3)&"</msgdate></chatinfo>"
rs.movenext
loop
end if
rs.close
set rs=nothing
  
set rs=server.CreateObject("adodb.recordset")
sql="select * from msg where frompage='"&frompage&"' order by id desc"
rs.open sql,conn,1,1
if not rs.bof or not rs.eof then
do while not rs.eof
msg=msg&rs("msg")&chr(13)
rs.movenext
loop
end if
rs.close
set rs=nothing
conn.close
set conn=nothing
response.Write("<lanyang>"&content&"<msginfo>"&msg&"</msginfo></lanyang>")
%>

  注:

  1、if session(nc)="" then 

  session(nc)=now() 

  end if

  当访客进入系统后,获得的只是从访客开始向后的聊天信息,而并非所有信息,因此我们就必须对访客进入系统的时间进行存储,而且因为同一台电脑可以打开多个页面,我们必须保证每个页面存储时间的变量唯一,因此我们通过根据唯一的呢称来设定变量,但由于改名以后呢称发生变化,因此我们要将旧呢称的时间信息存储到新的呢称变量中,这样就可以保证我们前面聊天记录的不丢失。

  2、服务器端文件为asp生成的xml文件,其中主要包括chatinfo与msginfo两个节点,前者节点用来显示聊天信息,而后者则为操作提示信息。

  十一、系统退出

  系统退出包括两种方式:一是关闭浏览器,二是关闭系统(系统右上角的小叉)。不管是那一种方式的退出都必须在退出后删除online表中的访问者信息。但两者也有所不同,关闭系统后网页还在运行某此函数,因此我们必须先停止这些函数,否则JS会提示找不到对象而出错。在服务器端我们会根据在线的人数进行不同的删除操作,当最后一位访问者退出系统时,我们将会删除关于这个页面的所有聊天信息及提示信息。

  客户端:

window.onunload=unloadpage; //此函数所处位置为前面第三节中代码星号位置
function closeMsg()
{
if(confirm("提示:关闭后通过刷页面再次打开!"))
{
document.getElementById("eMsg").innerHTML="";
document.getElementById("eMsg").style.display="none";
if(objTimer) window.clearInterval(objTimer);
unloadpage();
}
}
  
function unloadpage() //退出程序所执行的函数
{
   loadXML("get","quit.asp?frompage="+frompage+"a&b="+b+"&nc="+nc+"a",blankfunction);
   if(objTimerout) window.clearTimeout( objTimerout)
   if(objTimeronline) window.clearTimeout( objTimeronline)
   }
function blankfunction(xmlDom) //空函数
{//空函数}

  服务器端:quit.asp

<% Response.Charset="gb2312" %>
<% Session.CodePage=936 %>
<!--#include file="conn.asp"-->
<%
b=request("b")
if instr(b,"Netscape") then
frompage=StreamToStr(trim(request("frompage")))
nc=StreamToStr(trim(request("nc")))
else
frompage=del1(request("frompage"))
nc=del1(request("nc"))
end if
set rs=server.CreateObject("adodb.recordset")
sql="select * from online where frompage='"&frompage&"' and nc='"&nc&"'"
rs.open sql,conn,1,3
if not rs.bof or not rs.eof then
rs.delete
rs.update
end if
rs.close
set rs=nothing
  
set rsx=server.CreateObject("adodb.recordset")  '添加信息提示
sql="select * from msg where frompage='"&frompage&"'"
rsx.open sql,conn,1,3
rsx.addnew
rsx("frompage")=frompage
rsx("msg")=nc&"退出系统"
rsx.update
rsx.close
  
set rs=server.CreateObject("adodb.recordset")
sql="select * from online where frompage='"&frompage&"'"
rs.open sql,conn,1,1
if not rs.bof or not rs.eof then
onlinenum=rs.recordcount
end if
rs.close
set rs=nothing
  
if onlinenum=0 then
conn.execute "delete from chatroom where frompage='"&frompage&"'"
conn.execute "delete from msg where frompage='"&frompage&"'"
end if
conn.close
set conn=nothing
response.write("提示:成功退出!")
%>

  十二、保存记录

function savechat() //保存记录
{
   if(window.clipboardData)
  {
       window.clipboardData.clearData();
       window.clipboardData.setData("Text", txt);
          alert("提示:已经将记录复制到剪贴板,请通过Ctrl+v或粘贴到其它编辑器中。");
  } else
   {
      alert("此浏览器不支持剪贴板复制!");
      return false;
}
}

  十三、还原按钮与最小化按钮

  最小化按钮:

function changemin() 
{
document.getElementById("eMsg").innerHTML=minstr; //变换系统区域内容
if(objTimerout) window.clearTimeout(objTimerout);//停止获得聊天记录函数
OnlineNum();//启动在线人数统计
}

  还原按钮:

function changemax() 
{
document.getElementById("eMsg").innerHTML=maxstr; //变换系统区域内容
document.getElementById("nc").value=nc; //获得呢称
getChat(); //获得聊天记录
}

  十四、服务器连结文件 conn.asp

<%
dim conn
dim connstr
dim db
db="main.mdb" '数据库文件位置
connstr="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath(""&db&"")
set conn=server.createobject("ADODB.CONNECTION")
conn.open connstr
  
Function del1(s) 'IE时处理函数
del1=left(s,len(s)-1)
end function
  
Function StreamToStr(sStream)  'Firefox下编码转换
dim dr 
Set dr=Server.CreateObject("Adodb.Stream") 
dr.Mode=3 
dr.Type=2 
dr.Open 
dr.Charset="GB2312"
dr.Position=0
dr.WriteText sStream
dr.Position=0 
dr.Charset="UTF-8" 
StreamToStr=dr.ReadText
StreamToStr= left(StreamToStr,len(StreamToStr)-1) 
dr.Close 
Set dr=Nothing 
End Function
%>

  十五、Firefox兼容处理

  程序第一次测试时并不能在Firefox中正常运行,因为懒羊很少用Firefox,所以一直未在其环境下测试,后来与小编聊天时才发现这个问题,于是对程序作了调整,对于修改部分程序中已经用红色标注出来,下面就针对标注的知识点作一个简单的介绍。

  1、  IE:document.getElementById("eMsg").style.top =document.documentElement.clientHeight - divHeight + parseInt(document.documentElement.scrollTop,10);

  Firefox:document.getElementById("eMsg").style.top =(document.documentElement.clientHeight - divHeight + parseInt(document.documentElement.scrollTop,10))+"px";

  IE中后面可以不加单位“px”而Firefox中却不可以,或许Firefox没IE智能吧,因此为了兼容干脆全部加上。

  2、  CSS样式文件中在对.gn ul{margin:0;padding:0;list-style:none;}进行定义时,刚开始并没使用padding:0这条语句,然而在Firefox却转了行,原来Firefox只认识padding,因此我们在设置类似样式时,为了兼容起见可以将margin与padding全部设置为零。

  3、  在信息发送采用快捷键时,原来的语句很简单,并没有如程序中作出判断:

  if((event.keyCode==83)&&(event.altKey)){sendMessage();}

  然而Firefox并不认可event.KeyCode,而必须采用event.which

  var keycode = event.keyCode?event.keyCode:event.which?event.which:event.charCode;

  keyCode用于返回的是功能键的编码

  charCode用于返回数字和字符键的编码

  which包含keyCode和charCode两种情况

  4、  我们通过xmlDOM获得某一个节点具体值时,原来采用chatinfo[i].childNodes(0).text,然而在Firefox中对于.text并不支持,因此我们将代码改为

  var nc=chatinfo[i].childNodes[0].firstChild.data;

  还有一点值得注意,在表现数组时IE中可以用“( )”,而在Firefox中必须采用“[ ]”。

  5、  编码要求

  这一点算是最让懒羊头疼的了,原来程序全部采用GB2312,我们知道xmlhttp默认是以utf-8,但IE或许有一定的免役能力,能够识别,然而Firefox中却不可以,每次提交信息后添加到数据库时全部变成乱码,因此我们在后台不得不通过程序对传过来的参数进行编码转换,从UTF-8转为GB2312再存入数据库,具体的编码转换函数见conn.asp文件中的StreamToStr函数。然而有一点懒羊也不是很明白,为何在传递时非得加一个字符,因此就出现了前面的loadXML("get","quit.asp?frompage="+frompage+"a&b="+b+"&nc="+nc+"a",blankfunction);

  这样的语句,当然在如果是在IE中服务器端同样也要通过del1对字符串进行处理去掉传递过来的那个字符。这里懒羊采用的方法比较笨,如果大家有好的方法不妨试一试。

  至此,所有的开发过程也就讲完了,你只需将客户端代码合成文件lanyangpl.js,然后目标网页通过以下语句调用即可使用:

<script src="interface.js"></script>
<script src="xml.js"></script>
<script src="lanyangpl.js"></script>

  注意,请将代码段放置body内,特别是interface.js必须放进body内。

  或许细心的朋友发现,此程序与新浪的woocall并不相同,woocall界面采用flash完成,当然有能力的朋友也可以通过flash去开发一个页面聊天系统,本教程中的所有代码可以正常运行,但离真正投入使用还有一段距离,希望大家在学习的过程在再加以完善,如果大家做出好的版本也请发给懒羊学习学习。

来源:it168    作者:懒羊    责编:豆豆技术应用

正在加载评论...