内容摘要:不知大家有没有用过新浪的Woocall,如果没有用过也没有关系,现在就去试用一下http://Woocall.sina.com.cn,大家是不是感觉很酷,那么大家想不想自己开发一个,如果有这个打算的话,就随懒羊一起来吧。
不知大家有没有用过新浪的Woocall,如果没有用过也没有关系,现在就去试用一下http://woocall.sina.com.cn/,大家是不是感觉很酷,那么大家想不想自己开发一个,如果有这个打算的话,就随懒羊一起来吧。
一、系统功能概述
本系统主要包括两个界面,一个是最小化时的界面(图一),另一个为聊天(还原)时的界面(图二)。

图一

图二
主要实现功能有:
1、 在线访客统计
2、 呢称修改功能
3、 信息发送功能
4、 信息接收功能
5、 聊天记录保存功能(IE)
测试环境:IE6.0 Firefox 2.0.0.4
三、界面效果及位置的实现

上图为模拟网页页面的效果图,首先我们先看看上面标号文字的具体含义:
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表——存储聊天记录
| 字段名 | id | nc | frompage | dateandtime | chatmsg |
| 说明 | 编号 | 呢称 | 来源页 | 时间 | 聊天内容 |
| 类型 | 自动编号 | 文本 | 文本 | 日期/时间 | 文本 |
| 长度 | 20 | 50 | 200 |
Msg表——存储提示信息
| 字段名 | id | msg | frompage |
| 说明 | 编号 | 信息内容 | 来源页 |
| 类型 | 自动编号 | 文本 | 文本 |
| 长度 | 200 | 50 |
online表——存储当前在线访客
| 字段名 | id | nc | frompage |
| 说明 | 编号 | 呢称 | 来源页 |
| 类型 | 自动编号 | 文本 | 文本 |
| 长度 | 20 | 50 |
六、系统登陆
页面聊天系统是让在同一个页面上的网友可以相互聊天,而不是所有进入系统的网友,这就要求我们必须在进入系统时先对网页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 作者:懒羊 责编:豆豆技术应用
- Ajax开发页面聊天系统
- Ajax开发实例教程.NET页面屏聊系统
- 加强防范!“QQ艳照门”病毒大揭密
- 增强内外轮廓法!轻松换背景2.0发布
- 用迅雷制作、分享自己的红色专辑
- 多项改进!完美卸载V2008 26.41发布
- Windows Update已提供XP SP3下载
- IE新开窗口最大化最简单有效的方法
- 网页设计中CSS关联调用的4种方式
- Vista禁用TCP调谐 为浏览网页加速