已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
AJAX 设计模式原名:AJAX Design Patterns摘自 由Snyke发表Fishbone译我想到现在为止,没听说过AJAX的人应该为数不多了吧,甚至没有关注过web开发的人也能感受到新技术的潜力。大家一定已经看烦了那些关于AJAX的介绍文章,介绍AJAX是多么神奇,并拿GOOGLE SUGGEST,GMAIL等等技术来说明AJAX的前途,因此我就不再重复介绍AJAX的发展历史等等了,而直接说说在真实世界里该怎么去应用它。那么我这里所讲的文章跟其他的有什么不同呢?不管是与否,我这里所讲的不是利用AJAX创建一些奇特的小程序,而是讲讲怎么用AJAX来设计和开发一个完整的网站。为了增加文章的可读性,避免使用一些可读性较差的底层代码,我决定用dojo的开发工具toolkit来讲,我也曾经打算采用prototype的js库来讲,因为它写的很好,而且简单易用,但是dojo给我们提供了更多封装好的功能。无论哪种框架,都有一个共同的缺陷:缺少详细的说明文档,我们需要花费很多时间在调试上或在阅读一些解读它代码的文章来帮助理解。对于调试,我建议用firefox浏览器的自带调试工具来调试,它真的是一个不错的调试工具,它能让AJAX更容易理解,特别是它的调试日志记录了每个AJAX的请求信息。本文章,我们将利用AJAX来设计一些组件做为我们交流的入口,当然也得设计一套基本的开发工具,以帮助我们开发更加复杂的程序。我们想要什么?做为一个开发者,我们需要在开始开发之前知道我们要怎么去做。需求分析不是本文章的一部分,所以我们只讲设计模式的一些基本原则:对于页面:加载和显示的HTML代码越简单越规范越好。对于用户:我们需要很好的交互性,所以让用户自己注册,建立资料,并能和其他用户交互这是最基本的功能。对于消息:有些能及时收发消息的web通讯做的很不错,运行起来也简单,而且他可以实现用户和用户只间的交互。论坛:要交流技术或者其他什么话题,那么没有比论坛更合适的了。很多功能将在以后加上去,但是对于现在,上述的这些功能就暂时能满足当前的需求了。页面设计虽然说我们的重点应该放在开发功能上面,但是设计对于程序来说还是同等重要的。如果一个程序写的很好,但是却没有很好的交互性,那么它也就没什么用处了。我们这里将设计一个简单的页面:1. 内容区域2. 边缘导航菜单3. 主菜单(各个组件之间的调用都是建立在这个主菜单之上的)4. 页面标题,没什么好说的5. 在线用户列表组件以AJAX为基础框架的话,我们就可以摆脱老页面的一时一页的模式,来谈谈多事件模式或者MVC-模式。我们可以自定义一些API方法,这些方法可以调用动态语言与后台进行交互。我们可以调用这些API方法进行一些复杂的任务。回到本文章上,我们将用几个小的组件来布置网页,以后我们会结合虚拟组件(virtual modules)来实现一些功能。这些组件包括:页面组件:这是我们运行的第一个组件,这里只是显示从文件取过来的内容,没什么其他特别的。用户组件:这一组件,能完成不同的任务注册:注册一新用户登录:资料:显示用户的相关信息。在线显示:一旦发现有用户上线,就启动控件显示上线的用户信息,而用AJAX来实现这一功能,它的效果几乎是同步的,就是说一有用户上线就马上提示的,而不是延时多少时间才显示出来的。而且它的效率很高,运行简单。论坛:还有什么比论坛的交互性更好的网站?代码的执行我们将我们要用到的功能都封装到一个对象内,这很类似于java里的静态类,这样做的话,我们就可以将不同组件里的命名较清晰地分离开来。首先我们得创建一个引擎。载入其他组件以及使他们跟页面的交互都是通过引擎来处理的。然而在页面交互(包括规划,设计,)和引擎的背后,数据的呈现和输出我们将利用层来做,因为它运行起来简单,所以不必考虑其他的HTML对象了。换句话说,我们是在开发应用程序界面。首先要做的也是最重要的是,引擎得先将一切初始化。var Engine = bootstrap: function() this.setStatus(“Loading”); dojo.require(“dojo.io.*”); dojo.hostenv.writeIncludes(); if(“”+document.location).indexOf(#) 0) Engine.loadPage(“#Page/Welcome”); else Engine.loadPage(“” + document.location); ,这部分代码我想是很容易理解的,它设置了一个进度状态提示信息loading,还包含了一些dojo的库,然后用Engine.loadPage()来显示页面。如你所见,他是将所有的东西都封装在一个对象Engine里面,这样的话,外部的程序很容易调用它。页面载入完成时执行的函数是这样写的:接下来该做的事就是让这个Engine能够载入其他组件,它的完成是通过载入一个包含组件的javascript文件(再次将它自己的命名空间封装)来完成的,通过调用一个组件的init()方法我们就可以初始化这个组件了。 loadedModules: new Array(), modules: new Array(), loadModule: function(module) if(Engine.loadedModulesmodule) return; dojo.io.bind( url: “javascript/” + module + “.js”, sync: true, error: function(type, evaldObj)Engine.showError(“Error while loading module.”);, load: function(type, data, evt) eval(data); Engine.modulesmodule.execute(uri); ); ,在性能上考虑,我们希望组件被装载一次就够了,这就是为什么我们在第1-2行用了两个数组的缘故:loadedModules 这个数组包含了一组布尔型的数据,它是用来告诉我们每个组件是不是已经被载入,第二个数组只是包含了一些对组件的引用(作为一个对象,他们可以这样来引用).loadModules(),其实它本身没什么其他东西,就是一个同步的xmlhttprequest来获取组件的代码功能。因为我们不想让代码没下载完就被调用,所以我们这里是同步的,这样能保证调用都能成功。我们也已经注意到了,代码是在eval()里运行的。现在我们把目光放在loadPage()这个函数上。通过取得一个输入的URI(即js文件的路径),他就能通过控制一个已经载入的组件来载入相应的组件,得到想要的结果: uri: “/”;, loadPage: function(url) Engine.setStatus(“Loading”); if(!url) url = “” + document.location; var hashIndex = url.indexOf(#); if(hashIndex 0 | hashIndex 0) moduleLength = uri.indexOf(/); else moduleLength = uri.length; var module = uri.substring(0,moduleLength); uri = uri.substring(uri.indexOf(/); if(Engine.loadedModulesmodule & ! dojo.lang.isUndefined(Engine.modulesmodule) Engine.modulesmodule.execute(uri); else Engine.loadModule(module); ,URI已经载入,那么以后其他的组件要调用他就没必要再去载入它了。我们可以发先其实loadPage()这个函数所做的主要工作是解析URL地址。通过第一个参数来判断哪一个组件需要被载入是相当简单的。也许很多人会问,为什么我们得用象这样的/Page#This/is/a/long/string URL地址呢?那是因为我们我们不想丢弃标签在页面中的作用。AJAX本身其实抛弃了书签的作用,因为它的所读取的信息和展现的信息都是在一个页面中的,然而如果不是AJAX的话,每一个URL地址其实都是独立的一个资源。我们通过在URL地址的最后面添加#以及一些额外数据的方法来使得浏览器认为我们是在访问新的网址,这样的话,AJAX会重新装载页面。bootstrap()这个函数其实也是通过传递URL给loadPage()来载入页面的。简而言之:当用户第二次访问我们的网站时,只要输入URL地址就可以看到,我们访问过的URL页面都还在历史记录里保留着。URL的解析步骤:1.#前面的所有字符是程序的地址2.#和第一个/之间的是组件名,如果它是存在的就会被载入3./到URL地址的结束之间的字符作为组件中的调用函数execute()里的参数(可以参见下面的例子)那么我们现在能做的就是运行一些将在后面组件中用到的示例性的函数:setStatus: function(message) if($(status) != null) $(status).parentNode.removeChild($(status); var body = document.getElementsByTagName(“body”)0; var div = document.createElement(“div”); div.style.position = “absolute”; div.style.top = “50%”; div.style.left = “50%”; div.style.width = “200px”; div.style.margin = “-12px 0 0 -100px”; div.style.border = “0px”; div.style.padding = “20px”; div.style.opacity = “0.85; div.style.backgroundColor = “#353555; div.style.border = “1px solid #CFCFFF”; div.style.color = “#CFCFFF”; div.style.fontSize = “25px”; div.style.textAlign = “center”; div.id = status; body.appendChild(div); div.innerHTML = message; , hideStatus: function() Engine.opacityDown($(status); , opacityDown: function(theElement) if(theElement = null) return; var opacity = parseFloat(theElement.style.opacity); if (opacity 0.08) theElement.parentNode.removeChild(theElement); else opacity -= 0.07; theElement.style.opacity = opacity; setTimeout(function()Engine.opacityDown(theElement);, 50); return true; , setContent: function(content) $(content).innerHTML = content; , showError: function(message) Engine.setStatus(message); setTimeout(“Engine.hideStatus()”,10000); 到此为止,引擎已经讲完了,完整代码可以在/AjaxTutorial/stage1/javascript/Engine.js下载到 第一个组件那么我们现在就来运行我们的第一个组件。他的任务是通过异步的方式从外部载入一个额外的资源(一个HTML页面)然后在我们的内容区域显示出来。var Page = init: function() Engine.modules“Page” = Page; Engine.loadedModules“Page” = true; , execute: function(uri) try dojo.io.bind( url: “resources” + uri + “.php”, sync: false, error: function(type, evaldObj) Engine.showError(“Error while loading Content.”);, load: function(type, data, evt) Engine.setContent(data); Engine.hideStatus(); ); catch(e) alert(e); Page.init();当组件被载入,他会到引擎里先注册自己(参见init()函数)然后引擎会调用execute()方法异步取得页面资源,然后将它在内容区域显示出来。是不是很简单?
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高中地理(高一年级)复习讲义:从“成本驱动”到“新质赋能”的产业地理跃迁
- 【初中道德与法治 八年级 主题班会教学设计】破浪前行正当时-拒绝“45°摆荡”拥抱扎根式成长
- 【备考参考】解码区域图:2026高考地理(广东专版)综合创新复习讲义
- 2026年地震避震自救知识培训
- 节能门窗清洁方案范本
- 2026年公共基础知识幼儿园在编
- 2026年HCIP-高频考点模拟题及解析
- 2026年农业电商运营师考试题集
- 2026年火灾应急救护知识
- 2026年机械行业招聘专业知识模拟题
- 四川省凉山州2025年中考物理真题附同步解析
- 湖北省部分高中2025届高三下学期四月统考(二模)政治试卷(含解析)
- DB32T 5124.3-2025 临床护理技术规范 第3部分:成人危重症患者有创动脉血压监测
- 小学一年级数学下册应用题大全300题【满分必刷】
- 中外比较文学研究专题知到智慧树期末考试答案题库2024年秋湖南师范大学
- 委托代缴社保协议书范例
- 智库能力测试题及答案
- T-FDSCX 002-2024 福鼎白茶标准
- 中外航海文化知到课后答案智慧树章节测试答案2025年春中国人民解放军海军大连舰艇学院
- 《政府与集团项目型公关策略和销售技巧》
- CNAS-CC01:2015 管理体系认证机构要求
评论
0/150
提交评论