Dojo1.11官方教程文档翻译(1.3)新的Dojo
DOJO学习笔记(06)--字符串控件dojo.string
dojo学习笔记(三)模块:mon / dojo.stringmon 和 dojo.string 是一样的,只要require其中一个就可以使用以下方法dojo.string.trim去掉字符串的空白Usage Example:s = " abc ";dojo.string.trim(s); //will return "abc"dojo.string.trim(s, 0);//will return "abc"dojo.string.trim(s, 1);//will return "abc "dojo.string.trim(s, -1);//will return " abc"dojo.string.trimStart去掉字符串开头的空白Usage Example:s = " abc ";dojo.string.trimStart(s); //will return "abc " dojo.string.trimEnd去掉字符串结尾的空白Usage Example:s = " abc ";dojo.string.trimEnd(s); //will return " abc" dojo.string.repeat生成由同一字符(串)重复组成的字符串Usage Example:dojo.string.repeat("a", 4); //will return "aaaa"dojo.string.repeat("1234", 3, "-"); //will return "1234-1234-1234" dojo.string.pad使用字符补齐字符串Usage Example:dojo.string.pad("100", 6);//will return "000100"dojo.string.pad("100", 6, "0", 1);//will return "000100"dojo.string.pad("100", 6, "0", -1);//will return "100000"dojo.string.padLeft使用字符补齐字符串开头Usage Example:dojo.string.padLeft("100", 6); //will return "100000" dojo.string.padRight使用字符补齐字符串结尾Usage Example:dojo.string.padRight("100", 6); //will return "100000"模块:mon / ngmon 和 ng 是一样的,只要require其中一个就可以使用以下方法ng.mixin将一个对象的方法和属性增加到另一个对象上Usage Example:var s1 = {name: "TestObj", test1: function(){alert("this is test1!"); }}var s2 = {value: 1000, test2: function(){alert("this is test2!");}} var d = {};ng.mixin(d, s1, s2); //执行后d就具备了s1和s2的所有属性和方法d.test1();ng.extend为指定类的原型扩展方法与属性Usage Example:TestClass = function() {};ng.extend(TestClass, {name: "demo", test: function(){alert("Te st!");}});var o = new TestClass(); //TestClass本来是没有test方法的,但是extend 以后就有test方法了o.test();ng.find=ng.indexOf查找指定对象在指定数组中的位置Usage Example:var arr = [1,2,3,3,2,1];ng.find(arr, 2);//will return 1 ng.find(arr, 2, true);//will return 1ng.find(arr, "2", true);//will return -1ng.find(arr, "2", false);//will return 1ng.find(arr, 2, true, true); //will return 4ng.findLast=stIndexOf查找指定对象在指定数组中的位置,从后往前查Usage Example:var arr = [1,2,3,3,2,1];ng.findLast(arr, 2);//will return 4 ng.findLast(arr, 2, true);//will return 4ng.findLast(arr, "2", true);//will return -1ng.findLast(arr, "2", false);//will return 4ng.inArray查找指定对象是否在指定数组中Usage Example:var arr = [1,2,3];ng.inArray(arr, 1);//will return true ng.inArray(arr, 4);//will return falseng.isObject判断输入的类型是否为对象Usage Example:ng.isObject(new String()); //will return trueng.isObject("123")); //will return falseng.isArray判断输入的类型是否为数组Usage Example:ng.isArray({a:1,b:2}); //will return falseng.isArray([1,2,3]); //will return trueng.isFunction判断输入的类型是否为函数Usage Example:ng.isFunction(function() {}); //will return trueng.isString判断输入的类型是否为字符串Usage Example:ng.isString(""); //will return trueng.isString(0); //will return falseng.isAlien判断输入的类型是否为系统函数Usage Example:ng.isAlien(isNaN); //will return trueng.isBoolean判断输入的类型是否为布尔类型Usage Example:ng.isBoolean(2>1); //will return trueng.isNumber判断输入的类型是否为数值,根据注释所说,此函数使用不太可靠,但是可替换使用的系统函数isNaN也不太可靠ng.isUndefined判断输入是否为未定义,根据注释所说,此函数有可能会导致抛出异常,推荐使用 typeof foo == "undefined" 来判断模块:ng.extrasng.setTimeout延迟指定时间后执行指定方法Usage Example:function onTime(msg){dojo.debug(msg)}ng.setTimeout(onTime, 100 0, "test"); //1秒后会输出调试信息"test"ng.setTimeout(dojo, "debug", 1000, "test"); //1秒后会输出调试信息"test"ng.getNameInObj获得指定项目在指定对象中的名称Usage Example:ng.getNameInObj(dojo, dojo.debug); //will return "debug" ng.shallowCopy返回指定对象的浅表复制副本Usage Example:ng.shallowCopy({}); //will return a 空对象ng.firstValued返回第一个存在定义的参数Usage Example:var a;ng.firstValued(a,2,3); //will return 2。
Dojo中文使用手册
Dojo中文使用手册本手册针对0.9、1.0及1.x版本。
目录快速安装Hello World-第一个程序程序调试第一部分:使用Dojo-Dojo和Dijit例子第一个例子:为什么一些人不填写传真表单?第二个例子:总是点击两次第三个例子:和技术人员交谈第二部分Dijit-Dojo的小部件库概述共用特征表单、验证和个性化的文本输入框表单小部件复选框、单选框、切换(?)组合框(ComboBox)下拉过滤选择框(FilteringSelect)数字选择框(NumberSpinner)滑尺(Slider)文本输入域(Textarea)文本框类(验证、货币、数字、日期、时间)布局(只讲一个tabContainer)命令控制按钮、组合按钮和下拉按钮菜单工具菜单用户使用帮助提示和反馈进度条提示对话框和工具对话框页框(TitlePane)高级功能(只讲一个Tree)树(Tree)第三部分:使用Dojo和Dijit与javascript协作通用性初始对象模块建立和设计小部件自已设计小部件类事件系统异步交互XMLHttpRequest(XHR)拖拽使用Dojo.Data接口使用dojo.query选择DOM节点回退按钮其它功能多个版本共处于一个页面第四部分:调试第五部分:Dojox扩展包cometd(客户端)dojox图表dojox集合dojox加密dojox数据dojox网格(翻译)dojox离线(翻译)快速安装Dojo 提供了三种安装方式:1.使用美国在线(AOL)的内容分发网络(CDN)上的dojo.2.在本地使用dojo的一个稳定版本.3.从dojo网站的SVN服务器上获取的最新代码.使用内容分发网络(CDN)上的Dojo这种方法非常的快捷!你能够通过添加一个<script> 到美国在线(AOL)的内容分发网络(CDN)上,而无需占用你服务器上的任何空间和资源.所有在这本手册里出现的Dijit范例均通过此方法获取Dojo的js文件.你可以直接拷贝粘贴第1,2部分的任何例子到你自己的服务器上就可以正常的运行了!在第3部分的例子中,因为很多是一些代码片段,所以我们将提醒您如何做一些更改以便使这些例子正常运行. 您可以使用: <script type="text/javascript"src="/dojo/1.0.0/dojo/dojo.xd.js"></script> 来引用Dojo的js 文件请参考: Dojo And AOL获取最新的引用链接.使用本地的Dojo如果您是Dojo的传统用户,你可以以以往的方式下载,安装,并且使用Dojo.1.从/downloads下载最新的Dojo2.解压缩文件到本地服务器上. 假设您将文件安装到/js目录下,其目录结构应该如下(注:dojo1.2.3版本与本目录不相同,只有dojo、dijit、dojox三个子目录)。
dojo快速入门
DOJO快速入门出处2006年初,dojo还是0.22的时候就很关注它的发展,可一直没有在实际项目中使用。
一来是由于文档的缺少,而来是dojo的相关介绍总是让人望而生畏。
到现在都如此,第一个hello world就搞了一大堆东西,比如widget组件,自定义的script标签等,加上要引入什么css文件,djConfig、dojo.require等等,让人很迷惑,这么复杂,到底dojo该怎么使用呢?我只是想把dojo当作一个普通的js类库,就像prototype那样?OK,闲话少说,来看看如何使用dojo。
-----------------------------------------------------------------------------------------------------什么是dojo?dojo Toolkit 是一个开源的JavaScript工具包用于构造web应用。
它通过提供设计良好的api和工具包缩短了实现设计的时间。
它是轻量极其健壮的,提供工具来实现DOM操作,动画,ajax,event 和键盘标准化, 国际化I18N,可访问性(a11y).Dojo基本上是单独一个轻量级的实体(26kb). Dojo是完全免费的,又一组活跃于社区的developer开发。
无论项目的大小,Dojo都是一个弹性的解决方案。
内建的package系统不再使查找依赖成为问题,build系统合并优化各层的代码,D.O.H使单元和回归测试很容易。
Add-ons除了dojo.js提供的大量工具,通过调用dojo.require(),使用强大的package 系统可以为系统增加很多功能。
Dojo核心包括drag&drop,高级ajax传输,字符串处理,强大的Data API等等。
无穷的可能性dojo toolkit 也包括称为Dijit的项目包。
它是用于使用和创建封装的和可重用的组件或widgets。
dojo学习笔记
Dojo 学习笔记(1. 模块与包)Intro:Dojo 是一个非常强大的面向对象的JavaScript 的工具箱, 建议读者能够去补充一下JavaScript 下如何使用O O进行编程的, 这对于你以后阅读Dojo Source 有很大的用处.请大家下载dojo 0.3.1, 以下的说明均针对此版本翻译自/WikiHome/DojoDotBook/BookUsingDojoGetting Started1: 把Dojo 加入到我们的Web程序中1. 标志<script type="text/javascript">djConfig = { isDebug: false };</script>djConfig 是Dojo 里的一个全局对象, 其作用就是为Dojo 提供各种选项, isDebug 是最常用的属性之一,设置为True 以便能够在页面上直接看到调试输出, 当然其中还有些属性与调试有关, 这里就不罗索了2. 引用dojo 的启动代码<script type="text/javascript" src="/yourpath/dojo.js" />这样你就引用了dojo 的代码, 并可以直接使用其中部分常用的对象, 下载下来的dojo.js 是压缩(remove comments and space) 后的代码, 要阅读的话, 建议阅读dojo.js.uncompressed.js, dojo.js大概有127K, 而未压缩前有211K, ok, 为什么会这么大呢, 原来其已经把部分常用的模块整合进dojo.js 里 ,因此显得大了一点, build.txt 里就说明了默认的dojo.js 包含了哪些模块3. 声明你所要用到的包<script type="text/javascript">dojo.require("dojo.math");dojo.require("dojo.io.*");dojo.require("dojo.widget.*");</script>你就把这些代码当成是java 的import 语句或 C #中的using 语句一样, 如果你不require 的话, 而模块本身又没有整合在dojo.js 中, 是会出现脚本错误的喔2. 针对不同需求提供的预整合包Dojo 本身是由许多模块所组合而成的, 但是由于用户需求的多样性, dojo 针对不同的需求而提供了不同的版本, 用户在下载dojo 的时候就看见可以选择很多的版本, 比如Ajax 版和Widget 版, 每个版本最重要的区别就在于dojo.js 文件, 但是除此之外, 每一个版本都是全功能的, dojo.js 根据版本的不同而整合进了不同的模块3. 直接获取Dojo 的最新源代码首先你必须安装Subversion, 当Subversion 在你的电脑上能够正常工作后, 你就可以通过如下命令下载dojo 的源代码:svn co /dojo/trunk/这会在你的当前目录下创建一个trunk 的目录; 如果你希望直接Get 到当前目录, 用这个命令:svn co /dojo/trunk/ .或者你希望Get 到当前目录下的MyDir 目录, 用这个命令:svn co /dojo/trunk/ MyDir模块与包模块Dojo 的代码被划分为逻辑单元称之为模块, 这有点类似于Java 中的package, 除了dojo 的模块能够包含类( 类似于java 中的classes) 和简单函数比如: 模块"dojo.html" 包含了一系列的函数, 比如dojo.html.getContentBox(), 模块"dojo.dnd" 包含了一系列的HtmlDragObject 的类注意名称约定, 函数的首字母为小写字母, 类的首字母为大写模块也可以称之为"命名空间"包在多数情况下, dojo 的模块只需要定义在一个文件就可以了, 但有时, 一个模块可能划分到多个文件,比如: 模块dojo.html, 本来是定义在一个文件中, 可是由于功能的增强, 文件逐渐变大, 我们不得不将其拆分为多个文件, 这主要是为性能考虑, 以便浏览器可以只下载其需要用到的代码, 不幸的是其实现细节对于dojo 的用户看起来不那么透明, 你必须知道你想要用到的功能到底是包含在哪个文件,然后才能require 并使用它这样的每一个文件都称之为一个包dojo.require("dojo.html.extras")将引用文件src/html/extras.js, 这将定义模块dojo.html 的若干( 并非所有) 函数据我所知, 尽管单个文件可以定义包里的多个类, 单个脚本文件不能定义多个模块( 在Java 可以等效于在一个文件中定义 2 个类), 并且, 包的名称和模块的名称可以不同, 比如: 包dojo.widget.Button 定义了dojo.widget.html.Button基本上你应该这样认为, 包和模块尽管密切相关, 但是是两个完全不同的实体为什么会有模块和包这样的概念?为什么会有模块和包这样的概念? 为了满足你的应用程序只需要加载其所用到的东西的需求, 充分利用模块化设计的优点, dojo 维护了最小的足印以便仍能提供你所需要的功能, 为什么要你的用户浪费时间去下载用不到的JavaScript, 当一个包就是一个js 文件时, 一个模块本质上就是一个命名空间, 比如:dojo.style 或dojo.html.extras多数简单情况下, 一个包包含了一个模块, 但更常见的是, 一个模块可能被拆分为几个包文件利用包和模块, 将能确保你能够交付最相关的功能代码, 最小程度的减少代码的膨胀和消除由此带来的不好的用户体验, 这就是模块设计的主要目标, 通过模块化, 你能够引入自定义模块( 你自己拥有的JavaScript 工具), 并且维护模块对于核心代码库基本不会产生什么影响另外, Dojo 的模块系统也提供了内建的机制来使用代码提供命名空间, 比如, 通过模块dojo.event 定义的Dojo 的事件系统怎样引用设置引用语句你怎样才能知道该引用哪个包到dojo.require()?1. 模块首先, 确定你要使用什么模块, 这个例子我们假定你要使用dojo.lfx.html2. 包搜索代码后你发现dojo.lfx.html 定义在 2 个文件:src/lfx/html.jssrc/lfx/extras.js根据你要用到的功能, 你可以dojo.require("dojo.lfx.html");或dojo.require("dojo.lfx.html");dojo.require("dojo.lfx.extras");通配符新用户可能会对dojo.lfx.* 这样就可以替代上面 2 句而感到诧异, 实际上,__package__.js 中已经定义了通配符可以代替的语句, 并且这样可以让dojo 根据当时的环境而决定加载具体的模块/////////////////////////////////////////////////////////////////////////////////////////Dojo 学习笔记(2. djConfig 解说)djConfig 是dojo 内置的一个全局设置对象,其作用是可以通过其控制dojo 的行为首先我们需要在引用dojo.js 前声明djConfig 对象,以便在加载dojo.js 的时候才能够取得所设置的值,虽然在0.3 版本以后dojo 支持在加载后设置,但是强烈建议你把声明djConfig 的代码作为第一段script一个完整的djConfig 对象定义如下(值均为dojo 的默认值)<script type="text/javascript">var djConfig = {isDebug: false,debugContainerId: "",bindEncoding: "",allowQueryConfig: false,baseScriptUri: "",parseWidgets: truesearchIds: [],baseRelativePath: "",libraryScriptUri: "",iePreventClobber: false,ieClobberMinimal: true,preventBackButtonFix: true,};</script>isDebug 是一个很有用的属性,顾名思义,如果设置为真,则所有dojo.Debug 的输出有效,开发时应该设置为true ,发布时应该设置为falsedebugContainerId 同样也是与调试有关的,如果不指定的话,调试信息将会直接利用document.write 输出,这样可能会破坏页面的整体布局,所以你可以指定任何一个可以作为容器的html 元素的id 作为调试信息输出容器allowQueryConfig ,这个属性指明dojo 是否允许从页面url 的参数中读取djConfig 中的相关属性,当值为true 时,dojo 会优先从url 参数中读取djConfig 的其他属性,比如: http://server/dojoDemo.htm?djConfig.debugContainerId=divDebugbaseScriptUri ,一般不需要设置,dojo 会自动根据你引用dojo.js 的路径设置这个值,比如,<script type="text/javascript" src="../dojo/dojo.js"></script> ,自动获取的值便是../dojo/ps: 如果你有多个工程需要同时引用dojo.js 的话,建议也把dojo 当作一个独立的工程,引用的时候采用绝对路径就可以了parseWidgets ,这个是可以控制dojo 是否自动解析具有dojoType 的html 元素为对应的widget ,如果你没有使用任何Widget ,建议设置为false 以加快dojo 的加载速度searchIds ,这是一个字符串数组,定义了所有需要解析为widget 的html 元素的ID,如果ID 不在其中的html元素是不会被解析的,当数组为空数组时,则所有具有dojoType 的元素都会被解析还有一个bindEncoding ,是用来设置默认的bind 请求的编码方式至于其它的属性,不是用处不大,就是不知道有什么作用在实际开发中,可以把djConfig 的定义放在一个js 文件里,并将其作为第一个引用的js 文件,这样应该是最方便的。
dojo
<div id="tab1" dojoType="yout.ContentPane" title="Tab1" closable="true">hi</div>
<style type="text/css">
@import "../js/dojo/resources/dojo.css";
@import "../js/dijit/themes/tundra/tundra.css";
.dijitInputFieldFocused{
border:solid 2px #FFDF00;
}
</style>
<script type="text/javascript" djConfig="parseOnLoad:true,isDebug:true" src="../js/dojo/dojo.js"></script>
<script>
dojo.require("dijit.form.ValidationTextbox");
如果和dnd连在一起还可以实现拖动
标签页内,用户可以方便在不同的标签页之间切换,关闭某个标签页,或者删除某个标签页。
DojoQuery详解
} }
在上述代码中,我们需要对页面中的所有节点进行遍历,逐一判断其 className 属性是否满足匹配条件才行。通过这个典型的例子,我们可以清楚地看到,使用 Dojo Query 在 DOM 节点查询方面具有非常显著的优势。 事实上,使用 Dojo Query 不仅在表达查询条件的简洁性上会更具优势,相比于直接利用 DOM API 进行处理的方式,其执行速度也通常会更加的快。接下来读者便会看到,这一点尤其在我们需要查询相对复杂的页面节点 关系时,会变得更为突出。 除了上述我们看到的,Dojo Query 提供了基本的依据 tag、class、id 进行查询的方式以外,它还提供了许多更为复杂的查询语法,而所有这些语法则都遵循于 CSS 规范。Dojo Query 的这一做法十分的明智,因为 CSS 是已经被大家所广泛使用和接受了的一种 Web 技术,其对 HTML 页面元素进行选择性修饰的方式,兼具语法简洁和功能强大的特点,目前所有的主流浏览器都对 CSS 有很好的支持。Dojo Query 沿用了 CSS 的语法,使得 使用者无需学习一整套新的查询语法,便可以很好的掌握 Dojo Query 的使用,以完成各种复杂的查询功能。 目前,Dojo Query 支持许多常见的 CSS 选择器语法。例如,我们可以利用较为复杂的类选择器语法,实现对符合指定 class 属性的指定元素进行查询:
}); </script> </head> <body>
<button id="b1" /> <button id="b2" /> <form id="thisForm" >
DOJO中文手册
什么是dojo<script type="text/javascript">djConfig = { isDebug:</script><script type="text/javascript" src="/yourpath/dojo.js" /><script type="text/javascript">dojo.require("dojo.math");dojo.require("dojo.io.*");dojo.require("dojo.widget.*");</script>svn co /dojo/trunk/svn co /dojo/trunk/ .svn co /dojo/trunk/ MyDirdojo.require("dojo.html.extras")dojo.require("dojo.lfx.html");dojo.require("dojo.lfx.html"); dojo.require("dojo.lfx.extras");<script type="text/javascript"> varisDebug:debugContainerId: "",allowQueryConfig:baseScriptUri: "",parseWidgets:searchIds: [],baseRelativePath: "", libraryScriptUri: "",iePreventClobber:ieClobberMinimal:preventBackButtonFix: };</script>dojo.event.kwConnect({srcObj: dojo.byId("inputTest"),srcFunc: "onclick",adviceObj: obj,adviceFunc: "doOnclick2",type: "before", //默认为"after",可选: "before", "around",注意:type是用来决定adviceFu nc的行为的,如果为"around",则aroundFunc将失效aroundObj: null,aroundFunc: null, //如果指定了aroundFunc,则其将对adviceFunc进行拦截,但是当type为"around"时,则aroundFunc将不会执行once: false, //默认为false,允许重复绑定delay: 3000, //延时3秒后执行adviceFuncrate: 0, //这个从源代码没有看懂起什么作用adviceMsg: false //这个从源代码没有看懂起什么作用});dojo.event.kwDisconnect用来解除使用kwConnect指定的绑定模块:dojo.event.topicTopic机制与Advice机制都能够实现事件的绑定,但是显然,Topic更适合处理多重绑定。
DOJO API中文参考手册附加注解实例
djConfig 是 dojo 内置的一个全局设置对象,其作用是可以通过其控制 dojo 的行为 首先我们需要在引用 dojo.js 前声明 djConfig 对象,以便在加载 dojo.js 的时候才能够取得所设置的值,虽然在 0.3 版本以后 dojo 支持在加载后设置,但是强烈建议你把声明 djConfig 的代码作为第一段 script
searchIds: [], baseRelativePath: "", librarys criptUri: "", iePreventClobber: false, ieClobberMinimal: true, preventBackButtonFix: true, }; </s cript> isDebug 是一个很有用的属性,顾名思义,如果设置为真,则所有 dojo.Debug 的输出有效,开发时应该 设置为 true,发布时应该设置为 false debugContainerId 同样也是与调试有关的,如果不指定的话,调试信息将会直接利用 document.write 输出, 这样可能会破坏页面的整体布局,所以你可以指定任何一个可以作为容器的 html 元素的 id 作为调试信息 输出容器 allowQueryConfig,这个属性指明 dojo 是否允许从页面 url 的参数中读取 djConfig 中的相关属性,当值为 true 时,dojo 会优先从 url 参数中读取 djConfig 的其他属性,比 如: http://server/dojoDemo.htm?djConfig.debugContainerId=divDebug bases criptUri,一般不需要设置,dojo 会自动根据你引用 dojo.js 的路径设置这个值,比如,<s cript type="text/javas cript" src="../dojo/dojo.js"></s cript>,自动获取的值便是 ../dojo/ ps: 如果你有多个工程需要同时引用 dojo.js 的话,建议也把 dojo 当作一个独立的工程,引用的时候采用 绝对路径就可以了 parseWidgets,这个是可以控制 dojo 是否自动解析具有 dojoType 的 html 元素为对 应的 widget,如果你没有使用任何 Widget,建议设置为 false 以加快 dojo 的加载速度 searchIds,这是一个字符串数组,定义了所有需要解析为 widget 的 html 元素的 ID,如果 ID 不在其中的 html 元素是不会被解析的,当数组为空数组时,则所有具有 dojoType 的元素都会被解析 至于其它的属性,不是用处不大,就是不知道有什么作用 在实际开发中,可以把 djConfig 的定义放在一个 js 文件里,并将其作为第一个引用的 js 文件,这样应该 是最方便的。 实现功能:在一个容器里点击一个链接,在另外一个容器中显示这个链接所指向页面的内容。 <html> <head> <script src="./dojo/dojo.js"> </script> <script> dojo.require("dojo.widget.ContentPane"); var links = null, display = null; dojo.addOnLoad(init); function init(){ links = dojo.widget.byId("links"); display = dojo.widget.byId("display"); // listen to links domNode for onclick event // lowercased on all DOM events as opposed to widget events //"onclick",必须是小写的 dojo.event.connect(links.domNode, "onclick", 'relayClicks'); } // finds out if this is a link event function relayClicks(evt){ var node = evt.target;//取得事件源 if(node.nodeName.toLowerCase() == "a"){ // it is a link, prevent the browser from unloading the page evt.preventDefault(); // change page in display pane display.setUrl(node.href); } } </script> </head> <body> <h1>Example on how to easily relay <a href="someurl.html" target="display"> clicks</h1> <div dojoType="ContentPane" widgetId="links"
Dojo中文手册
实战Dojo工具包一个品质远远超出“原型建造”的Ajax库原文链接:/articles/dojo-in-practice/DojoToolkitInPractice.pdf 源代码下载:/articles/dojo-in-practice/dojo-itinerary.tgz译文链接:/upload/DojoInPractice.rar作者:Dion Almaer()译者:李锟()版本号:1.0版权声明:本文是有版权的著作,原文的版权属于原作者所有,译文的版权属于译者所有。
译者在得到了原作者的许可后翻译了这篇文章。
译文允许在不做任何改动(包括原文/译文链接、作者/译者信息、版权声明、文章的全部内容)的情况下自由转载。
内容目录1 简介 (3)2 Dojo工具包:JavaScript开发的水槽(Kitchen Sink) (3)3 设置和配置Dojo (4)3.1 选择正确的Dojo创建 (4)3.2 动态加载package (5)3.3 定制的创建 (5)4 应用:旅行路线编辑器 (6)5 DOM和HTML效果 (6)5.1 处理DOM (7)5.2 Dojo的HTML效果 (8)6 使用dojo.io.bind()的Ajax远程调用 (8)6.1.1 淡出和移除 (9)6.1.2 使用XMLHttpRequest来告诉服务器发生了什么 (9)7 拖放操作 (10)7.1.1 连接所有的天 (11)7.1.2 连接单个的天 (11)7.1.3 onLoad (11)8 结论 (12)9 作者简历 (12)1 简介当你开始建造一个Ajax应用时,你很快就会遇到一些情形,让你感觉自己好像是在重新发明轮子。
大量的开发者一想到Ajax,就会直接扑向XMLHttpRequest对象,但这仅仅只是一个开始,而且是Ajax开发中很容易的部分。
当你在建造JavaScript富客户端应用时,你会遇到大量令人烦恼的事情。
dojo学习
(一). Dojo基本1. Dojo分为三个项目:dojo是Dojo的基础,所有其他的功能都建立在其上,总之,它包含大约50个JavaScript脚本和几个其他资源。
这些资源用于处理浏览器差异的统一,JavaScript模块化,JavaScript核心库扩展,W3C DOM API扩展,远程脚本编程,拖放,数据存储API,本地化和国际化,以及一些其他的附加功能。
dijitDojo的小部件框架和内建的小部件集,widgets,例如TAB,TREE等dojoxDojo扩展库。
这包含了从表格小部件到绘图库的所有功能,例如ENHANCEDGRID, 2D,3D图形,图表,等2. Dojo常用方法dojo.require引用JS文件DOJO特色,按需加载JS文件dojo.addOnLoad表示在HTML页面加载后执行脚本程序dojo.byId按照DOMID得到一个DOM对象、(document.getElementsById)dijit.byId每个DIJIT UI组件有个ID,此函数通过ID获取一个UI对象dojo.forEach循环遍历数组通过id 来获得Dijit 实体没有通过dojo.byId() 方法而是使用的dijit.byId() 方法。
在Dojo 体系中,如果想通过Dijit 的id 来获得Dijit 实体,只能通过dijit.byId()。
而作用与document.getElementById() 相同的dojo.byId(),无法获得任何Dijit 实体。
Dojo 组织认为DOM 对象实体和Dijit 实体是两个完全不同的对象实体类型。
通过id 去获得这两种实体也应该使用不同的方法。
dojo.byId() 被分配用来获得DOM 对象实体,而dijit.byId() 则被分配用来获得Dijit 类型的实体(二). Dojo的使用1. 引入css样式表的定义文件<style type="text/css">@import"js/dijit/themes/tundra/tundra.css";@import"js/dojo/resources/dojo.css";</style>现在引用dojo自带的css样式。
DOJO系列教程一
DOJO系列教程一:Base作为专栏开篇,我们下面就从Base讲起。
Base是经过高度优化的工具箱内核,我喜欢把它看成是JavaScript标准库,要使用Dojo没有它是万万不行的。
简单地说,Base 提供了一系列语言实用程序,针对那些可能会导致代码膨胀的“你想实现但又不必自己编码的任务”。
我们知道,为节点添加样式、添加和移除类、查询DOM、处理作用域、简单的褪色动画、标准化事件模型,以及操作列表等等任务恐怕是没有穷尽的(几乎如此)。
AOL通过它们的CDN(Content Delivery Network,内容分发网络)提供在线的Dojo支持,而其中Base的“通过网络传输”(经过gzip压缩)仅有约27KB,这就让Dojo 很臃肿的说法不攻自破了。
27KB是一个比充斥于Web中的大多数Flash广告都要小的净荷,即使最慢的连接也能在瞬间完成下载。
AOL的CDN作为一种地理边际缓存(edge-cached)系统,不会让你苦苦等待页面加载。
闲话少说,言归正传。
接下来我们就开始介绍一些实用的代码。
用于将Base加载到页面中的基本模板如下所示:<html><head><title>Dojo Goodness, Part 1 </title><script type="text/javascript"src="/dojo/1.0/dojo/dojo.xd.js"></script><script type="text/javascript">dojo.addOnLoad(function() {/* Do stuff... */});</script></head><body><a href="">Dojo</a></body></html>如你所见,这个页面模板中除了包含一个加载Dojo组件的SCRIPT标签之外没有什么特别之处。
dojo类机制简介
dojo类机制简介随着AJAX和RIA技术的发展,JavaScript被广泛的使用,并在开发中发挥着越来越重要的作用。
JavaScript提供了特有的类机制,但是在语法习惯上与传统面向对象的语言有很大的不同,这使得不少的JavaScript开发人员感到比较迷惑,而dojo作为功能强大的JavaScript类库,有功能完整的类机制实现。
本文将通过实例介绍dojo的类机制,这是dojo提供的一种强大和灵活的功能,其dijit UI组件框架也是以此为基础实现的。
1. 使用dojo定义类声明dojo类是通过dojo.declare()方法来实现的,如我们想要定义一个名为com.levinzhang.Person的类,该类有name、age属性和getName、getAge方法:dojo.declare(\ name:null, age:null, constructor:function(name,age){ }, getName:function(){ },getAge:function(){ } }); 除了前面提到的属性的和方法以外,在代码中我们还定义了一个名为constructor的方法,这个方法在dojo的类机制中至关重要,当我们实例化该类得到对象的时候,该方法将会被调用,从而完成初始化的操作。
dojo的declare接受三个参数,分别为类的名称、要继承的父类以及该类的属性和方法。
实例化类的语法也很简洁,与实例化普通的JavaScript类并无分别: var person = new com.levinzhang.Person(\alert(person.getName());//将会提示出levinzhang2. 实现静态变量在常见的面向对象语言中,经常会使用到类层次的静态变量,而通过dojo定义的类也能实现静态变量的需求,不过静态变量仅限于数组和对象类型。
staticInfo:{count:0}, constructor: function(name,age){ = name; this.age = age; ++this.staticInfo.count; return this.age; return ; = name; this.age = age; } 如上所示,如果定义了数组和对象,而没有在构造方法中进行修改的话,这个对象将会成为该类的静态属性,测试代码如下: var person = new com.levinzhang.Person(\alert(person.staticInfo.count);//此时将会提示出1 var person2 = newcom.levinzhang.Person(\alert(person2.staticInfo.count);//此时将会提示出2需要注意的两点是:1)对于原始类型的变量如数字、布尔值和字符串,dojo的类机制并没有提供实现静态属性的功能;2)如果定义的数组或对象属性在constructor方法中被重新赋值,那么该属性将不再是静态属性,而是每个实例化对象都持有一份属于自己的备份了。
Dojo学习笔记(1. 模块与包)
Dojo学习笔记(1. 模块与包)Dojo是一个非常强大的面向对象的JavaScript的工具箱, 建议读者能够去补充一下JavaScript下如何使用OO进行编程的, 这对于你以后阅读Dojo Source有很大的用处请大家下载dojo 0.3.1, 以下的说明均针对此版本翻译自/WikiHome/DojoDotBook/Book UsingDojoGetting Started1: 把Dojo加入到我们的Web程序中1. 标志<script type="text/javascript">djConfig = { isDebug: false };</script>djConfig是Dojo里的一个全局对象, 其作用就是为Dojo提供各种选项, isDebug是最常用的属性之一, 设置为True以便能够在页面上直接看到调试输出, 当然其中还有些属性与调试有关, 这里就不罗索了2. 引用dojo 的启动代码<script type="text/javascript" src="/yourpath/dojo.js" /> 这样你就引用了dojo的代码, 并可以直接使用其中部分常用的对象,下载下来的dojo.js是压缩(remove comments and space)后的代码,要阅读的话,建议阅读dojo.js.uncompressed.js, dojo.js大概有127K, 而未压缩前有211K, ok,为什么会这么大呢, 原来其已经把部分常用的模块整合进dojo.js里, 因此显得大了一点,build.txt里就说明了默认的dojo.js包含了哪些模块3. 声明你所要用到的包<script type="text/javascript">dojo.require("dojo.math");dojo.require("dojo.io.*");dojo.require("dojo.widget.*");</script>你就把这些代码当成是java的import语句或C#中的using 语句一样, 如果你不require的话, 而模块本身又没有整合在dojo.js中, 是会出现脚本错误的喔2. 针对不同需求提供的预整合包Dojo本身是由许多模块所组合而成的, 但是由于用户需求的多样性, dojo针对不同的需求而提供了不同的版本,用户在下载dojo的时候就看见可以选择很多的版本, 比如Ajax版和Widget版, 每个版本最重要的区别就在于dojo.js 文件,但是除此之外, 每一个版本都是全功能的, dojo.js根据版本的不同而整合进了不同的模块3. 直接获取Dojo的最新源代码首先你必须安装Subversion, 当Subversion在你的电脑上能够正常工作后,你就可以通过如下命令下载dojo的源代码:svn co /dojo/trunk/这会在你的当前目录下创建一个trunk 的目录; 如果你希望直接Get到当前目录, 用这个命令:svn co /dojo/trunk/ .或者你希望Get到当前目录下的MyDir 目录, 用这个命令: svn co /dojo/trunk/ MyDir模块与包模块Dojo的代码被划分为逻辑单元称之为模块,这有点类似于Java中的package,除了dojo的模块能够包含类(类似于java中的classes)和简单函数比如: 模块"dojo.html"包含了一系列的函数, 比如dojo.html.getContentBox(), 模块"dojo.dnd"包含了一系列的HtmlDragObject的类注意名称约定, 函数的首字母为小写字母,类的首字母为大写。
Dojo学习笔记01-03
Dojo 通过很少的代码完成了以上的功能。 (以后可能我详细说说 Dojo 的系统 包 ,只需要三个 js 文件)。当你写脚本时,只需要包含很少的 js 文件(大小)。 也可以选择的(包含)下载 Dojo 提供的庞大的功L 和 JavaScript 脚本语言不变的情况下,用不同的 render 方式展示数据。更进一步,the DojoML 剖析器可以接受 html 和 svg 为输入,容易的建立降级反应的应用。
dojo.requireIf(dojo.html.ie, "dojo.html"); dojo.html.ie 为 true,才会加载 dojo.html 模块
//如果
dojo.provide 除非你要开发自己的模块,不然是用不到这个方法的,你可以这 句看成是向系统注册这个模块名称 Usage Example: dojo.provide("dojo.custom"); dojo.exists 判断指定对象是否具有指定名称的方法 Usage Example: dojo.exists(dojo, "exists"); //will return true
Standard Widget Toolkit) 如果 dojo.html.ie 为 true 的话 dojo.html.ie50 dojo.html.ie55 dojo.html.ie60 dojo.html.ie70 返回 true 说明浏览器是 IE 5.0 返回 true 说明浏览器是 IE 5.5 返回 true 说明浏览器是 IE 6.0 返回 true 说明浏览器是 IE 7.0
* WebWork * Tapestry * Eclipse ATF * MyFaces 这个列表还会随着时间的推移而扩大。 Dojo 的开发团队由 Alex Russell 领军,人数众多,力量非常强大。
Dojo离线技术应用:支持离线功能的Web编辑器
Dojo 离线技术应用:支持离线功能的 Web 编辑器级别: 初级莫 映, 高级工程师, IBM张 顺, 软件工程师, IBM2009 年 9 月 16 日本文以一个完整的示例为读者介绍如何将 Dojo 离线技术应用于实际。
贯穿全文的示例是一个在线的 Web 编辑器。
在这个示例中,我们将完成:如何为一个已有的在线Web 编辑器引入离线编辑功能,同时还包括如何编写相应的服务器端代码,以接受并同步来自客户端的编辑内容。
通过阅读本文,读者能够了解到使用 Dojo 离线库的完整过程,以及使用过程中的个中细节与注意事项。
概述使用 Dojo 离线功能可以在页面加载时保存页面内容及其相关的图片、CSS 与 JavaScript 等资源,如此,即便在离线情况下我们也能够继续对页面进行操作,并且操作内容可以被如实地保存于本地,并在与服务器的连接被恢复时自动同步至服务端。
使用 Dojo 离线功能,可以有效提高用户访问的可靠性,并增进用户的体验。
在《 使用 Dojo 开发离线应用》一文中,我们介绍了 Dojo 离线功能的基本功能、实现原理及编程模式,本文中,笔者将以一个完整的示例为读者介绍如何将 Dojo 离线技术应用于实际。
贯穿全文的示例是一个在线的 Web 编辑器。
在这个示例中,我们将完成:如何为一个已有的在线 Web 编辑器引入离线编辑功能,同时还包括如何编写相应的服务器端代码,以接受并同步来自客户端的编辑内容。
通过阅读本文,读者能够了解到使用 Dojo 离线库的完整过程,以及使用过程中的一些细节与注意事项。
线编辑器器Moxie 离线编辑Moxie 是一个包括服务器端与客户端实现的较为完整的 Dojo 离线应用,功能较为单一,程序结构清晰,代码简洁,是一个较好的 Dojo 离线示例应用程序,从中我们可以系统地学习如何使用 Dojo 离线库进行页面缓存和处理各种事件等。
我们在使用在线编辑器的过程中,经常会遇到由于编辑时间过长导致 session 过期,或是网络连接断开,编辑内容无法保存的情况。
Dojo1.6官方教程创建自定义Dojo小部件(Widget)
Dojo 1.6 官方教程: 创建自定义Dojo小部件(Widget)在这个教程中,我们将会演示如何利用Dojo 和Dijit框架来创建自定义的小部件。
主要会使用到dijit._Widget 和dijit._Templated 基类和mixin。
对dijit框架的基础知识,可以参看前两篇教程难度:中等适用Dojo版本:1.6作者:Brian ArnoldBrian Arnold is a software engineer at SitePen, Inc. He has a lovely wife, two cute dogs, is an active member of (and presenter at) Webuquerque, and ranks among the top 3% of fake guitarists in Rock Band.原文连接:/documentation/tutorials/1.6/recipes/custom_widget/feijia *****************Dojo的Dijit 库包含了丰富的界面小部件(Widgets),通过使用这些小部件,可以打造出强大的Web应用界面,从高级的表单元素,到复杂页面布局。
但是对于一些较复杂的应用,开发者仍会碰到做进一步定制的需求,例如非常复杂的信息展示需求。
你当然可以手动的自己构造DOM来展示数据,但是如果利用Dijit已经提供的框架和工具,我们可以快速的开发出灵活又强大的自定义小部件。
场景假设我们需要开发一个能展示所有Dojo教程作者的简介信息的页面。
我们手头的数据源是如下的JSON数据:[html]view plainc opy1.[2. {3. "name": "Brian Arnold",4. "avatar": "/includes/authors/brian_arnold/avatar.jpg",5. "bio": "Brian Arnold is a software engineer at SitePen, Inc., ..."6. },7. /* More authors here... */8.]我们的需求是把这些信息以下面的DOM结构展示在页面上:1.<body>2.<!-- Headers and whatnot -->3.<h2>Authors</h2>4.<div id="authorContainer">5.<!-- Authors go here! -->6.</div>7.</body>当然,我们希望这个展示页面可以再加点效果,例如当鼠标移到某个作者上时,背景色可以淡入显示。
Dojo实用API大全(中文注解)
Dojo实用API大全(中文注解)Dojo实用API大全(中文注解)模块:dojo.domdojo.dom.isNode测试指定对象是否为节点Usage Example:dojo.dom.isNode(dojo.byId('edtTitle'));dojo.dom.getUniqueId取得唯一idUsage Example:dojo.dom.getUniqueId(); //will return dj_unique_# dojo.dom.firstElement = dojo.dom.getFirstChildElement 取得指定节点下的第一个满足指定Tag条件的子节点Usage Example:dojo.dom.firstElement(parentNode, 'SPAN');/doc/ed12850707.html,stElement = dojo.dom.getLastChildElement取得指定节点下的最后一个满足指定Tag条件的子节点Usage Example:/doc/ed12850707.html,stElement(par entNode, 'SPAN');dojo.dom.nextElement = dojo.dom.getNextSiblingElement 取得指定节点的下一个满足指定Tag条件的子节点Usage Example:dojo.dom.nextElement(node, 'SPAN');dojo.dom.prevElement = dojo.dom.getPreviousSiblingElement取得指定节点的前一个满足指定Tag条件的子节点Usage Example:dojo.dom.prevElement(node, 'SPAN');dojo.dom.moveChildren把指定节点下的所有子节点移动到目标节点下,并返回移动的节点数Usage Example:dojo.dom.moveChildren(srcNode, destNode, true); //仅移动子节点,srcNode中的文字将被丢弃dojo.dom.moveChildren(srcNode, destNode, false);//包括文字和子节点都将被移动到目标节点下dojo.dom.copyChildren把指定节点下的所有子节点复制到目标节点下,并返回复制的节点数Usage Example:dojo.dom.moveChildren(srcNode, destNode, true); //仅复制子节点,srcNode中的文字将被忽略dojo.dom.moveChildren(srcNode, destNode, false);//包括文字和子节点都将被复制到目标节点下dojo.dom.removeChildren删除指定节点下的所有子节点,并返回删除的节点数Usage Example:dojo.dom.moveChildren(node);dojo.dom.replaceChildren用指定的新节点替换父节点下的所有子节点Usage Example:dojo.dom.replaceChildren(node, newChild); //目前还不支持newChild为数组形式dojo.dom.removeNode删除指定的节点Usage Example:dojo.dom.removeNode(node);dojo.dom.getAncestors返回指定节点的父节点集合Usage Example:dojo.dom.getAncestors(node, null, false); //返回所有的父节点集合(包括指定的节点node)dojo.dom.getAncestors(node, null, true); //返回最近的一个父节点dojo.dom.getAncestors(node, function(el){/* 此处增加过滤条件 */return true}, false); //返回所有满足条件的父节点集合dojo.dom.getAncestorsByTag返回所有符合指定T ag的指定节点的父节点集合Usage Example:dojo.dom.getAncestorsByTag(node, 'span', false); //返回所有的类型为SPAN的父节点集合dojo.dom.getAncestorsByTag(node, 'span', true); //返回最近的一个类型为SPAN的父节点dojo.dom.getFirstAncestorByTag返回最近的一个符合指定Tag的指定节点的父节点Usage Example:dojo.dom.getFirstAncestorByTag(node, 'span'); //返回最近的一个类型为SPAN的父节点dojo.dom.isDescendantOf判断指定的节点是否为另一个节点的子孙Usage Example:dojo.dom.isDescendantOf(node, ancestor, true); //判断node 是否为ancestor的子孙dojo.dom.isDescendantOf(node, node, false); //will return truedojo.dom.isDescendantOf(node, node, true); //will return falsedojo.dom.innerXML返回指定节点的XMLUsage Example:dojo.dom.innerXML(node);dojo.dom.createDocument创建一个空的文档对象Usage Example:dojo.dom.createDocument();dojo.dom.createDocumentFromText根据文字创建一个文档对象Usage Example:dojo.dom.createDocumentFromText('1','text/xml'); doc.load根据文件装在XMLUsage Example:var doc = dojo.dom.createDocument();doc.load('http://server/dojo.xml');dojo.dom.prependChild将指定的节点插入到父节点的最前面Usage Example:dojo.dom.prependChild(node, parent);dojo.dom.insertBefore将指定的节点插入到参考节点的前面Usage Example:dojo.dom.insertBefore(node, ref, false); //如果满足要求的话就直接退出dojo.dom.insertBefore(node, ref, true);dojo.dom.insertAfter将指定的节点插入到参考节点的后面Usage Example:dojo.dom.insertAfter(node, ref, false); //如果满足要求的话就直接退出dojo.dom.insertAfter(node, ref, true);dojo.dom.insertAtPosition将指定的节点插入到参考节点的指定位置Usage Example:dojo.dom.insertAtPosition(node, ref, "before");//参考节点之前dojo.dom.insertAtPosition(node, ref, "after"); //参考节点之后dojo.dom.insertAtPosition(node, ref, "first"); //参考节点的第一个子节点dojo.dom.insertAtPosition(node, ref, "last"); //参考节点的最后一个子节点dojo.dom.insertAtPosition(node, ref); //默认位置为"last"dojo.dom.insertAtIndex将指定的节点插入到参考节点的子节点中的指定索引的位置Usage Example:dojo.dom.insertAtIndex(node, containingNode, 3); //把node 插入到containingNode的子节点中,使其成为第3个子节点dojo.dom.textContent设置或获取指定节点的文本Usage Example:dojo.dom.textContent(node, 'text'); //设置node的文本为'text'dojo.dom.textContent(node); //返回node的文本dojo.dom.hasParent判断指定节点是否有父节点Usage Example:dojo.dom.hasParent(node);dojo.dom.isTag判断节点是否具有指定的tagUsage Example:var el = document.createElement("SPAN");dojo.dom.isTag(el, "SPAN"); //will return "SPAN"dojo.dom.isTag(el, "span"); //will return ""dojo.dom.isTag(el, "INPUT", "SPAN", "IMG"); //will return "SPAN"模块:dojo.event终于进入有名的dojo事件处理系统的学习了,学习前建议读者先去补习一下AOP的相关知识dojo.event.connect绑定指定的方法到指定的对象的方法上Usage Example:简单绑定1function doOnClick1(){alert("Clicked!");}dojo.event.connect(dojo.byId("inputT est"),"onclick","doOnCl ick1");简单绑定2obj = { doOnClick2: function(){ alert("Clicked!");}}dojo.event.connect(dojo.byId("inputT est"),"onclick",obj,"do OnClick2");如果存在需要进行多个事件的绑定的时候,你就会看到dojo的方便之处了obj2 = { doOnClick2: function(){alert("Clicked!");}}dojo.event.connect(dojo.byId("inputT est"),"onclick",obj,"do OnClick2");dojo.event.connect(dojo.byId("inputT est"),"onclick",obj2,"do OnClick2");connect可以对任何对象的方法进行绑定,而不是只能针对DOM 对象dojo.event.connect(obj,"doOnclick2","doOnClick1"); //在调用obj.doOnclick2()后调用doOnClick1()dojo.event.connectBeforedojo.event.connect默认是后绑定,connectBefore则是早绑定,绑定的方法将在指定方法前执行,用法与connect一致dojo.event.connectAroundUsage Example:function aroundTest(invocation){//此处可以增加代码,比如检查参数(invocation.args)var result = invocation.proceed();//此处可以增加代码,比如修改结果(result)return result;}dojo.event.connectAround(dojo.byId("inputTest"),"onclick"," aroundTest");dojo.event.connectOnce说起这个函数,还真的是让我想了半天,直觉上我就把它想象成executeOnce,结果测试的结果让我差点想不通connectOnce就是指保证只绑定一次,来避免重复绑定会导致的重复执行的问题dojo.event.disconnect解除绑定,调用参数与connect一致,即可解除之前的绑定操作dojo.event.log在执行指定对象的指定方法后自动记录日志Usage Example:dojo.event.log(obj, "doOnClick"); //当调用obj.doOnClick时记录下日志"DEBUG: ([object Object]).doOnClick : "你也可以这样写:dojo.event.log({srcObj: obj, srcFunc: "doOnClick"});dojo.event.kwConnectkwConnect可以做到更加灵活的绑定,比如可以设置延迟执行绑定Usage Example:dojo.event.kwConnect({srcObj: dojo.byId("inputTest"),srcFunc: "onclick",adviceObj: obj,adviceFunc: "doOnclick2",type: "before", //默认为"after",可选: "before", "around",注意:type是用来决定adviceFunc的行为的,如果为"around",则aroundFunc将失效aroundObj: null,aroundFunc: null, //如果指定了aroundFunc,则其将对adviceFunc进行拦截,但是当type为"around"时,则aroundFunc 将不会执行once: false, //默认为false,允许重复绑定delay: 3000, //延时3秒后执行adviceFuncrate: 0, //这个从源代码没有看懂起什么作用adviceMsg: false //这个从源代码没有看懂起什么作用});dojo.event.kwDisconnect用来解除使用kwConnect指定的绑定模块:dojo.event.topicTopic机制与Advice机制都能够实现事件的绑定,但是显然,Topic更适合处理多重绑定。
针对 Java 开发人员的 Dojo 概念
针对Java 开发人员的Dojo 概念简介:Dojo 在基于Web 的应用程序中越来越受到欢迎。
很多开发人员是Java™ 编程方面的能手,但是在JavaScript 方面却缺乏经验。
从强类型、面向对象的编译语言转向动态的、弱类型脚本语言,开发人员需要经历概念跃迁带来的困难。
这种混乱使开发人员很难正确地声明Dojo 类。
本文将帮助梳理这种混乱,解释为何必须设置上下文,以及如何实现它。
简介如果您是一名只有很少或根本没有JavaScript 经验的开发人员,在接触Dojo 时可能需要掌握一些必要的概念。
Dojo 的一个主要问题是(在撰写本文之际),它仍然处于其婴儿期(版本 1.0 在2008 年 2 月份才发布),并且可用的文档仍然非常有限。
本文将帮助您理解Dojo 和Java 代码之间的联系,使您在开发应用程序时可以快速入手并掌握这个工具箱。
本文并没有介绍如何获得Dojo 工具箱或一些必要的使用指令,因为已经有大量的资源提供了此类信息。
本文主要针对从servlet 开发转向Dojo 的Web 开发人员。
Ajax 资源中心请访问Ajax 资源中心,这是有关Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。
任何Ajax 的新信息都能在这里找到。
JavaScript hash需要面对的主要挑战之一就是理解在调用Dojo 函数时使用的语法,特别是“hash” 或JavaScript 对象。
hash 被表示为使用逗号间隔的一组属性,并且使用大括号括起。
清单1 显示了一个简单的例子,它声明了一个包含6 个属性的hash:一个字符串、一个整数、一个布尔值、一个未定义的属性、另一个hash 和一个函数。
清单1. 示例JavaScript hashvar myHash = {str_attr : "foo",int_attr : 7,bool_attr : true,undefined_attr : null,hash_attr : {},func_attr : function() {}};注意,JavaScript 是弱类型的,因此尽管每个属性被初始化为一个与其名称相关的值,但仍然需要把str_attr 属性设置为一个整数或布尔值(或其他任何类型)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Dojo1.11官方教程文档翻译(1.3)新的Dojo起步Dojo1.7是Dojo Toolkit向现代架构的一个重大转变,Dojo1.10在这个趋势上更进一步。
因为它广泛的向后兼容,为了充分利用Dojo1.10的优势,一些基本概念由此发生了改变。
这些概念将作为Dojo2.0的基础,采用这些新概念将帮你在正确的路上走得更远。
当然为了从这些新的要素(如dojo\/on )中直接获益,你需要采用其中一些新概念。
本教程将解释一些Dojo中介绍的概念,主要侧重于新的Dojo。
我会尽力说明为什么作出改变和如何改变。
一些变化是从根本上的出现的,咋一看会很迷惑,但它们都有着充分的理由——让你的代码更高效、运行更快、玩转JavaScript、更棒的可维护性。
总之,花时间去理解modern Dojo是值得的。
本教程不是一个手把手的版本迁移指导,但对于很熟悉Dojo的你来说,它远胜于一个初级概念读本。
更多的技术细节请参考Dojo 1.X to 2.0 Migration Guide 。
Hello新世界新Dojo的一个核心理念就是全局命名空间是件坏事。
这有很多原因,在一个复杂的web应用中,全局命名空间很容易被各种代码污染,特别是当许多组织使用多重JavaScript框架时。
我甚至不用从安全的角度去提那些故意修改全局命名空间产生的恶果。
如果你打算在新Dojo中的全局命名空间里访问一些东西,请剁手。
由于向后兼容的原因大量的toolkit暂时是全局范围的,但不要用在新的开发中。
当你发现你在输入dojo.* 或dijit.* 或dojox.* ,你正步入歧途。
那些只是引入dojo.js 来获取一个核心功能然后输入dojo.something 来require几个模块到你的核心内容的开发者们,你们真的要改改了,因为这么干真的很糟。
再来一次,跟着我念“全局命名空间真烂,全局命名空间真烂,我才不用全局命名空间,我才不用全局命名空间”。
另一个核心理念是同步作业很慢,而异步通常更快。
旧Dojo已经从dojo.Deferred获得了异步JavaScript强大血脉,但是对于新Dojo,希望一切都异步操作。
为了加强Dojo的模块化以及上述理念的影响,在Dojo1.7中采用统一模块命名叫做异步模块定义(AMD)。
就是说Dojo模块加载器从根本上的重写通常都离不开require() 和define() 函数。
完整文档在这里loader in the reference guide 。
先举个以旧方式做的例子:dojo.ready(function(){dojo.byId("helloworld").innerHTML = "Hello World!";});下面走进新时代:require(["dojo/dom", "dojo/domReady!"], function(dom){dom.byId("helloworld").innerHTML = "Hello New World!";});欢迎来到美丽新世界。
require() 是新Dojo的基础。
它创建Javascript闭包提供给需要的模块使用,就像通过参数将变量传递给函数一样。
通常,第一个参数是一个模块ID组成的数组,第二个是一个函数。
在require() 的闭包里,我们可以通过在参数从声明的变量来引用这些模块。
在调用模块时,通常会有一些惯例,一般在参考指南中会说明。
加载器——正如旧的那种,会负责查找、加载、和管理模块的所有累活。
你可能会发现有需求数组中有一个名为dojo\/domReady!的模块没有返回变量,它是一种加载器插件,用来控制加载器的行为。
本模块的作用是让加载器等待DOM结构加载完成。
在异步的世界里,操作假设的页面DOM结构可不是个好主意,所以如果你要在代码中对DOM 做点事的话,先确定你包含了这个插件。
因为我们在代码中并不使用这个插件,惯例是把它放在数组的最后,而且不提供它的返回变量。
即便在模块已经加载后,你仍可以使用require() 来引用该模块,用来将模块ID变为一个字符串参数。
你会在Dojo Toolkit里看到这种编码风格,因为我们希望能改在代码中集中管理依赖关系。
该风格编码示例如下:require(["dojo/dom"], function(){// some codevar dom = require("dojo/dom");// some more code});AMD的另外一个核心功能是define(),用来定义模块。
详细教程看Defining Modules 。
Dojo Base和Core你在用新dojo的时候可能听过“baseless”这个术语,就是确保一个模块它需要的基本Dojo 功能之外,不会依赖其它更多的东西。
在遗留问题的世界里,仍然有大量的函数在基础dojo.js里,而且至少在2.0之前依然存在。
不过要是你希望确保你的代码将来如你所愿的易于迁移,就别用dojo.*。
就是说你可能并不了解现在的一部分命名空间。
dojoConfig 有一个选项是async ,它默认为false,就是所有的Dojo 基础模块都会自动加载。
如果你设为true来利用加载器的异步性质,这些模块就不会自动加载。
这些是为了应用更快的响应和加载。
此外,Dojo 拥抱EcmaScript 5规范,并在可能的情况下,为了将ES5 带给旧浏览器使用部分Dojo来模拟ES5和填坑。
就是在一些情况下以Dojo的方式处理问题,但并不直接使用Dojo。
你一旦使用Dojo Base 和Core,一起会像下面这样进行。
dojo.require() 时你这么干:dojo.require("dojo.string");dojo.byId("someNode").innerHTML = dojo.string.trim(" I Like Trim Strings ");用require()则是这样:require(["dojo/dom", "dojo/string", "dojo/domReady!"], function(dom, string){ dom.byId("someNode").innerHTML = string.trim(" I Like Trim Strings ");});Events and Advicedojo.connect() 和dojo.disconnect() 被移入到dojo/_base/connect 模块,新Dojo使用dojo/on 来进行事件处理,dojo/aspect 则针对方法advice。
Events 有更深层次的教程,这里将涉及一些差异。
在旧Dojo中,事件和修正方法行为之间没有明确的区别,都用的dojo.connect() 。
事件是事情发生在于对象之间的关系,例如一个点击事件。
dojo/on 完美处理DOM原生时间以及Dojo对象或小部件引发的事件。
advice 是源于面向方面编程(AOP)的概念外加连接点或方法的行为。
Dojo的很多部分都符合AOP,dojo/aspect 则为此提供了一个集中机制。
在旧Dojo中,我们有多种方式来完成一个点击事件的处理:<script>dojo.require("dijit.form.Button");myOnClick = function(evt){console.log("I was clicked");};dojo.connect(dojo.byId("button3"), "onclick", myOnClick);</script><body><div><button id="button1" type="button" onclick="myOnClick">Button1</button><button id="button2" data-dojo-type="dijit.form.Button" type="button"data-dojo-props="onClick: myOnClick">Button2</button><button id="button3" type="button">Button3</button><button id="button4" data-dojo-type="dijit.form.Button" type="button"><span>Button4</span><script type="dojo/connect" data-dojo-event="onClick">console.log("I was clicked");</script></div></body>在新Dojo中只使用dojo/on, 你可以用编程式或声明式的来编写你的代码,不用管你处理的是DOM事件还是Dijit\/widget :<script>require(["dojo/dom","dojo/on","dojo/parser","dijit/registry","dijit/form/Button","dojo/domReady!"], function(dom, on, parser, registry){var myClick = function(evt){console.log("I was clicked");};parser.parse();on(dom.byId("button1"), "click", myClick);on(registry.byId("button2"), "click", myClick);});</script><body><div><button id="button1" type="button">Button1</button><button id="button2" data-dojo-type="dijit/form/Button" type="button">Button2</button> <button id="button3" data-dojo-type="dijit/form/Button" type="button"><div>Button4</div><script type="dojo/on" data-dojo-event="click">console.log("I was clicked");</script></button></div></body>注意没有用dijit.byId ,在新Dojo中widgets使用dijit/registry ,registry.byId() 用来取得widget的引用。