找到一点可怜的关于dojo资料,谢谢作者!


Posted in Javascript onDecember 06, 2006

介绍:
这里将给你对于dojo的启蒙课程。你可能会跟自己说"这段可以跳过了,因为我已经很了解javascript并且对网站开发很了解了。“不过这里有个机会让你认识到其实你的知识并不是那么扎实,还有很多基础的东西需要学习。

当 我们给人们介绍dojo的时候,遇到了两种难题。有些用户已经使用DHTML很久,并且对javascript有了很深的理解,他们清楚 javascript能作什么,不能做什么,在脑海里存在定型思维,有些时候,更难让这些人明白dojo。第二种难题就是对于那些新手,他们太缺乏经验和 对javascript的了解了。

我鼓励这两种朋友都读一下介绍内容,甚至你可以不全看。

什么是Dojo?

其实总结Dojo到底是什么是非常困难的。我说总结Dojo是很困难的,是因为Dojo是一个可扩展的代码集合 (expandable collection of code)。扩展不只是来自于众多开发者,并且你会发现你可以根据你自己的需要扩展自己的一套东西。就是说,你把目光放在Dojo身上的原因是因为 Dojo可以和javascript取长补短。

在开发客户端(client-side development)总共有3个主要部分:events,重复使用DHTML blocks,客户端和服务器传递信息。Dojo在这三方面都很在行,并且使他们变的很容易。

历史

译者注:历史我是真不想翻译了,如果有人很感兴趣的话,可以给我留言,我有时间会翻译的。

。。。。。。。。。。。。

什么是工具(Toolkit)?

很多人认为结构(framework),库(library),工具是同一个意思。但是弄清楚它们之间的区别,对于以后的理解很有帮助。

Framework

在软件开发中,为了让其他的项目可以分享和合作,通常定义一个结构(framework)。一个结构通常包含支持程序(support programs),库和一个脚本程序。你可能认识到Dojo就是framework的一个部分,但并不是framework的本身。

Library

库文件定义了很多可以引用的方法(function),它们是在任何位置都可以运行的,并不是我们平常自己在程序中定义的方法。看了这些,你可能会说“嘿!dojo就是库的集合!”。你应该是对的,但是,dojo比一个库的集合要包含得多很多。

Toolkit

看 过前文,你可能还在琢磨到底dojo是作什么的。很明显,他不是一个结构(framework),它是一个工具(toolkit)或者是一个库?最后让我 来解答一下,通常库都是之前定义好的,你可以引用到你的程序中并使用它们,但是在dojo中,我们在这个库外面加了一层封包系统。这样就使它跟一般的库有 些不一样。

在这个系统中,我们把库分成很多部分。有核心方法(core functions),还有很多其他不常用的子库(sub library)。这就使你使用dojo的时候感觉它很简洁。下面会有更具体的分析,会让你更加明白dojo。

Dojo会给你什么

曾经,Netscape盛行一时,大部分人都在使用,所以当时Netscape给出了一个网站制作的标准。好景不长,后来出现了微软的IE,IE当时强过Netscape,成为了新的标准。但是这个标准跟W3C有一定的差别,所以在人们制作网站时,开始向IE新标准靠拢。

很多年过去了,IE依旧不败,而且并没有更新很多。一样多的bug,缺少标准化。慢慢的网虫们开始使用firefox,opera,safari,它们为了跟上W3C的标准,所以更新得很快。

很多同样的功能,但是对于不同的浏览器需要写不同的代码,这对我们来说意味着什么?意味着我们要做出一个完美的网站是很苦难的。这时一个程序员会去做什么呢?

知识补充

如果光使用静态html制作网站,当然不会出现上面的问题,但是这也意味这网站不可能具有交互性,最多的也只是提供一个表单(form)让用户提交,然后再返回一个新的页面显示数据。

Javascript的出现正是为了解决这些难题。

解决所有问题

Dojo不仅是存在于抽象层,并且也是独立存在的。不只是提供一些库,一些方法,一些功能,而且让的代码更加简洁,保证你的代码只包含所需要的部分。

Dojo会让你的生活更加简单,因为他替你链接了很多东西,把你的复杂项目分成一些小问题,让你的代码更简洁,更有效率,并且可以更好的重复使用。

第一章:开始使用Dojo

Dojo有很多版本,你可以一下子不知道该选择哪个,这里可以让你放心,无论你使用的是什么版本,本书中的例子你都可以运行。

下载Dojo

(译者注:这个是我使用的版本,zip文件,你也可以自己到Dojoa主页进行下载。)

Dojo模块(Modules)

Dojo的库定义使用了模块,就像JAVA一样。这样可以让你只引用自己需要的部分,而不是全部,保证了浏览速度。

例如Dojo的event包定义在模块dojo.event中。

(译者注:此部分原著甚是??拢?腋??蛄艘幌拢?行巳さ呐笥芽梢圆渭??摹#

引用模块格式:

dojo.require("dojo.module[.sub module]");

例如我们想引用lite effects systems,

dojo.require("dojo.lfx");

这会引入所有lfx下的子模块,当然你也可以使用dojo.lfx.*,如果想单独引用lfx下的toggle模块:

dojo.require("dojo.lfx.toggle");

Widgets

什么是widget呢?一个按钮 ,一个图片,这都是widget,最常见的html widget有链接,按钮,输入框。

使用Dojo可以改变widget ,例如在日期输入框旁边加上一个彩色日历,让用户可以选择日期,与此同时Dojo并不会破坏你原始的输入框,因为Dojo是扩展了你的html而不是替换了它。

使用widget的优势主要三点:
跨平台:使用Dojo widget,无论使用任何浏览器,都会准确的得到正确效果。
自动退化:一些老浏览器可能对javascript支持并不是那么完美,Dojo也可以让它们显示出正确的内容,例如前面彩色日历的例子,如果浏览器不支持,那么Dojo会自动将日历退化到一个简单的选择框,或者其他(根据不同widget而定)。
扩展性:你可以利用Dojo提供的widget创造出新的widget,在这个过程中你并不需要从库中复制任何代码或者修改库中的代码。

如何使用Widget

Widget有很多使用方法。Widget会搜索整个网页框架,然后自动把应该添加的内容加入到当中。

下面是个简单的例子,我们也可以看出WIdget是怎样自动退化的,因为我们并没有给ComboBox定义选择项,而只是一个value,而且所以最后显示出来的只象是一个简单的inputbox,如果用户禁用了javascript,显示结果也会一样。

<input dojoType="ComboBox" value="default" dataUrl="comboBoxData.js">

但是如果我们只想使用W3C标准(译者注:没有那些额外的tag,例如dojoType),我们可以用下面的方法。

<input class="dojo-ComboBox?" value="default" dataUrl="comboBoxData.js">

<dojo:ComboBox? value="default" dataUrl="comboBoxData.js">

你可能注意到了dataUrl,他的作用是把comboBoxData.js中的内容加到comboBox中,但是现在comboBoxData.js中没用任何内容。(译者注:当然你可以随意改变dataUrl的内容,名字不是固定的。)

下面是一个select的例子:

<select dojoType="combobox">
<option value="foo">foo</option>
<option value="bar">bar</option>
<option value="baz">baz</option>
<option value="thud">thud</option>
</select>

从上面的例子中,你知道了很多事情,但却好像没什么用处,这里只是想告诉你其实dojo并没有那么复杂。

后退和前进

动态网页程序(dynamic web application)避免了频繁的刷新页面,不过通常也带来后退和前进按钮会失去作用。更多的,有的时候,用户可能很难把网页加入收藏夹。

Dojo提供了一个解决办法,让网页程序处理浏览器的后退和前进,并且提供给浏览器一个唯一的地址。这个解决办法就是使用dojo.undo.browser。

使用dojo.undo.browser

在dojo 0.2.2版本中,并没有dojo.undo.browser,这是在0.3以后的版本中才加入的。

首先,需要使用dojo.undo.browser.setInitialStae(state)设定当浏览器第一次载入网页的状态。

理论

动 态网页程序会调用XMLHTTPRequest和DOM来更新网页内容而避免了刷新,更新浏览历史,并且也不会改变浏览器的地址栏。这就意味着当用户点击 了后退按钮,整个网页程序丢失了当前运行的状态(state)。而且即使用户想把当前的网页内容加入收藏夹,也是不可能的,因为收藏夹不会记录网页程序运 行的状态,而只会简单的记录下网页程序的地址(URL)。

开发者可以使用dojo.undo.browser包得到用户点击后退和前进的事件(event),然后根据这些事件来更新页面内容。 dojo.undo.browser通过使用一个隐藏的表单(hidden IFRAME)或者一个唯一的标签(fragment identifier)传递浏览的历史记录。(译者注:可以想像成一个cookie或者一个session,但是这个session信息是存储在hidden IFRAME或者标签中) 例如:

http://some.domain.com/my/path/to/page.html#fragmentIdentifier

(译者注:#fragmentIdentifier就是标签记录)

因为当改变标签的时候并不会使网页刷新,所以非常适合记录当前网页程序的状态。当然开发者可以自定义一个更容易读懂的标签,并且使用户可以把它加入收藏夹。

dojo.undo.browser允许开发者创建一个相对于运行状态的对象(state object),这个对象会得到回叫(callback)当用户点击后退或者前进按钮。

开发

下面是使用dojo.undo.browser之前必须作的一些事情:

1:在djConfig中设置preventBackButtonFix: false。这样保证了隐藏的表单(hidden IFRAME)将会添加到页面当中,如果不加入这段,dojo.undo.browser不会正常工作。

译者注:设置方法就是在header中加入如下代码:

<script language="JavaScript" type="text/javascript">
djConfig = { isDebug: true, preventBackButtonFix: false };
</script>

2: 加入dojo.require("dojo.undo.browser");

设定网页程序的初始状态:

dojo.undo.browser.setInitialState(state);

当用户每次点击前进或者后退,state对象都会被调用。

然后我们需要给state对象创建几个方法(function)
得到后退提示:back(),backButtion()或者handle(type),type可以是“back”或者是“forward”。
得到前进提示:forward(),forwardButton()或者handle(type),type如上。

下面是个简单的例子:

var state = {
back: function() { alert("Back was clicked!"); },
forward: function() { alert("Forward was clicked!"); }
};

注册一个state对象使用下面的方法:

dojo.undo.browser.addToHistory(state);

如 果向改变浏览器的地址(URL),引用state对象的changeUrl属性。如果changeUrl是true,dojo.undo.browser 就将产生一个唯一的标签,如果changeUrl被定义为任何其他的值(不包括undefined,null,0和空string),那么这个值就会被使 用为标签。这样用户就可以把当前页加入收藏夹了。

提示
如果你要使用changeUrl,即使你不设定自己的标签,也至少定义为true。
如果你要在本机测试,不要使用IE。因为当IE访问本地文件时不会创建历史列表ifram_history.html。请把网页上传到服务器上测试。
Safari2.0.3+:只有后退按钮可以正常工作,并且只有当changeUrl没用使用的时候。
Opera 8.5.3:不会正常运行。

这里有一个网上的例子:

http://archive.dojotoolkit.org/nightly/tests/undo/test_browser.html

发布Dojo

译者注:此部分的英文版还没有完成,所以暂不翻译了,以后一定会补上。

6月27日更新:

I/O

dojo.io.blind介绍

在我们制作dojo的时候,目的是让用户和开发者都能享受到DHTML程序。在很多朋友的支持下,特别是Aaron Boodman和Mark Anderson,我们已经找到了解决可用性的方法。我们提供了一个单独的易用的API和一个包装类,这个类只需要两个文件。dojo.io包提供了对XMLHTTP和一些其他更复杂的传输结构的支持。

在dojo.io 包中我们一般最常使用的是dojo.io.bind()方法。dojo.io.blind()是一个标准的异步的请求API,它包含了各种传输层 (transport layers),包括queues of iFrames,XMLHTTP,mod_pubsub,LivePage等等。Dojo会试图为当前的请求选择最合适的传输方法,因为在做网站时一般不 会使用到其他传输,所以我们只用到XMLHTTP。dojo接受一个匿名的类,但是在知道这个类的属性的情况下,把它作为方法参数(function argument)。下面的代码是创建一个请求(request),这个请求会从URL返回原始的字符串。
dojo.io.bind({
    url:  " http://foo.bar.com/sampleData.txt " ,
    load:  function (type, data, evt){  /* do something w/ the data  */  },
    mimetype:  " text/plain "
});

这就是全部,你提供了一个数据地址,还有一个当你得到返回值时要执行的function。但是如果在请求过程中出错了怎么办呢?我们再来创建一个register来解决:

dojo.io.bind({
    url: "http://foo.bar.com/sampleData.txt",
    load: function(type, data, evt){ /*do something w/ the data */ },
    error: function(type, error){ /*do something w/ the error*/ },
    mimetype: "text/plain"
});

同样也可以只创建一个单独的handler来解决:
dojo.io.bind({
    url: "http://foo.bar.com/sampleData.txt",
    handle: function(type, data, evt){
        if(type == "load"){
            // do something with the data object
        }else if(type == "error"){
            // here, "data" is our error object
            // respond to the error here
        }else{
            // other types of events might get passed, handle them here
        }
    },
    mimetype: "text/plain"
});

下面的代码提交一段javascript程序段,然后让服务器运行它,一般我们这么做是为了加速程序运行,注意mimetype:
dojo.io.bind({
    url: "http://foo.bar.com/sampleData.js",
    load: function(type, evaldObj){ /* do something */ },
    mimetype: "text/javascript"
});

如果你想确保程序使用XMLHTTP,可以这样写:
dojo.io.bind({
    url: "http://foo.bar.com/sampleData.js",
    load: function(type, evaldObj){ /* do something */ },
    mimetype: "text/plain", // get plain text, don't eval()
    transport: "XMLHTTPTransport"
});
Being a jack-of-all-trades, bind() also supports the submission of forms via a request (with the single caveat that it won't do file upload over XMLHTTP):
作为一个jack-of-all-trades(万事通),bind()同样支持来自于表单提交的数据。
dojo.io.bind({
    url: "http://foo.bar.com/processForm.cgi",
    load: function(type, evaldObj){ /* do something */ },
    formNode: document.getElementById("formToSubmit")
});
以上只是一些最基本的,其实这些可以不用全部由开发者自定义。

RPC
你可以看到,Dojo通过dojo.io.bind提供了简单,强大的方法使用多种多样的I/O functions。但是在开发过程中,程序员会调用很多很多I/O,这同时会给服务器和客户端加重负担。Dojo的RPC服务就是为了减少负担,易用,精简代码而生的。

RPC 的全名是Remote Procedre Calls,或者Remote Method Invocation,(译者:远程method调用)。最基本的,RPC允许开发者调用在远程服务器上的方法(method)。Dojo不仅提供了基本 的RPC client包,而且还扩展了它,使它支持JSON-RPC服务和YAHOO服务。同时你也可以自己写出相对于其他服务的类。

我们假定有一个需要调用服务器端程序的小程序,假设要调用add(x,y)和subtract(x,y)。在没有特殊情况的条件下,我们的客户端会这样写:
add = function(x,y) {

    request = {x: x, y: y};

    dojo.io.bind({
            url: "add.php",
            load: onAddResults,
            mimetype: "text/plain",
        content: request
    });
}

subtract = function(x,y) {

    request = {x: x, y: y};

    dojo.io.bind({
            url: "subract",
            load: onSubtractResults,
            mimetype: "text/plain"
        content: request
    });
}

你 看,这不是很难。但是无论是我们让服务器运行add和subtract还是让客户端自己计算,这只是一个非常简单的程序。如果我们要调用在服务器上30个 不同method会怎么样呢?我猜我们可能要重复的写几乎一样的代码一遍又一遍,每次都要创建一个请求类(request object),设定URL,设定变量等等。这不仅容易出错,而且还很枯燥。
Dojo的RPC客户端简化了这个过程:
{
    "serviceType": "JSON-RPC",
    "serviceURL": "rpcProcessor.php",
    "methods":[
        {
            "name": "add",
            "parameters":[
                {"name": "x"},
                {"name": "y"}   
            ]
        },
        {
            "name": "subtract",
            "parameters":[
                {"name": "x"},
                {"name": "y"}   
            ]
        }

    ]
}

以上就是对于服务器的定义。一旦定义创建完毕,其他的事情就简单了,我们还可以创建一个类:
var myObject = new dojo.rpc.JsonService?(defintion);
要使用服务器的方法:
myObject.add(3,5);

我 敢打赌你会在想“我不是只调用方法就够了,我还有得到计算的结果。”你是对的,但这也是非常容易的。服务器端的myObject.add()会返回一个延 缓类(deferred object)。Twisted Python用户可能对延缓类(deferred object)很熟悉,延缓类(deferred object)允许开发者根据返回数据的类型附加一个或更多的回叫(callbacks)和错误处理(errbacks)。这里有一个简单的例子:
var myDeferred = myObject.add(3,5);
myDeferred.addCallback(myCallbackMethod);

我 们把mycallbackmethod作为回叫添加到我们的延缓类mydeferred。这时,8会被传递进mycallbackmethod。另一方 面,我们也可以添加一个errback method来处理服务器返回的出错信息。我们随意添加回叫方法(callback),多少都可以,它们会按照我们定义的顺序被调用。

以上的例子都是围绕dojo.rpc.JsonService展开的。我们还可以使用dojo.rpc.YahooService,规范和结构都是一样的。这两个类都是继承了dojo.rpc.RpcService。要创建自己的类会在第二章中详细介绍。

转载自http://www.blogjava.net/burnet

原文地址 http://www.blogjava.net/burnet/articles/54186.html

Javascript 相关文章推荐
Javascript客户端脚本的设计和应用
Aug 21 Javascript
List the Codec Files on a Computer
Jun 18 Javascript
javascript cookie操作类的实现代码小结附使用方法
Jun 02 Javascript
jquery 回车事件实现代码
Aug 23 Javascript
js 删除数组的几种方法小结
Feb 21 Javascript
js实现按一下删除键删除整个单词附demo
Sep 05 Javascript
Javascript仿新浪游戏频道鼠标悬停显示子菜单效果
Aug 21 Javascript
jquery分页插件jquery.pagination.js实现无刷新分页
Apr 01 Javascript
基于javascript实现精确到毫秒的倒计时限时抢购
Apr 17 Javascript
Node.js引入UIBootstrap的方法示例
May 11 Javascript
JS对日期操作封装代码实例
Nov 08 Javascript
15个值得收藏的JavaScript函数
Sep 15 Javascript
jQuery的一些注意
Dec 06 #Javascript
基于prototype的validation.js发布2.3.4新版本,让你彻底脱离表单验证的烦恼
Dec 06 #Javascript
鼠标移动到一张图片时变为另一张图片
Dec 05 #Javascript
JS日历 推荐
Dec 03 #Javascript
Js的MessageBox
Dec 03 #Javascript
硬盘浏览程序,保存成网页格式便可使用
Dec 03 #Javascript
常用js脚本
Dec 03 #Javascript
You might like
PHP利用超级全局变量$_POST来接收表单数据的实例
2016/11/05 PHP
php数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
Laravel 5.2 文档 数据库 ―― 起步介绍
2019/10/21 PHP
表单(FORM)的一些实用效果代码
2007/03/25 Javascript
script标签的 charset 属性使用说明
2010/12/04 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
前端微信支付js代码
2016/07/25 Javascript
javascript代码调试之console.log 用法图文详解
2016/09/30 Javascript
JS中作用域和变量提升(hoisting)的深入理解
2016/10/31 Javascript
微信小程序中input标签详解及简单实例
2017/05/18 Javascript
react-native 封装选择弹出框示例(试用ios&amp;android)
2017/07/11 Javascript
详解vue项目中如何引入全局sass/less变量、function、mixin
2018/06/02 Javascript
js实现各浏览器全屏代码实例
2018/07/03 Javascript
vue中子组件的methods中获取到props中的值方法
2018/08/27 Javascript
vue权限管理系统的实现代码
2019/01/17 Javascript
jQuery 筛选器简单操作示例
2019/10/02 jQuery
axios解决高并发的方法:axios.all()与axios.spread()的操作
2020/11/09 Javascript
Python入门篇之正则表达式
2014/10/20 Python
Python中特殊函数集锦
2015/07/27 Python
Python存取XML的常见方法实例分析
2017/03/21 Python
异步任务队列Celery在Django中的使用方法
2018/06/07 Python
python获取代码运行时间的实例代码
2018/06/11 Python
python将txt文件读入为np.array的方法
2018/10/30 Python
将python字符串转化成长表达式的函数eval实例
2020/05/11 Python
Python用来做Web开发的优势有哪些
2020/08/05 Python
Selenium Webdriver元素定位的八种常用方式(小结)
2021/01/13 Python
CSS3中box-shadow的用法介绍
2015/07/15 HTML / CSS
Big Green Smile德国网上商店:提供各种天然产品
2018/05/23 全球购物
澳大利亚二手奢侈品网站:Modsie
2019/09/23 全球购物
Java基础面试题
2012/11/02 面试题
工厂总经理岗位职责
2014/02/07 职场文书
入党积极分子评语
2014/05/04 职场文书
详细的本科生职业生涯规划范文
2014/09/16 职场文书
房屋出租委托书格式
2014/09/23 职场文书
2014年图书室工作总结
2014/12/09 职场文书
创业计划书之家政服务
2019/09/18 职场文书