我们首先应该做什么呢?似乎应该是开发在路线中添加新的一天的功能。为了做这件事,我们需要建造新的一天所需的HTML,包括它的标题、一个空的集合(因为还没有为它添加站点)等等。
我们能够使用DOM来建造这些,但是如果我们能够只做一个拷贝,这将变得更加容易。为了做这件事,我们可以在HTML中加入一个空的表格,但是不显示它。
这是一组包含列表的div,模板代码的作用是作为一个占位符(例如EMPTY DAY,而不是天号的标题,以及特殊的id,用来在程序中获取):
1 处理DOM
为了创建新的一天,我们需要为上面那段HTML制作一个拷贝,并且将它放置在文档中的正确位置。
为了完成这个工作,我们可以使用一些Dojo的辅助方法:
• dojo.byId:我确信你输入document.getElementById()的次数比你参加宴会的次数还要多。这个简单的辅助方法不仅使你少输入一些字符,而且使你既可以传入一个文本id,也可以传入一个节点本身。这是一种实用主义的做法,它意味着你可以忘记你拥有的实际上是什么,它照样可以工作。有些读者可能会想到这看起来有点像Prototype中的函数$(id),的确如此。为何Dojo没有决定使用一个更短的名称,例如$呢?因为他们并不想污染名字空间。$用起来很棒,但是如果别人也定义了$,并且定义略有不同,那么会怎样?这样就会有问题了。$()函数有另外一个很好的特征,它可以接受多个id/节点,并且返回它们。你可以在Dojo中使用dojo.byIdArray()来做相同的事情。将“dojo.”放在大多数调用之前的原因是Dojo通过package的语义来保证我们不会遇到这种类型的冲突。
• dojo.dom.insertBefore(newElement, elementBefore); dojo.dom拥有大量的dom辅助方法,可以帮助你更好地处理DOM(DOM处理在Ajax开发中不是一件痛苦的事情吗?)我们使用这个功能来将新的一天放置在上一天(unused-sites)之前。
AddDay()方法完整的代码如下所示。这里有一点冗余,因为它必须要重置新的天号的id,增加总共的天数,等等:
function addDay() {
var lastDay = dojo.byId(“unused-sites”);
var emptyDayTemplate = dojo.byId(“empty-new-day”);
numberOfDays++; // we have one more day now
var newDay = emptyDayTemplate.cloneNode(true);
newDay.id = “fullday-” + numberOfDays;
// set the title
newDay.childNodes[1].childNodes[1].nodeValue = "day " + numberOfDays;
// set the new ol id
var ol = newDay.childNodes[3];
ol.id = “day-” + numberOfDays;
// set the new empty li id
var li = ol.childNodes[1];
li.id = “empty-day-” + numberOfDays;
setupDayForDND(newDay); // drag and drop explained later
dojo.dom.insertBefore(newDay, lastDay);
dojo.fx.wipeIn(newDay, 500); // effect below
}
你可以看到大量标准的DOM方法,例如node.cloneNode(true),正是这个调用拷贝了空的一天的模板,然后我们更新其中的字段。我们传递true标志告诉DOM需要拷贝节点中的节点,进行深度遍历。
还有哪些其他的dojo.dom辅助方法?
你也许能够从名称上判断出这些跨浏览器的辅助方法是做什么的:
• dojo.dom.isNode
• dojo.dom.getTagName
• dojo.dom.firstElement
• dojo.dom.lastElement
• dojo.dom.nextElement
• dojo.dom.prevElement
• dojo.dom.moveChildren (srcNode, destNode, trim)
• dojo.dom.copyChildren (srcNode, destNode, trim)
• dojo.dom.removeChildren(node)
• dojo.dom.replaceChildren(node, newChild)
• dojo.dom.removeNode(node)
• dojo.dom.getAncestors
• dojo.dom.getAncestorsByTag
• dojo.dom.innerXML
• dojo.dom.createDocumentFromText
• dojo.dom.prependChild
• dojo.dom.insertAfter
• dojo.dom.insertAtPosition
• dojo.dom.textContent: 实现了DOM Level 3的属性
2 Dojo的HTML效果
我们使用dojo.dom来加入新的一天,但是仅仅这样做还不够好。我们并不想使用户的视线移动,我们想在文档改变的地方,同时显示这个变化。
Script.aculo.us因为它的killer级的效果库而广为人知,但是很多人并不知道Dojo也有自己的效果库。
我们选择使用dojo.lfx.wipeIn()来处理这个节点,使得产生的效果好象是将百叶窗关上。
然而我们不必将它擦去。也许你更加喜欢一种淡入/淡出/隐藏的渐变效果、一种幻灯片播放的效果、一种颜色渐变/高亮的效果、或者一种向外/向内的爆炸效果?Dojo支持所有这些效果,并且它们都使用一行代码即可完成,并且还支持为效果添加回调函数的能力。
这些效果可能看起来不过是像口红一样的点缀,无关大局,但是它们为你的应用增添了光泽,使得你的用户发出“喔”的一声赞叹,并且它们对于改善应用的可用性也大有帮助。
尽管如此,还要记住一个警告,就是你不要想将页面上的所有操作方式都推翻。如果我们这样做,人们会认为我们是Flash开发者。