Posts tagged JavaScript

VBScript中变量作用域

下午在写程序的时候,碰到个变量重定义的问题,具体是在一个函数中的两个地方定义了相同的变量,两个变量分别放在IF语句的两部分中,本来以为这两次定义在语句中不同的块,应该没有影响,然而在运行中IIS却提示变量重定义,把重复定义去掉即正确。

解决了问题之后突然想到在Fdream的blog看过一篇文章《JavaScript变量无块级作用域》,似乎这两个是差不多的,在VBScript中变量同样没有块级作用域

再次去看了那篇文章之后我也做了下试验,得到结果:在VBScript中,函数中定义的变量的作用域是整个函数,而不是块级,不管这个变量是在函数中哪个位置定义的。因此,函数中一个变量不管在函数的哪个位置定义,它在整个函数中都可以使用。

下面用一些例子来说明这个问题。

Option Explicit
Sub foo()
Dim var
var=”hello,world!”
MsgBox var
End Sub
Call foo()

下面的代码跟上面的代码等效,但是var的定义放在了函数的最后:

Option Explicit
Sub foo()
var=”hello,world!”
MsgBox var
Dim var
End Sub
Call foo()

下面的例子说明变量不管在哪定义,在整个函数中都是可以使用的,当然如果把定义的位置放的特殊一点有利于代码的清晰,阅读起来比较方便,修改时也比较方便。

Option Explicit
Sub foo()
Dim var1
var1=”YES”
MsgBox “var1: “&var1&vbCrLf&”var2: “&var2
IF var1=”YES” Then
Dim var2
var2=”NO”
End IF
MsgBox “var1: “&var1&vbCrLf&”var2: “&var2
End Sub
Call foo()

在ASP开发中,写一个函数时通常的做法是变量到用时才定义,虽然变量的作用域与定义的位置无关,不过我觉得还是写在变量使用之前比较好,以后改起代码来比较方便,不至于修改了一段代码之后还要翻到函数头去修改变量定义。

AJAX应用之草稿自动保存

相信用过Gmail的人都知道Gmail有一个草稿自动保存的功能,每过一段时间,Gmail都会自动保存邮件草稿,这样在一些突发情况下就能快速地恢复工作,免得写了半天的邮件眨眼之间就没有了。在学了AJAX之后,我也给自己的blog加上了这个功能。当然,这个应用并不只限于blog上,应该说还是比较通用的。

PS.为了开发的方便,我用了一个自己写的AJAX类,具体内容和下载在这里

演示地址

仍旧以代码加注释的方式来说明怎么编写。

首先是表单填写页面,用一个ID为AutoSaveMsg的DIV来显示返回信息,并且用一个ID为Draft_AutoSave的CheckBox来确定是否进行自动保存,然后将Textarea的ID命名为message。同时为了应对多用户同时使用的需要,加上用户名,每个用户的草稿分开保存。为了说明方便,我把一些修饰性的东西去掉,这样看起来比较明了:

  • AJAX应用之草稿自动保存<br />
  • <!– 用户名默认为NONAME –>
  • 用户名:<input type=”text” name=”memName” id=”memName” size=”20″ value=”NONAME” />&nbsp;&nbsp;&nbsp;&nbsp;
  • <!– 在自动保存选项的onclick事件中调用自动保存状态设置函数 –>
  • <input onclick=”SetAutoSave();” type=”checkbox” id=”Draft_AutoSave” value=”1″ checked=”true”  />自动保存?<br />
  • 内容:
  • <textarea id=”message”></textarea><br />
  • <!– AutoSaveMsg显示返回信息 –>
  • <div id=”AutoSaveMsg”></div>
  • <input type=”submit” value=”提交内容” />&nbsp;&nbsp;
  • <!– 调用函数恢复最后保存的草稿 –>
  • <input type=”button” onclick=”AutoSaveRestore();” value=”恢复最后保存的草稿” />
  • </div>
  • </div>
  • <!– 将JS代码放在所有对象之后,以免在页面未加载完成时出现对象不存在的错误 –>
  • <!– AJAX类 –>
  • <script type=”text/javascript” src=”ajaxrequest.js”></script>
  • <!– 自动保存代码 –>
  • <script type=”text/javascript” src=”autosave.js”></script>

接下来是autosave.js

  • // 首先设置全局变量
  • // 要保存的内容对象FormContent
  • var FormContent=document.getElementById(“message”);
  • // 显示返回信息的对象
  • var AutoSaveMsg=document.getElementById(“AutoSaveMsg”);
  • // 用户名
  • var memName=document.getElementById(“memName”).value;
  • // 自动保存时间间隔
  • var AutoSaveTime=60000;
  • // 计时器对象
  • var AutoSaveTimer;
  • // 首先设置一次自动保存状态
  • SetAutoSave();
  • // 自动保存函数
  • function AutoSave() {
  • // 如果内容或用户名为空,则不进行处理,直接返回
  • if(!FormContent.value||!memName) return;
  • // 创建AJAXRequest对象,详细使用见文章开始的链接
  • var ajaxobj=new AJAXRequest;
  • ajaxobj.url=”autosave.asp”;
  • ajaxobj.content=”memname=”+escape(memName)+”&postcontent=”+escape(FormContent.value);
  • ajaxobj.callback=function(xmlObj) {
  • // 显示反馈信息
  • AutoSaveMsg.innerHTML=xmlObj.responseText;
  • }
  • ajaxobj.send();
  • }
  • // 设置自动保存状态函数
  • function SetAutoSave() {
  • // 是否自动保存?
  • if(document.getElementById(“Draft_AutoSave”).checked==true)
  • // 是,设置计时器
  • AutoSaveTimer=setInterval(“AutoSave()”,AutoSaveTime);
  • else
  • // 否,清除计时器
  • clearInterval(AutoSaveTimer);
  • }
  • // 恢复最后保存的草稿
  • function AutoSaveRestore() {
  • // 创建AJAXRequest对象
  • var ajaxobj=new AJAXRequest;
  • // 提示用户正在恢复
  • AutoSaveMsg.innerHTML=”正在恢复,请稍候……”
  • ajaxobj.url=”autosave.asp”;
  • ajaxobj.content=”action=restore&memname=”+escape(memName);
  • ajaxobj.callback=function(xmlObj) {
  • // 提示用户恢复成功
  • AutoSaveMsg.innerHTML=”恢复最后保存成功”;
  • // 如果内容为空则不改写textarea的内容
  • if(xmlObj.responseText!=”") {
  • // 恢复草稿
  • FormContent.value=xmlObj.responseText;
  • }
  • }
  • ajaxobj.send()
  • }

最后是autosave.asp,用于在后台保存草稿:

  • <%@LANGUAGE=”VBscript” CODEPAGE=”65001″%>
  • <% Option Explicit %>
  • <%
  • ‘ 语言为VBScript,编码为UTF-8,要求变量声明
  • ‘ 出现错误则忽略,继续执行
  • On Error Resume Next
  • ‘ 定义一些变量
  • Dim PostContent,memName,action,objStream
  • ‘ 获取操作,是保存草稿还是恢复草稿
  • action=Request.Form(“action”)
  • ‘ 获取用户名
  • memName=Request.Form(“memname”)
  • ‘ 获取草稿内容
  • PostContent=Request.Form(“postcontent”)
  • IF action=”restore” Then
  • ‘ 恢复草稿,如果用户名不为空则进行恢复操作
  • IF memName<>Empty Then
  • ‘ 使用 ADODB.Stream 来进行文件操作
  • Set objStream = Server.CreateObject(“ADODB.Stream”)
  • With objStream
  • .Type = 2
  • .Mode = 3
  • .Open
  • ‘ 文件名为 autosave_ + 用户名 + .txt
  • .LoadFromFile(Server.MapPath(“autosave_”&memName&”.txt”))
  • .Charset = ”utf-8″
  • ‘.Position = 0
  • PostContent = .ReadText()
  • .Close
  • End With
  • Set objStream = NoThing
  • ‘ 输出草稿
  • IF PostContent<>”" Then Response.Write(PostContent)
  • End IF
  • Else
  • ‘ 保存草稿,如果草稿内容和用户名均不为空则进行保存操作
  • IF PostContent<>Empty AND memName<>Empty Then
  • ‘ 使用 ADODB.Stream 来进行文件操作
  • Set objStream = Server.CreateObject(“ADODB.Stream”)
  • With objStream
  • .Type = 2
  • .Mode = 3
  • .Open
  • .Charset = ”utf-8″
  • .Position = objStream.Size
  • .WriteText= PostContent
  • .SaveToFile Server.MapPath(“autosave_”&memName&”.txt”),2
  • .Close
  • End With
  • Set objStream = NoThing
  • ‘ 输出保存是否成功信息
  • If Err.Number=0 then
  • Response.Write(“最后于 ”&Now()&” 自动保存成功”)
  • Else
  • Response.Write(“最后于 ”&Now()&” 自动保存失败,错误号:”&Err.Number&”,错误描述:”&Err.Dscription)
  • End If
  • End IF
  • End IF
  • %>

至此,AJAX草稿自动保存完成了。

AJAX初体验之上手篇

AJAX是这两年蛮热的东西,我也凑凑热闹,前些天去找了些教程学学,下面就按整个处理过程把自己学的东西写写,不过,因为是初学,所以有错误就请见谅啦,也欢迎指正,vipxjw#163.com。

PS.写完了之后看了下,结果再次验证自己写教程真是乱得可以,东说一块西说一块,条理不太清楚的说:)。

1.创建 XMLHttpRequest 对象

现在的浏览器有很多种,创建 XMLHttpRequest 的方法也不相同,所以为了兼容各种浏览器,在创建 XMLHttpRequest 时也应该考虑到各种浏览器的情况。目前主流的浏览器在Windows下有IE、Firefox及Opera,所以我们写的代码要尽量兼容这几个浏览器。在参考了一些资料后,我用下面的方法来创建 XMLHttpRequest 对象:

// 先定义一个变量,并赋初值为 false,方便后面判断对象是否创建成功
var xmlObj = false;
// 使用 try 来捕获创建失败,再换个方法来创建
try {
// 在 Mozilla 中使用这种方式来创建 XMLHttpRequest 对象
xmlObj=new XMLHttpRequest;
}
catch(e) {
try {
// 如果不成功,那么尝试在较新 IE 里的方式
xmlObj=new ActiveXObject(“MSXML2.XMLHTTP”);
}
catch(e2) {
try {
// 失败则尝试使用较老版本 IE 里的方式
xmlObj=new ActiveXObject(“Microsoft.XMLHTTP”);
}
catch(e3) {
// 还是失败,那么就认为创建失败……
xmlObj=false;
}
}
}
// 如果创建 XMLHttpRequest 对象失败,那么提醒访问者该页面可能无法正确访问
if (!xmlObj) {
alert(“XMLHttpRequest init Failed!”);
}
2.使用 XMLHttpRequest 来获取 XML 文档
在用 XMLHttpRequest 来获取 XML 需要注意这个文档必需和自己在同一个域中,我的理解是同一个域名之下,或者同一目录之中,如果不是就会出现“拒绝访问”的错误。在本地高度时,也必需运行一个 Web 服务器,而不能直接在浏览器里打开这个网页。

// 使用 open 方法来打开一个请求,这个方法有3个参数,分别是请求方式,请求文件的URL及同步方式(?不是很清楚具体叫什么来的:)
// 请求方式可以是 GET,POST,HEAD中的一种,因为我要获取文件,所以用 GET
// 请求文件的URL,直接用相对路径即可
// 同步方式,表示请求发出后是等待回应(false)还是继续执行下面的代码(true),即所谓异步了。AJAX的第一个A就是表示异步了,所以这里用 true
xmlObj.open (“GET”, “sample.xml”, true);
// 因为使用异步方式所以要在 XMLHttpRequest 对象的状态改变时做相应的处理
xmlObj.onreadystatechange=function() {
// 如果 XMLHttpRequest 的状态为4,应该是ready来的,那么继续处理
if(xmlObj.readyState==4) {
// 需要判断返回状态是否为200 OK,有些情况如文件不存在,就为返回404
if(xmlObj.status==200) {
// 一切OK,调用处理过程
DoMyXML();
}
}
}
// 发送请求,因为是GET,所以send的内容为null
xmlObj.send(null);

3.用ASP来创建XML文档3.用ASP来创建XML文档
为了动态显示的需要,就要用到动态网页了,我用的是ASP。

<%
‘ 修改头标识指明这是一个XML文档
Response.ContentType=”text/xml”
‘ ……
strXML=”<?xml versin=”"1.0″” encoding=”"gb2312″”?>”
‘ 这里就按XML的要求来输出数据库里的内容了
strXML=strXML&”…..”
‘ ……
Response.Write(strXML)
%>

4.处理XML文档
在获取了XML文档之后,就要从中获取需要的东西了,假如我从服务获取了下面的XML文档:

  • <?xml version=”1.0″ encoding=”gb2312″?>
  • <root>
  • <item>
  • <title>AJAX Study</title>
  • <content>Study AJAX</content>
  • </item>
  • </root>

我要的是title及content的内容,那么可以像下面这样做:

  • function DoMyXML() {
  • var xmlDoc,items,title,content;
  • // 先从XMLHttpRequest对象中得到XML文档
  • xmlDoc=xmlObj.responseXML;
  • // 再得到items
  • items=xmlDoc.getElementsByTagName(“item”);
  • // 最后根据TagName来获取想要的内容
  • // 如果XML文档里有多个item,可以用数组的下标来表示第几个
  • title=items[0].getElementsByTagName(“title”)[0].firstChild.data;
  • content=items[0].getElementsByTagName(“content”)[0].firstChild.data;
  • }

好了,现在已经得到我想要的东西,可以把它们显示出来了。

5.输出处理结果

先假定有一个如下的HTML文档用来显示想要输出的内容:

  • <html>
  • <head>
  • <title>AJAX Study</title>
  • </head>
  • <body>
  • <div id=”mydisplay”></div>
  • </body>
  • </html>

  • 这里定义了一个ID为mydisplay的DIV容器用来显示输出内容,好了,再转到JS:
    • //…接DoMyXML;
    • //content=items[0]…..;
    • var strHTML;
    • // 先组织好要显示的内容
    • strHTML=”Item title: ” + title + ”<br />Item content: ” + content;
    • // 获取目标容器,再设置它的innerHTML为要显示的内容
    • document.getElementById(“mydisplay”).innerHTML=strHTML;

  • OK,这些差不多是编写AJAX程序的基础,具体用就看个人发挥了,当然AJAX并不只这些,还有如果POST方法发送数据等,不过这个还没学过,所以只能讲这些了^_^。还是那句话,因为是初学,有错误在所难免,欢迎指正。
  • [JavaScript] 静态的动态续篇之来点XML

    在搞定了基本的伪动态之后,我马上把它应用到了网站,但随后就发现了一个问题:我如何来管理新闻列表呢?要是让我在每次要加新闻时去修改源文件然后再上传我可是千万个不愿,不仅麻烦而且容易出错,懒人怎么能可以这么做。动动脑子,于是想到了用XML,这个早已存在,但近些年才流行起来的技术。

    在HTML里,可以使用数据岛来使用XML数据,一个使用方法就是在HTML里加入一句:

    <xml id=”data”>

    <!– 在此为XML数据 –>

    </xml>

    这样,就可以在HTML里使用XML提供的数据。不过,这样还是显得麻烦了,还是要上传整个文件,那么用方便点的吧~~

    <xml id=”data” src=”data.xml”/>

    这样处理之后,我就可以只用修改一个XML文件然后上传到服务器了。

    接下来,就是搞定在客户端对XML数据的处理了~~

    首先,我得设计一个新闻的数据结构。这个简单,毕竟在列表时只需要用到新闻的标题和时间,但为了链接,需要加上一个ID,结果如下:

    <newslist>

    <news>

    <id>1</id>

    <title>第一个新闻</title>

    <date>2005-11-16</date>

    </news>

    </newslist>

    数据结构搞定了,继续!

    在客户端对数据处理当然首选JavaScript了,再么这篇文章讲的也是用JavaScript来实现伪动态。

    在JS里,对数据岛的访问可以使用记录集:

    var rs=data.recordset;

    这个记录集的使用方法和ASP中类似,这下方便我了:),可以很方便地实现新闻的列表及链接了~在显示新闻,还需要显示的是上一条新闻的标题及下一条新闻的标题,而且显示新闻列表时,就不需要显示上一条及下一条新闻了。于是我放了两个层分别用来显示新闻和上一条及下一条新闻的信息,并在需要的时候设置是否显示。其中newsmain用来显示新闻或者新闻列表,newspage用来显示上一条及下一条新闻的信息。接着把对应ID的新闻存为网页文件,在显示时使用iframe嵌入。

    先写个函数来从网址中获取新闻ID,这个在前一篇文章已经讲过,拿来用~~

    function getid() {

    var str,len,pos,id,fn;     // 定义一些变量

    str=top.window.location.href;    //获取当然文件地址

    len=str.length;     // 得到地址长度

    pos=str.indexOf(“?id=”,0);   // 得到”?id=”的起始地址

    // 判断是否存在”?id=”

    if(pos>0) {

    id=str.substring(pos+4,len);   // 获取ID

    return eval(id);  // 返回数值类型的ID,方便处理

    }

    else {

    return 0;  // 错误参数,返回0,显示新闻列表

    }

    }

    再来个函数处理进入页面时执行什么动作,是显示新闻列表还是显示相应ID的新闻

    function showmain() {

    var id;

    id=getid();  // 获取新闻ID

    // 是 0 则显示列表

    if(id>0) {

    rs.absoluteposition=id;  // 设置游标到指定的新闻

    shownews(id); // 显示新闻

    }

    else {

    showlist();   // 显示新闻列表

    }

    }

    显示新闻列表的函数

    function showlist() {

    var ss=”";  // HTML

    var i;  // 循环计数器

    rs.movefirst();  // 移动到第一个记录

    // 循环读取新闻记录

    for(i=0;i<rs.recordcount;i++) {

    ss=ss+”<font color=#800000>·</font><a href=’javascript:shownews(“+rs(“id”)+”)’>”+rs(“title”)+”</a>&nbsp;(“+rs(“date”)+”)<br/>”;  // 添加一个新闻

    rs.movenext();  //移动到下一条一新闻

    }

    document.all.newsmain.innerHTML=ss;  //在新闻显示区输出新闻

    document.all.newspage.style.visibility=”hidden”;  // 显示新闻列表时,不显示前后新闻的信息

    }

    显示指定的新闻,并显示前后新闻的信息

    function shownews(id) {

    var ps;  // 用于存放前后新闻的信息

    document.all.newsmain.innerHTML=”<iframe class=’news_main’ frameborder=’0′ src=’news/”+id+”.htm’/>”;  // 用iframe来显示新闻

    document.all.newspage.style.visibility=”visible”;  // 使前后新闻信息可见

    rs.absoluteposition=id;  // 将记录游标移动到当前新闻

    // 如果ID小于1说明是第一条记录,上一篇新闻就是“没有了”:)

    if(id<=1) {

    ps=”上一篇:没有了”;

    }

    // 否则就显示上一篇新闻的标题

    else {

    rs.moveprevious();  // 记录游标向前移动

    ps=”<a href=’javascript:shownews(“+(id-1)+”)’>上一篇:”+rs(“title”)+”</a>”;  // 显示前篇新闻信息

    rs.movenext();  // 恢复记录游标

    }

    ps=ps+”&nbsp;”;  // 在两个信息之间插入一个空格

    // 如果ID大于记录总数说明这是最后一个新闻了~

    if(id>=rs.recordcount) {

    ps=ps+”下一篇:没有了”;

    }

    // 否则显示下篇新闻的标题

    else {

    rs.movenext();  // 记录游标向前移动

    ps=ps+”<a href=’javascript:shownews(“+(id+1)+”)’>下一篇:”+rs(“title”)+”</a>”;  // 显示下篇新闻的标题

    rs.moveprevious();  // 恢复记录游标

    }

    document.all.newspage.innerHTML=ps;  // 显示前后新闻标题~

    }

    好了,到底算是基本完工了~具体使用可以这样来:

    在head区加入XML数据岛

    <head><xml id=”data” src=”newslist.xml”/></head>

    接着在body的onload事件里执行showmain()

    <body onload=”showmain()”>

    还需要在body里加入两个层用于显示信息

    <div id=”newspage”></div>

    <div id=”newsmain”></div>

    完工!

    不过,我所用的方法也有不完善的地方,如新闻列表的ID必须保证顺序排列且不能有缺漏,因为在使用记录集时用到了绝对定位,还有其他等等。我写文章比较烂,所以:欢迎指正批评^-^!也欢迎大家我交流经验心得等,我的mail是vipxjw@tom.com。

    [JavaScript] 静态的动态

    这段时间因为要做个网站,而空间又不支持ASP,所以又拿起JavaScript教程看了下,看能不能在静态的空间里实现动态,当然,这个动态不是真正意义上的了,可以说只是一个“伪动态”了:)

    最基本的动态页面的功能,莫过于news.asp?id=1这样的形式了,于是我就拿这个目标开工,弄了一会还真有些成效~基本构思是:从浏览器的地址栏获取当前文件的地址,然后从其中提取id,最后用内嵌框架来显示相关内容。以下是基本的代码

    <script>
    var str,len,pos,id,fn;     // 定义一些变量
    str=top.window.location.href;    //获取当然文件地址
    len=str.length;     // 得到地址长度
    pos=str.indexOf(“?id=”,0);   // 得到”?id=”的起始地址
    if(pos>0)   // 判断是否存在”?id=”
    {
    id=str.substring(pos+4,len);   // 获取ID
    fn=”<iframe src=’news/” + id + ”.htm’></iframe>”  // 在内嵌框架里显示相关内容
    document.write(fn);   // 输出
    } else {
    document.writeln(“错误的参数!”);  // 不存在ID
    }
    </script>

    这样,就可以把新闻做成页面放在news目录,然后在外部调用news.htm?id=1就可以来查看相关的新闻了~~

    当然这里的代码并不成熟,比如没有判断ID是否为数字等,这等以后去慢慢完善了:)