目 录
UI交互设计应用领域及前景的调查分析
一个优秀的网站通常会有以下几个方面的优势:漂亮的设计、友好的界面、规范的结构、智能化的后台处理以及充实的内容,另外还有一个不可忽视的就是良好的UI交互性。网站的UI交互性通常是给用户网页浏览过程中良好体验的一个非常重要的环节,满足用户的浏览需求,对用户的选择作出“及时”的响应,是UI交互性网页设计的关键。网页设计者一定要明白,缺乏UI交互性的网站即使看上去很美也是没有生命力的。
“UI交互”的本质就是用户(客户端)发出请求,通过网络传送到服务器(服务器端),服务器端处理用户的请求后得到结果,再次通过网络传送到客户端,客户端将返回的结果展示给用户。现在的UI交互式网页设计技术中,使用的最为广泛的就是Ajax技术,那么什么是Ajax呢?如何实现Ajax的应用呢?以下就围绕着这两个问题并通过实例进行说明。
1、同步Web应用模型与异步Web应用模型:
传统的网页设计技术中,“UI交互”就已经存在,但与Ajax异步通信之间存在有一定的区别,看下面图示:
从图示中,可以看到,传统的Web应用模型中,客户端与服务器端是直接通信的,客户端发出请求后,一直等待服务器端的返回数据,直到服务器端处理完成返回数据后,客户端才会显示出处理结果,中间的数据传递过程和处理过程就是客户的等待的过程,浏览器中往往是显示一片空白,这就是同步应用模型,其最大缺点就是:页面全刷新,用户等待时间长,体验差。
异步Web应用模型中,弱化了客户界面前台的表单功能,不再由表单来实现数据的传递,转而通过Ajax引擎向服务器端传递数据,Ajax功能的实现则通过JavaScript语言来完成,服务器端返回的数据也通过Ajax引擎,利用JavaScript来操作Html DOM更新页面。由于与服务器端的数据交流是由Ajax引擎完成,客户在前台的操作是不会被打断的,即数据在传递的过程中,用户可以继续其他的操作,这实际上也就是我们常说的“局部刷新”技术,用户的体验是非常完美的,在良好的网络状态下,甚至与我们的本机应用程序操作体验近似。
2、Ajax异步通信技术:
Ajax(Asynchronous JavaScript And XML,异步JavaScript和XML)并不是什么新的语言或技术,而是使用JavaScript和XML完成的异步发送请求。
Ajax实际上就是JavaScript语言操作了一个新的对象,这个对象就是XMLHttpRequest对象,XMLHttpRequest就是异步发送请求的对象,这就是Ajax技术的核心,而开发Ajax程序则需要完成五件事情,分别是:获取XMLHttpRequest对象、注册回调方法、打开请求、发送请求、编写回调方法。
l 获取XMLHttpRequest对象:由于不同的浏览器对W3C标准的支持程度是不同的,所以在网页编程中一定要考虑到浏览器的兼容问题
var xmlHttp; //定义全局的XMLHttpRequest
function createXMLHttpRequest(){
//适用IE6以下版本的IE
if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft. XMLHttp");
}
//适用IE7、IE8、FireFox等主流浏览器
else if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}
}
l 注册回调方法:回调方法会监听服务器端的响应,在发送异步请求后,回调方法会每隔一段时间被调用一次
xmlhttp.onreadystatechange = callback;
l 打开请求:open()方法有三个参数,其中第一个参数是请求方式,可选值为GET或POST,建议使用POST;第二个参数是请求资源的URL,实际是服务器端响应程序;第三个参数是一个布尔值,true表示为异步请求。为解决浏览器缓存问题,通常在URL中使用时间戳来欺骗浏览器。
xmlhttp.open(“POST”, URL, true);
l 发送请求:GET请求与POST请求的设置的参数是不同的。
xmlHttp.send(content)
l 编写回调方法:回调函数通常是获取服务器的返回数据,并通过操作DOM,将结果显示在网页中。在回调函数中通常要判断两个状态值,xmhttp.readyState==4代表对象读取服务器响应结束,xmlhttp.status == 200表示服务器正确完成了响应。
function callback() {
if(xmhttp.readyState == 4) {
if(xmlhttp.status == 200) {
var text = xmlhttp.responseText;//获取服务器的响应文本
...
}
}
}
3、jQuery库:
Ajax程序的开发是一个很繁琐的事情,五个步骤缺一不可,遇到实际问题要处理的事情会更多,那么有简化的方法来开发Ajax程序吗?答案就是jQuery。
jQuery是一个优秀的JavaScript库,极大地简化了JavaScript开发人员遍历HTML文档、操作DOM、处理事件、执行动画和开发Ajax的操作。其独特而又优雅的代码风格改变了JavaScript程序员的设计思路和编写程序的方式。jQuery将所有的Ajax操作封装到Ajax方法中,使得开发者处理Ajax的时候能够专心处理业务逻辑而无需关心复杂的浏览器兼容性和XMLHttpRequest对象的创建和使用的问题,极大地简化了我们的编程,其主要的Ajax方法有:
l load( url, [data], [callback] ):载入远程 HTML 文件代码并插入至 DOM 中
l jQuery.get( url, [data], [callback] ):使用GET方式来进行异步请求
l jQuery.post( url, [data], [callback], [type] ) :使用POST方式来进行异步请求
l jQuery.Ajax( options ) : 通过 HTTP 请求加载远程数据
1、任务描述:
下面是在网页中截取的图片:
由于乡镇较多,可能达到上百个,下拉列表太长,造成用户查找相应数据很困难,于是我们希望选择了首字母后,乡镇下拉列表中只显示对应字母开始的那些乡镇名,方便用户的操作,如下图效果:首字母为B,乡镇只显示出对应的两项数据。
2、数据库设计:
我们使用最简单的ACCESS数据库来保存相关的乡镇数据,在ACCESS中建立数据表XIANGZHENG:
为了得到乡镇的首字母,我们建立查询cx_xzFirstLetter:
SELECT DISTINCT left(xiangzhengEname,1) AS firstLetter
FROM xiangzheng
ORDER BY left(xiangzhengEname,1);
3、HTML页面设计:
我们只需要建立一个非常简单的页面,下拉列表中的<option>选项都是空白的,内部的数据是在页面生成后,由服务器端获取的。HTML页面中关键代码:
<script type="text/javascript" src="../js/jquery-1.4.min.js"> </script>
<script type="text/javascript" src="../js/main.js"></script>
<label>所属乡镇名称</label>
首字母<select id="xzletter" name="xzletter"></select>
乡镇<select id="xiangzhengname" name="xiangzhengname"></select>
4、JavaScript脚本程序main.js:
前台的HTML文件中,表单<form>都已经被省略,数据的传递完全通过后台Ajax程序完成,下面是利用jQuery编写的Ajax源代码
$(document).ready(function(){
//乡镇名称与首字母两个下拉列表连动
//定义函数,当首字母发生变化后,函数被调用,改变乡镇的数据
var getXzOpt=function(){
//建立时间戳curtime
var curtime=new Date();
curtime=curtime.getTime();
tLetter=$("#xzletter").val();
$.get("../asp/getXiangzhengOption.asp",
{letter:tLetter,time:curtime},function(d){
$("#xiangzhengname").empty().append(d);
});
};
//页面被加载后即执行下面的Ajax方法
$.get("../asp/getXzFirstLetterOption.asp",{},function(d){
$("#xzletter").append(d).change(getXzOpt);
getXzOpt();
});
});
5、服务器端程序
服务器端用于连接数据库,在数据库中获取前台页面所需要的数据,并传递给前台Ajax引擎。
sub makeOption(runsql)
thesql=runsql
rs.open thesql,conn,3
if not (rs.eof and rs.bof) then
arr=rs.getrows()
y=ubound(arr,2)'相当于记录个数
for i=0 to y
response.Write("<option alue='"&arr(0,i)&"'>"&arr(0,i)&"</option>")
next
end if
end sub
文件getXzFirstLetterOption.asp源代码:
<%
Set rs=Server.CreateObject("Adodb.RecordSet")
sql="select firstletter from cs_xzFirstLetter"
response.Buffer=true
response.Write("<option value='0'>全部</option>")
makeOption sql
response.Flush()
rs.close
set rs=nothing
%>
文件getXiangzhengOption.asp源代码:
<%
Set rs=Server.CreateObject("Adodb.RecordSet")
tletter=request.QueryString("letter")
if tletter="" or tletter=empty or isnull(tletter) then
sql="select xiangzhengname from xiangzheng"
else
sql="select xiangzhengname from xiangzheng where left(xiangzhengename,1) ='"&tletter&"'"
end if
response.Buffer=true
makeOption sql
response.Flush()
rs.close
set rs=nothing
%>
6、分析总结:
上述几个文件中,中间的桥梁就是main.js文件,实际上也就是它完成了Ajax引擎的作用,由于使用jQuery风格,可以看到代码只有几行,却完成了Ajax程序需要完成的五件事件,并且将结果写入了网页,我们再来简要分析一下其中的关键代码:
$.get("../asp/getXzFirstLetterOption.asp",{},function(d){
$("#xzletter").append(d).change(getXzOpt);
getXzOpt();
});
$.get()方法是jQuery封装的Ajax方法,jQuery将XMLHttpRequest对象的获取、回调方法的注册、打开请求、发送请求这四个步骤都已经封装在get()方法中,我们只需要简单的调用即可,其完整的格式是:jQuery.get(url,[data],[callback]),它有三个参数,第一个参数url为发送请求的地址,第二个参数是GET方式传递的数据,第三个参数是回调函数,也是Ajax的第五件事情在这里完成。
回调函数中,通过一个语句$("#xzletter").append(d).change(getXzOpt)就完成了两大功能,一个将服务器端数据写入了页面,这是append()方法完成的,二是给首字母下拉列表注册了change事件,这是change()方法完成的,在这里,我们不得不感叹jQuery代码的简练,完美地体现了其WRITE LESS,DO MORE的宗旨。
1、界面设计及设计思路:
整个页面设计左右两部分,左侧菜单项,当点击时将会导入右侧的表单,表单内的下拉列表项均由数据库中相关数据控制,当点击“提交”按钮后,当前表单中录入的数据会写入到数据库中,并且在下方显示出新添加的数据行。下方的“编辑”按钮可实现当前行数据的修改,“删除”按钮可实现当前行数据的删除。
2、相关HTML页面代码:
左侧菜单页main.asp的主要部分:
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<% response.codepage=65001%>
<% response.charset="utf-8" %>
<title>醴陵市安全生产培训信息管理系统</title>
<link href="../css/main.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="../js/jquery-1.4.min.js"></script>
<script type="text/javascript" src="../js/main.js"></script>
</head>
<body>
<div id="toper">
<h1>醴陵市安全生产培训信息管理系统</h1>
</div>
<div id="mainer">
<div id="lefter">
<h1 class="fsta">基本数据录入</h1>
<div class="subdiv">
<a href="#" bname="qiyeinfo">企业基本信息</a>
<a href="#" bname="stu">新训学员数据录入</a>
</div>
…………
</div>
<div id="righter">
<div id="righter1">
……
</div>
<div id="righter2">
</div>
</div>
</div>
</body>
表单单独放在一个文件中(t_qiyeinfo.html):
<h2>企业基本信息录入</h2>
<form id="addform">
<table border="0" cellpadding="5" id="formtable">
<tr>
<td><label>企业名称</label></td>
<td><input name="qyname" type="text" class="isdata notnull" id="qyname" size="20"> *</td>
</tr>
<tr>
<td><label>企业拼音简称</label></td>
<td><input name="qyEname" type="text" class="isdata" id="qyEname" size="20" readonly="readonly"></td>
</tr>
<tr>
<td><label>所属行业</label></td>
<td><select id="hangyeselect" name="hangyeselect" class="isdata"></select></td>
</tr>
<tr>
<td><label>所属乡镇名称</label></td>
<td>首字母<select id="xzletter" name="xzletter"></select>
乡镇<select id="xiangzhengname" name="xiangzhengname" class="isdata"></select></td>
</tr>
<tr>
<td><label>法人</label></td>
<td><input name="faren" type="text" class="isdata notnull" id="faren" size="20"> *</td>
</tr>
<tr>
<td><label>联系电话</label></td>
<td><input name="tele" type="text" class="isdata phone notnull" id="tele" size="20"> *<label></label></td>
</tr>
<tr>
<td><label>企业性质</label></td>
<td><select id="qiyexingzhi" name="qiyexingzhi" class="isdata">
<option selected="selected" value="私营企业">私营企业</option>
<option value="三资企业">三资企业</option>
<option value="联营企业">联营企业</option>
<option value="集体所有制企业">集体所有制企业</option>
<option value="全民所有制企业">全民所有制企业</option>
</select></td>
</tr>
<tr>
<td><label>企业规模</label></td>
<td><select id="guimoselect" name="guimoselect" class="isdata"></select></td>
</tr>
<tr>
<td><label>主要产品</label></td>
<td><input name="mainproduct" type="text" class="isdata notnull" id="mainproduct" size="50"> *</td>
</tr>
<tr>
<td><label>登录密码</label></td>
<td><input name="pass" type="text" class="isdata notnull" id="pass" size="20" readonly="readonly"> * <input type="button" id="autocreate" value="自动生成"></td>
</tr>
<tr>
<td><label>是否允许添加数据</label></td>
<td><select id="addpower" name="addpower" class="isdata"><option value="是">是</option><option selected="selected" value="否">否</option></select></td>
</tr>
<tr>
<td></td>
<td><input tablename="qiyeinfo" id="addsubmit" type="button" value="确认提交"><input id="formreset" type="reset" value="重新输入"></td>
</tr>
</table>
</form>
3、Js脚本设计:
菜单项的点击,将会激活js脚本中相应的代码,脚本中使用了jQuery代码应用Ajax技术导入右侧表单,并将表单中的下拉列表初始化,并为下拉列表及提交按钮等绑定事件,实现用户的提交请求等功能。
//左边菜单项的点击,右边导入表单,以方便添加记录
$("#lefter a").bind('click',function(){
$("#lefter a").removeClass("cur");
$(this).addClass("cur");
bn=$(this).attr("bname");
switch(bn)
{
case "qiyeinfo":
$("#righter1").load("../html/t_qiyeinfo.html",function(){
rightAlign();
var curtime=new Date();
curtime=curtime.getTime();
//乡镇名称与首字母两个下拉列表连动
var getXzOpt=function(){
tLetter=$("#xzletter").val(); $.get("../asp/getXiangzhengOption.asp",{letter:tLetter,time:curtime},function(d){
$("#xiangzhengname").empty().append(d);
});
}; $.get("../asp/getXzFirstLetterOption.asp",{time:curtime},function(d){
$("#xzletter").append(d).change(getXzOpt);
getXzOpt();
});
$.get("../asp/getHangyeOption.asp",{time:curtime},function(d){
$("#hangyeselect").append(d);
});
$.get("../asp/getGuimoOption.asp",{time:curtime},function(d){
$("#guimoselect").append(d);
});
$("#autocreate").live("click",function(){
var tmp1=parseInt(Math.random()*10000);
var tmp2="";
for(i=0;i<3;i++) {tmp2+=String.fromCharCode(97+parseInt(Math.random()*26)); }
var tmp=tmp2.toUpperCase()+tmp1
$("#pass").val(tmp);
});
/**** 企业名称录入时自动填写汉字的拼音 *****/
$('#qyname').bind('change',{here:$('#qyEname')},writePinYin); $('#qyname').bind('keyup',{here:$('#qyEname')},writePinYin);
});
showTable(bn);//页面下方表格的显示
break;
}
});
//添加记录按钮的点击,使得表单数据提交
$("#addsubmit").live("click",function(){
var tbname=$(this).attr("tablename");
var notHasNull=checkForm(tbname);
if(!notHasNull)
{
alert("数据不完整!");
return;
}
var ilen=$(".isdata").length;
var sendValue="tablename="+tbname+"&";
for(i=0;i<ilen;i++)
{
tempValue=escape($(".isdata").eq(i).val());
sendValue+="input"+i+"="+tempValue;
if(i!=ilen-1)
sendValue+="&";
}
$.post("../asp/addrecord.asp",sendValue,function(data){
//添加记录后显示表内数据
showTable(tbname);
//清除表单中的数据
clearForm(tbname);
alert(data);
});
});
4、服务器端ASP程序设计:
从上段JS程序中可以看到,内部有多段Ajax程序与服务器端的多个ASP程序进行了UI交互,这里不将ASP程序全部列举。
ShowTable.asp文件的作用有两个,一是表单被调入时即在表单下方显示出表内最近被更新的数据,二是当添加了新数据时,马上将新数据显示在表格内,下面是它的源程序代码:
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<% response.codepage=65001%>
<% response.charset="utf-8" %>
<!--#include file="conn.asp"-->
<%
Server.ScriptTimeout=999
Set rs=Server.CreateObject("Adodb.RecordSet")
response.Buffer=true
tbname=request.QueryString("tablename")
'curpici=request.QueryString("pici")
if tbname="" or tbname=empty then
tbname="xiangzheng"
end if
if tbname="stu" or tbname="qiyeinfo" then
topten="top 10"
else
topten=""
end if
sql="select "&topten&" * from "&tbname&" order by id desc"
dim fieldname
select case tbname
case "qiyeinfo"
fieldname=array("企业基本信息(最近录入)","企业名称","拼音简称","所属行业","所属乡镇","法人代表","联系电话","企业性质","企业规模","主要产品","登录密码","添加权限")
case …………
end select
response.write("<h3 id='tablebt' tablename='"&tbname&"'>"&fieldname(0)&"</h3>")
rs.open sql,conn,3
response.Write("<table><tr class='fieldname' >")
response.Write("<td>操作</td><td>ID</td>")
for i=1 to rs.fields.count-1
response.Write("<td>"&fieldname(i)&"</td>")
next
response.Write("</tr>")
'显示出所有的记录
while not rs.eof
response.Write("<tr class='recordarea ")
if(int(curid)=rs(0)) then
response.Write("currecordarea")
end if
response.Write("' id='record"&rs(0)&"'>")
response.Write("<td><input type='button' class='edit' numbers="&rs(0)&" value='编 辑' /><input type='button' numbers="&rs(0)&" class='dele' value='删 除' /></td>")
response.Write("<td><label class='recordno'>"&rs(0)&"</label></td>")
for i=1 to rs.fields.count-1
response.Write("<td>"&rs(i)& "</td>")
next
rs.movenext
response.Write("</tr>")
wend
response.Write("</table>")
response.Flush()
%>
5、页面UI交互分析:
现在我们看看具体执行时的效率,为了方便,我们使用FireFox浏览器的插件FireBug对页面的代码执行过程及时间上进行分析。
下图是我们点击左侧“企业基本信息”链接后,执行的一系列与服务器的UI交互操作:
可以看到,通过Ajax方式一共与服务器端有六次数据请求,我们通过下表对其功能分别进行说明:
次序 |
服务器端程序 |
耗用时间 |
作用 |
第1次 |
t_qiyeinfo.html |
56ms |
远程导入表单 |
第2次 |
showtable.asp |
77ms |
显示下方表格初始数据 |
第3次 |
getXzFirstLetterOption.asp |
66ms |
初始化乡镇首字母下拉列表 |
第4次 |
getHangyeOption.asp |
1ms |
初始化行业下拉列表 |
第5次 |
getGuimoOption.asp |
110ms |
初始化规模下拉列表 |
第6次 |
getXiangzhengOption.asp |
3ms |
初始化乡镇名下拉列表 |
我们再看看第4次AjaxUI交互的过程:
1)提交的数据请求参数time,这只是一个时间戳:
2)响应Http头信息与请求Http头信息,从请求头信息最后一行可以看到请求对象使用XMLHttpRequest,说明这是一次Ajax数据请求:
3)响应数据即从服务器端返回给客户端的数据,可以看到返回的正是这个下拉列表中所需的列表项的HTML代码:
6、小结:
如果我们继续操作这个页面,例如点击“编辑”按钮,点击“删除”按钮等,都可以在FireBug中看到我们向服务器提交了请求,服务器完成相应的操作并返回了我们的需求,这就是所谓的“UI交互”网页了。
网页设计者要在前台设计出客户提交请求的功能,也要在后台设计出服务器端的处理过程,并返回处理结果给客户端,这一系列的工作是非常复杂的,我们不仅要考虑页面的美观、实用性,更需要考虑用户在使用时的舒适度及数据返回的及时性等等。
Ajax技术非常实用,给我们的网上冲浪带来了良好的体验,对于网页设计者来说,Ajax技术却不可滥用,实践证明,网页的展示速度与网页内容的多少并没有很大关系,其时间大部分被消耗在网络传输过程中,所以网页设计者应该考虑尽量地减少与服务器端的数据交换。Ajax的每一次使用都会至少与服务器产生一个来回的数据交流,如果一个页面中,有太多的局部刷新,将会使页面展示速度严重滞后,反而会给网站带来负面影响。
jQuery是我们使用Ajax最方便的工具,他的用途也绝不仅限于此,他有出色的DOM操作封装,他有可靠的事件处理机制,完美的浏览器兼容性,丰富的插件支持等等,这些都值得我们去学习应用。
参考文献
[1]《锋利的jQuery》 作者:单东林 张晓菲 魏然 人民邮电出版社
[2]《jQuery_1.4_API》 jQuery官网