您的位置:首页 > Web前端 > JavaScript

终于搞定了无刷新,即所谓的web脚本替换

2006-01-19 02:21 239 查看
原来以为很难的东西
跑到论坛上东问西问,又懒得有人理
还好在经典翻出一篇2003年的老文章来
仔细研究了研究
才有点明白
原来所有的变量都写在那个要被改编的src的文件中
其实质只是相当于一个存储数据的文件
原来我还以为可以在其中执行语句呢
不过ms网上有执行语句的代码,不知他们是怎么调试好的
讲经典的源问贴出来、以飨读者
作者是andot,呵呵id上有个小小的语法错误

  最近Web编程中的页面无刷新技术比较流行,比如MSDN Library中左面的那棵目录树,还有一些聊天室,还有一些论坛都做成了无刷新页面。实现无刷新页面的技术现在有很多,比如Web Service Behavior,XML http,Microsoft Remote Scripting for ASP等,但是上面提到的这些技术都是在IE上才能实现的,而且Microsoft Remote Scripting for ASP只限于服务器端使用ASP,而Web Service Behavior要有提供Web Service的服务器才行。因此这些技术的都或多或少有些局限性。
  今天介绍的脚本替换技术是一种比较通用的实现页面无刷新的方法,而且原理和实现都比较简单。废话少说,咱们言归正传。
下面先举一个简单的脚本替换的例子:
主页面(exam.html):
<head>
<script language="javascript">
  var value = "";
  var timeid = null;
  var ready = false;

  function showvalue() {
    ready = false;   
    text.innerHTML = "请稍候……";
    if (scr.src == "1.js") scr.src = "2.js";
    else scr.src = "1.js";
    loadscr();
  }

  function loadscr() {
    if (ready) {
      text.innerHTML = value;
    }
    else {
      clearTimeout(timeid);
      timeid = setTimeout("loadscr();", 10);
    }
  }
 
</script>
</head>
<BODY aLink=#000020 bgColor=#ffffff id=all link=#000020 text=#070155 topMargin=10 vLink=#000020 marginheight="10" marginwidth="10">
<button type="button" onclick="showvalue();">切换</button>
<span id="text"></span>
<script id="scr" language="javascript" src=""></script>
</body>
下面是两个脚本,用来替换:
1.js

value = '这是第一个脚本';
ready = true;


2.js

value = '这是第二个脚本';
ready = true;


现在打开主页面,点切换按钮就看到效果了。

大家应该看到点[切换]按钮以后的效果了吧?这个例子切换的是两个静态脚本之间的切换。如果这两个脚本不是js扩展名的静态脚本,而是asp,aspx,php,jsp之类的动态脚本,那样就可以返回服务器处理以后的数据了,我们可以利用这一点实现页面无刷新的数据更新。另外asp,aspx,php,jsp之类的动态脚本可以在URL后面带参数,这样可以通过传递不同的参数来获取不同的数据。这样一个asp,aspx,php,jsp文件就相当于一个在服务器端执行的函数,参数是客户端传递过去的,然后服务器端处理完后直接返回结果,客户端得到结果后继续处理,这样通过脚本就实现了页面的无刷新数据替换。其实利用Web Service Behavior技术是相似的,不过Web Service Behavior技术把这个函数调用过程作了完美的封装,使得看上去跟函数调用一样,而且传递的数据是XML的,而这里的脚本替换技术,要自己来完成这个函数调用的模拟过程,传递的数据也是我们自己定义的脚本,不过这样我们自由度更大了,我们返回的可以不只是纯数据赋值的js脚本,还可以包含任何可以在客户端执行的js脚本。这样说很难说清楚,还是再举个简单的例子吧。

另外一个简单的例子,好像是一个成绩查询的东西,还没仔细看,呵呵

<html>
<head>
<meta name="GENERATOR" content="Microsoft FrontPage 6.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>济南大学2003年招生录取结果查询</title>
<style type="text/css">
body {
border: 0;
margin: 0;
padding: 0;
background-color: buttonface;
}
body, td {
font-size: 12px;
}
input, select {
font: menu;
}
</style>
<script language="javascript">

var timeid = null;
var ready = false;
var error = "";
var studentname = "";
var studentnum = "";
var examcardnum = "";
var idcardnum = "";
var specialty = "";
var level = "";

function loadQueryScript() {
if (ready) {
window.querybtn.disabled = false;
if (error != '') window.text.innerHTML = '<table border="0" width="260"><tr><td>' + error + '</td></tr></table>';
else {
str = '<table border="0" width="260">';
str += ' <tr>';
str += ' <td align="right">姓名:</td>';
str += ' <td>' + studentname + '</td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td align="right">学号:</td>';
str += ' <td><font color="red">' + studentnum + '</font></td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td align="right">准考证号:</td>';
str += ' <td>' + examcardnum + '</td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td align="right">身份证号:</td>';
str += ' <td>' + idcardnum + '</td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td align="right">录取专业:</td>';
str += ' <td>' + specialty + '</td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td align="right">培养层次:</td>';
str += ' <td>' + level + '</td>';
str += ' </tr>';
str += ' <tr>';
str += ' <td colspan="2">';
str += ' <font color="red">恭喜您已被我校录取,请注意查收您的录取通知书!并且请牢记您的学号,入校以后您所有的信息均以学号为管理依据。</font>';
str += ' </td>';
str += ' </tr>';
str += '</table>';
window.text.innerHTML = str;
}
}
else {
clearTimeout(timeid);
timeid = setTimeout("loadQueryScript();", 1000);
}
}

function querybtnClick() {
window.querybtn.disabled = true;
ready = false;
window.text.innerHTML = '<img src="images/searching.gif" align="absbottom" />正在查询中,请稍候……';
queryscript.src = "query.php?idcardnum=" + document.getElementById("idcardnum").value + "&examcardnum=" + document.getElementById("examcardnum").value + "&datetime=" + new Date().toString();
loadQueryScript();
}

function bodyDrag() {
return false;
}

function init() {
if (window.dialogArguments) {
dialogWidth = parseInt(dialogWidth) - document.body.clientWidth + 286 + "px";
dialogHeight = parseInt(dialogHeight) - document.body.clientHeight + 296 + "px";
window.querybtn.onclick = querybtnClick;
window.document.body.ondrag = bodyDrag;
}
else {
window.moveTo(10000, 10000);
window.showModalDialog('index.htm', window, 'help: no; status: no;');
window.opener = null;
window.close();
}
}
window.onload = init;
</script>
</head>
<body>
<table border="0" width="286" align="center" cellspacing="0" cellpadding="0">
<tr>
<td><img border="0" src="images/title.jpg" width="286" height="60" /></td>
</tr>
<tr>
<td height="160">
<div align="center" id="text">
<table border="0" width="260">
<tr>
<td>
欢迎使用济南大学 2003 年招生录取结果查询系统。请输入你的身份证号和准考证号进行查询,如果你还没有身份证,可以不填身份证号。其他相关招生信息请访问我校<a href="http://eadwww.ujn.edu.cn/zsb/zhaosheng.htm">招生信息网</a>。<br />
 </td>
</tr>
</table>
</div>
</td>
</tr>
<tr>
<td><img border="0" src="images/line.gif" width="286" height="4" /></td>
</tr>
<tr>
<td align="center">
<br />
<label for="idcardnum">身份证号:</label><input type="text" id="idcardnum" name="idcardnum" size="18" maxlength="18" /><br />
<label for="examcardnum">准考证号:</label><input type="text" id="examcardnum" name="examcardnum" size="14" maxlength="14" />
<button id="querybtn" name="querybtn" type="button" style="height: 21px" title="查询"><img src="images/query.gif" align="absbottom" /></button>
</td>
</tr>
</table>
<script language="javascript" src="" id="queryscript"></script>
</body>
</html>

这是这个暑假中写的“济南大学2003年招生录取结果查询”的程序的客户端,服务器段的脚本(query.php)如下(作了简略):

引用:
<?php

//数据库配置信息(以下数据数据库配置的实际信息略了)
$cfg[ 'server' ][ 'host' ] = "";
$cfg[ 'server' ][ 'port' ] = "";
$cfg[ 'server' ][ 'user' ] = "";
$cfg[ 'server' ][ 'password' ] = "";
$cfg[ 'server' ][ 'database' ] = "";

//连接数据库
$conn = null;
$server = $cfg[ 'server' ][ 'host' ];
if ($cfg[ 'server' ][ 'port' ] != "") $server .= ':'.$cfg[ 'server' ][ 'port' ];
if (!$conn = @mysql_pconnect($server, $cfg[ 'server' ][ 'user' ], $cfg[ 'server' ][ 'password' ])) {
echo 'error = "<font color=red><b>数据库服务器无法连接。/n请保证数据库服务器工作正常后,再重试。</b></font>"'."/n";
echo "ready = true;/n";
exit();
}
else if(!@mysql_select_db($cfg[ 'server' ][ 'database' ], $conn)) {
echo 'error = "<font color=red><b>数据库'.$cfg[ 'server' ][ 'database' ].'无法打开。/n请保证此数据库工作正常后,再重试。</b></font>"'."/n";
echo "ready = true;/n";
exit();
}

//获取表单数据
$idcardnum = (isset($_GET[ 'idcardnum' ]) ? $_GET[ 'idcardnum' ] : '');
$examcardnum = (isset($_GET[ 'examcardnum' ]) ? $_GET[ 'examcardnum' ] : '');

//查询
$sql = "select * from `matriculate` where `idcardnum` = '$idcardnum' and `examcardnum` = '$examcardnum' limit 1";
if (($result = @mysql_query($sql, $conn)) and ($row = mysql_fetch_object($result))) {
echo "idcardnum = '$row->idcardnum';/n";
echo "examcardnum = '$row->examcardnum';/n";
echo "studentnum = '$row->studentnum';/n";
echo "studentname = '$row->studentname';/n";
echo "specialty = '$row->specialty';/n";
echo "level = '$row->level';/n";
echo "error = '';/n";
echo "ready = true;/n";
}
else {
echo 'error = "<font color=red><b>对不起,系统没有查到你所需的资料,可能有如下原因:<br /></b></font>";'."/n";
echo 'error += "<font color=blue>1、可能你输入有误,请核对你的身份证号和准考证号;<br />";'."/n";
echo 'error += "2、可能录取工作还没有结束;<br />";'."/n";
echo 'error += "3、可能你填报志愿的批次还未开始录取;<br />";'."/n";
echo 'error += "4、你可能未被录取;<br />";'."/n";
echo 'error += "5、其他信息请关注<a href=http://eadwww.ujn.edu.cn/zsb/zhaosheng.htm>招生信息网</a>。</font>";'."/n";
echo "ready = true;/n";
}
?>

这个程序是利用脚本替换技术实现脚本无刷新数据更新的一个简单应用。如果看懂这个程序,我想你应该不难利用这个技术来写你自己的程序了。

脚本替换技术的几点注意事项:

1、需要替换的脚本的标签(比如第一个例子中的<script id="scr" language="javascript" src=""></script>标签)要定义在<body></body>之间,而不能定义在<head></head>之间。上面的两个例子都定义在<body></body>的最后一句,其实定义在<body></body>的开头或者其他位置也行,只要在<body></body>之间就行了。

2、替换的脚本链接最好不要重复,否则同一个链接只会返回第一次处理后的值,第二次请求时,将不再去服务器端执行,不过可以通过带一个多余参数来实现,利于第二个例子中的"query.php?idcardnum=" + document.getElementById("idcardnum").value + "&examcardnum=" + document.getElementById("examcardnum").value + "&datetime=" + new Date().toString()这个地址最后的"&datetime=" + new Date().toString()就是一个用来实现防止链接地址相同的参数。而这个参数其实在服务器端并不需要。

3、为了判断服务器端的脚本是否执行完毕,需要定义一个标志变量。上面例子中的ready变量就是这样的一个变量。他在替换脚本链接前初始化为false,服务器端脚本的最后一句要返回一个ready = true;的语句,这样当执行完这句时,表明服务器端的数据已经全部返回了。

这是我想到的最主要的三个需要注意的地方,其他的小地方我想大家应该通过这两个程序能自己理解。我就不多说了,如果大家有什么不明白的地方可以提出来,一起讨论。

这个技术不是我的原创,我只是在这里总结一下我的使用经验而已,有错误的地方希望各位给予指正。

============================================================

后来kai3000又提出了xml数据到,什么xsl,xstl等等的,看得我指头晕,懂得太少啊

其实网页无刷新还有更多的方法大家可以研究的

比如说 xml数据岛,嘿嘿 xml数据绑定

在这里抛砖引玉了

网页中存在一个xml数据岛 <xml src="aaa.jsp?id=15" id="xmlUserinfo"></xml>
aaa.jsp?id=15
返回xml格式入下
<xmlUserinfo>
<username>KAI300</username>
</xmlUserinfo>

页面载入以后,咱们就可以把这个username绑定到任何网页控件比如span吧

<SPAN DATASRC="#xmlUserinfo" DATAFLD="username" ></SPAN>

想要刷新的时候,之需要改变xmlUserinfo.src的值就可以了,随着数据岛的reload网页内容同时会发生更变

这种设计的有点在于不刷新(废话),html很好设计,不需要学习其他xmlhttp等技术,开发效率比较高

缺点在于,无法准确控制网页控件,不如xsl等其他解决方案来得直观,计算或数据处理功能弱,无法处理if-else情况.......

只能算是初级应用吧,抛砖引玉了.....

===================================================================

最后是blueprince的一段优化过的代码,真是到了禅一般的境界了

既然被翻出来了
我回复一个也无妨了 呵呵

不知道坏梨的是不是这个意思?

<head>
<script language="javascript">
var value = "";
var _onjsload=null;

function showvalue() {
_onjsload= function(){alert(scr.src+' loaded.')}
text.innerHTML = "Please wait .... ";
(scr.src == "1.js")?scr.src = "2.js":scr.src = "1.js";
}

function jsLoadReady(){
if(_onjsload!=null){
_onjsload();
text.innerHTML = value;
_onjsload=null;
}
}
</script>
</head>
<BODY aLink=#000020 bgColor=#ffffff id=all link=#000020 text=#070155 topMargin=10 vLink=#000020 marginheight="10" marginwidth="10">
<button type="button" onclick="showvalue();">Change</button>
<span id="text"></span>
<script id="scr" language="javascript" src=""></script>
</body>


1.js:

value = 'This is 1.js.';
jsLoadReady();


只是不知道
如果innerHTML换成
iframe.document.write
可不可以

如果换成iframe
和直接iframe的刷新有什么不一样?

比如这样:

<head>
<script language="javascript">
var value = "";
var _onjsload=null;

function showvalue() {
_onjsload= function(){alert(scr.src+' loaded.')}
text.document.body.innerHTML=""
text.document.write("Please wait .... ");
(scr.src == "1.js")?scr.src = "2.js":scr.src = "1.js";
}

function jsLoadReady(){
if(_onjsload!=null){
_onjsload();
text.document.body.innerHTML=""
text.document.write(value);
_onjsload=null;
}
}
</script>
</head>
<BODY aLink=#000020 bgColor=#ffffff id=all link=#000020 text=#070155 topMargin=10 vLink=#000020 marginheight="10" marginwidth="10">

<iframe id="text" border=1></iframe>
<button type="button" onclick="showvalue();">Change</button><br>
<script id="scr" language="javascript" src=""></script>
</body>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息