<p> “我最初看到有几个网站在做一些我想做的事情,但是还没有完全是现在的样子。我是想做的一些网络应用最早是想用FLASH的,但是我手下的员工对FLASH不熟悉,我想怎么样用传统的Web技术也能达到FLASH的效果。后来我在实践中发现,可以把JavaScript 和 XML 这两种传统的Web技术让来实现。”<p> 以上文字是Ajax的提出者Jesse James Garrett在“internet+互联网世纪论坛”上接受新浪网专访时所讲的话。你看了这段文字有什么想法呢,是不是觉得FLASH与Ajax存在些共同点。前两天写了一篇名叫《asp+ajax打造无刷新新闻评论系统》的文章,文章中通过一个实例的讲解大致的阐述了关于Ajax的使用,今天,我想利用同样的服务器端代码,再看看在FLASH中将如何的实现。</p><p> FLASH软件版本:flash 8</p><p> 操作系统:中文 Windows 操作系统</p><p> 一、Flash知识点</p><p> 1、 useCodepage</p><p> 一个布尔值,它通知 Flash Player 是使用 Unicode 来解释外部文本文件,还是使用运行播放器的操作系统的传统代码页来解释外部文本文件。默认值为 false。</p><p> 由于本文所调用的外部文件采用了GB2312,并非采用Unicode,因此必须将System.useCodepage=True, 当然如果你想确保在所有平台下运行正常,建议外部文件使用Unicode。</p><p> 2、 attachMovie(MovieClip.attachMovie 方法)</p><p> public attachMovie(id:String, name:String, depth:Number, [initObject:Object]) : MovieClip</p><p> 参数:</p><p> id:String - 库中要附加到舞台上某影片剪辑的影片剪辑元件的链接名称。这是在"链接属性"对话框中的"标识符"字段中输入的名称。“链接属性“通过右击库中元件”链接“弹出。</p>
<p> </p>
<p> name:String - 附加到该影片剪辑的影片剪辑实例的唯一名称。</p><p> depth:Number - 一个整数,指定 SWF 文件所放位置的深度级别。</p><p> initObject:Object [可选] - (Flash Player 6 和更高版本支持)包含要用来填充新附加的影片剪辑的属性的对象。此参数使动态创建的影片剪辑能够接收剪辑参数。如果 initObject 不是对象,则忽略它。initObject 的所有属性都已复制到新实例中。使用 initObject 指定的属性对于构造函数是可用的。</p><p> 返回 MovieClip - 对新创建的实例的引用。</p><p> 示例:将链接标识符为 pllist 的元件附加到主场景中。</p><p> _root.attachMovie("pllist", "pllist", 1);</p><p> 3、 影片剪辑动态路径的表示方法</p><p> 由于程序中大部分影片剪辑都是通过动态加载的,对于影片剪辑的个数以及位置都是事先不确定的,这就必须要求我们在程序运行的过程中给影片剪辑设置。一般情况下我们对于动态加载的影片剪辑命名都会遵循着这样一个规律:mc1、mc2、mc3、mc4……,那么我们如何来表示这些动态的影片剪辑呢?</p><p> [ ] 数组访问运算符</p><p> 数组访问运算符使您能够动态地设置和检索实例、变量和对象的名称。它还使您能够访问对象属性。</p><p> 示例:_root[“mc”+i]</p><p> Eval 函数</p><p> 按照名称访问变量、属性、对象或影片剪辑。如果表达式是变量或属性,则返回该变量或属性的值。如果表达式是对象或影片剪辑,则返回对该对象或影片剪辑的引用。如果无法找到表达式中列举的元素,则返回 undefined。</p><p> 示例:eval(“_root.mc”+i)</p><p> 4、 XML类</p><p> load(XML.load 方法)</p><p> 从指定的 URL 中加载 XML 文档,并使用下载的 XML 数据替换指定 XML 对象的内容。该 URL 是相对 URL,并使用 HTTP 进行调用。加载过程是异步的;它不会在执行 load() 方法后立即结束。</p>
<p> </p>
<p> 执行 load() 方法时,XML 对象的 loaded 属性被设置为 false。在 XML 数据下载完毕后,loaded 属性被设置为 true,并调用 onLoad 事件处理函数。直到 XML 数据完全下载后,才开始分析。如果该 XML 对象以前包含任何 XML 树,它们将被放弃。</p><p> 您可以定义一个在调用 XML 对象的 onLoad 事件处理函数时执行的自定义函数。</p><p> 示例:xml.load("pl_list.asp");</p><p> onLoad(XML.onLoad 处理函数)</p><p> onLoad = function(success:Boolean) {}</p><p> 接收到来自服务器的 XML 文档时由 Flash Player 调用。如果成功接收了 XML 文档,则 success 参数为 true。如果未收到该文档,或从服务器接收响应时出现错误,则 success 参数为 false。默认情况下,此方法的实现不处于活动状态。若要覆盖默认实现,必须指定一个包含自定义动作的函数。</p><p> 这段函数功能与Ajax中的xhr.onreadystatechange=function(){}</p><p> 示例:xml.onLoad = function(ok) {if (ok) {init();}};</p><p> attributes(XMLNode.attributes 属性)</p><p> public attributes : Object</p><p> 一个对象,其中包含指定的 XML 实例的所有属性。XML.attributes 对象为 XML 实例的每个属性包含一个变量。因为这些变量定义为该对象的一部分,所以通常将它们称为该对象的属性。每个属性的值以字符串形式保存在相应的属性中。例如,如果您有一个名为 color 的属性,则可以通过将 color 指定为属性名称来检索该属性的值.</p><p> 示例:xml.firstChild.attributes.tot</p><p> childNodes(XMLNode.childNodes 属性)</p><p> public childNodes : Array [read-only]</p><p> 指定 XML 对象的子级的数组。数组中的每个元素都是对表示子级节点的 XML 对象的引用。</p>
<p> </p>
<p> 示例:user = xml.firstChild.childNodes[c].childNodes[0];</p><p> 二、FLASH的实现</p><p> 基本思路</p><p> 基本思路与AJAX相似:首先通过xml类读取外部文件中评论信息,传递给flash中的元件模型,并根据评论的个数确定所要生成的元件数,并呈现在主场景中。</p><p> 页面界面:</p><p> <img src="/content/uploadfile/200805/2008053117024980.jpg" onclick="get_larger(this)" title="请点击图片查看原图" /></p><p> 具体操作步骤:(关于美工方面的问题自己斟酌)</p><p> 1、新建flash文档,600*600像素。</p><p> 2、新建影片剪辑pl(如下图),并在其中插入三个动态文本框,变量为别为user,dateandtime,contents,并分别选中“将文本呈现为HTML”,添加一个删除按钮,属性名为del;按F11打开库面板,右击pl选择”链接”,勾取“为actionscript导出”,并将“标识符”设为pl。</p><p> <img src="/content/uploadfile/200805/2008053117025361.jpg" onclick="get_larger(this)" title="请点击图片查看原图" /></p><p> 3、新建影片剪辑pllist,在其中添加一个动态文本框,变量为tot,并将左距离与上距离分别设为10与520,同样设置其标识符为pllist,此影片剪辑主要用于显示整个评论列表。</p><p> 4、新建影片剪辑gopage(翻页按钮),添加一个动态文本框,变量为curpage,用于显示页数,并为此影片添加第二帧,主要用于移上去所呈现的效果。</p><p> 5、如图页面界面,在主场景中添加两个按钮ok和no,设置其在场景中的名称分别为tjpl与tjno,然后在主场景中添加两个动态文本框用于填写评论呢称与内容,设置其在场景中的名称分别为u、c,这里我们可以设置u的最大字符数为20,以保持和数据库对应,再次添加一个文本框用于信息提示,设置其变量为msg。</p>
<p> </p>
<p> 6、以上工作全部做好后,接下来就是添加代码了,当然如果你觉得界面还是不够漂亮,你可再调整调整,最后在主场景的第一帧添加如下代码:</p><code> System.useCodepage = true; //使用操作系统的传统代码页来解释外部文本文件<br /> var xml = new XML(); //创建XML类<br /> xml.load("pl_list.asp"); //加载外部文件<br /> msg = "正在加载评论……";<br /> xml.onLoad = function(ok) {<br /> if (ok) {<br /> init(); //加载成功后调用init函数<br /> }<br /> };<br /> //解析外部文件<br /> function init() {<br /> _root.attachMovie("pllist", "pllist", 1); //为主场景添加一个pllist影片剪辑<br /> _root.pllist.tot = "共"+xml.firstChild.attributes.tot+"条"+" 当前第"+xml.firstChild.attributes.curpage+"页";//获得所有评论数与当前页码<br /> for (i=0; i<br /> drawPllist(i);//绘制评论列表<br /> }<br /> _root.pagecount(xml.firstChild.attributes.tot);<br /> msg = "加载成功";<br /> }<br /> //评论列表绘制函数<br /> function drawPllist(c) {<br /> _root.pllist.attachMovie("pl", "pl"+c, c);//将库中影片剪辑附加到pllist影片剪辑中<br /> with (_root.pllist["pl"+c]) {//这句可以用with(eval("_root.pllist.pl"+c)){替换<br /> _x = 20; //设置厅距离<br /> _y = 20+c*100;//设置上距离<br /> user = xml.firstChild.childNodes[c].childNodes[0];//获得呢称<br /> dateandtime = xml.firstChild.childNodes[c].childNodes[1].toString();//获得评论时间<br /> contents = xml.firstChild.childNodes[c].childNodes[2].toString();//获得评论内容<br /> }<br /> var xid = xml.firstChild.childNodes[c].childNodes[3].toString();//获得评论id,用于删除操作<br /> _root.pllist["pl"+c].del.onRelease = function() {<br /> xml.load("pl_del.asp?id="+substring(xid, 5, length(xid)-9));<br /> xml.onLoad = function(ok) {<br /> if (ok) {<br /> msg = "删除成功!";<br /> }<br /> xml.load("pl_list.asp");//删除后再次加载<br /> xml.onLoad = function(ok) {<br /> if (ok) {<br /> init();<br /> }<br /> };<br /> };<br /> };<br /> }<br /> //翻页处理<br /> function pagecount(tot) {<br /> if (tot%5 == 0) { //计算页数<br /> pages = int(tot/5);<br /> } else {<br /> pages = int(tot/5)+1;<br /> }<br /> for (var j = 1; j<=pages; j++) {<br /> drawpage(j);<br /> }<br /> }<br /> //绘制翻页按钮<br /> function drawpage(j) {<br /> _root.pllist.attachMovie("gopage", "gopage"+j, j+10);<br /> with (_root.pllist["gopage"+j]) {<br /> _x = 100+j*30;<br /> _y = 520;<br /> curpage = j;<br /> }<br /> _root.pllist["gopage"+j].onRelease = function() {<br /> xml.load("pl_list.asp?page="+j);<br /> msg = "正在加载评论……";<br /> xml.onLoad = function(ok) {<br /> if (ok) {<br /> init();<br /> }<br /> };<br /> };<br /> _root.pllist["gopage"+j].onRollOver = function() { this.gotoAndStop(2);<br /> };<br /> _root.pllist["gopage"+j].onRollOut = function() {<br /> this.gotoAndStop(1);<br /> };<br /> }<br /> //tjpl按钮事件,用于添加评论<br /> _root.tjpl.onRelease = function() {<br /> if (_root.u.text != "" and _root.c.text != "") {<br /> _root.msg = "正在添加!";<br /> xml.load("pl_fb.asp?newsid=1&user="+_root.u.text+"&content="+_root.c.text);<br /> xml.onLoad = function(ok) {<br /> if (ok) {<br /> msg = "添加成功!";<br /> }<br /> xml.load("pl_list.asp");<br /> xml.onLoad = function(ok) {<br /> if (ok) {<br /> init();<br /> }<br /> };<br /> };<br /> } else {<br /> msg = "呢称或内容为空,添加失败!";<br /> }<br /> };<br /> //tjno按钮事件,用于清空呢称与内容,以便重新填写<br /> _root.tjno.onRelease = function() {<br /> _root.c.text = "";<br /> _root.u.text = "";<br /> };</code><p> 我希望大家在阅读本篇文章时能够与前一篇文章对比起来阅读,由于本文为了和上一篇文章对照,而且采用了与上一篇同样的服务器端代码,因此有些地方在程序开发时就显得不尽人意。例如在FLASH调用xml时,习惯用attributes这个对象去获得属性值,而本篇却全部采用了元素节点,害得文中在取删除id就只好通过字符串函数截取,希望大家在开发应用系统时注意。</p>