论坛首页 Web前端技术论坛

使用 Unordered Lists 制作的下拉菜单和树

浏览 22802 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-05-13  
附件是参考文档:Unobtrusive DHTML, and the power of unordered lists
http://www.kryogenix.org/code/browser/aqlists/
制作的下拉菜单和树的例子。

我贴这个例子不是为了仅仅让大家拿去使用,否则就没有必要贴在这个版了。
这个例子的意义是在这里,页面的 structure、presentation 和 behavior 三部分已经分别通过 XHTML、CSS 和 JavaScript 完全分离开了。代码实现了最简化(如果你不知道什么是最简化,我可以把以前我的同事 lyd 完全使用 table 写的一个 tree 的 JS 实现让你看看,还是相当复杂的),也便于各部分的重用。这就是在最新的 Web 标准中这个三位一体神的化身其中每一部分所扮演的角色。

这个例子在充分支持 CSS2 的浏览器例如 Firefox、IE6 中可以正常显示。由于 IE5 不能正确地处理 CSS 的继承,所以显示的有些问题,稍后我会提出一个解决方案。另外还有几个问题大家可以自行解决:
1、下拉菜单应该在鼠标点击菜单以外的其它部位时立即收回。现在没有这种行为。
2、下拉菜单和树都可以进一步加以美化。
3、下拉菜单和树中的内容可以通过从 XMLHTTP 取回的数据加以配置。而不是象现在这样写死在页面中。
   发表时间:2005-05-17  
我再说一下把页面的 structure、presentation 和 behavior 分离开的意义。一般的人很容易理解把 structure 和 presentation 分离的意义,但是对于为什么需要把 presentation 和 behavior 分离开不是很清楚。
这三部分分离开,页面开发才有可能实现真正的重用,从而最终降低开发和维护的工作量。JS 代码是可以做自动测试的,使用 JsUnit 来做。Web 表示层代码测试困难是公认的,直到今天所有介绍 TDD 的经典教材也没有提出一个好方法。所以我问过一些朋友,都是倾向于不对表示层的代码做自动测试。为什么不做自动测试?没有重用价值的代码值得做自动测试吗?而且我们以前有个误区,认为如果做自动测试,表示层的所有东西都需要测试,其实这个想法是错误的。我们需要做自动测试的仅仅是 behavior 这一部分。以前的测试为什么很困难?就是因为 presentation 和 behavior 没有分离开,我们在 JS 代码中直接操作页面的样式(直接设置元素的 style)。我们不应该再这样做下去,我们应该把  presentation 的工作完全交给 CSS 来做。实现 presentation 和 behavior 的分离有两种方法,通过改变元素的 id 或者使用更通用的方法,通过改变元素的 className。而关于这个 id 或者这个 className 具体的样式在外部的 CSS 文件中设置。JS 文件可以生成新的 structure(createElement,etc.),但是不应该直接改变元素的 style。改变了 style,一切效果你都需要用眼睛看到了才算测试成功,这哪里可以做自动测试?而且假如用户对这个 style 不满意,你还需要去修改 JS 代码。你如果只改变元素的 id 或者 className,做自动测试就要容易得多,你只需要测试最终这个元素的 id 或者 className 是否变成了期望的值。而最终的样式是不是也是你期望的,那是 CSS 文件保证的事情,这只需要在第一次开发 CSS 的时候做一下人工测试就足够了。而这样以来,CSS 文件可以由美工来维护,他完全不需要知道 JS 是什么东西。界面程序员可以去做一些更加重要的事情。

所以在这里我们看到,把 presentation 和 behavior 彻底分离开是做 Web 表示层代码自动测试的关键。把这两部分分离开以后,自动测试的难题就迎刃而解了。再强调一下,只有 behavior 有可能做自动测试,presentation 是不需要也不大可能做自动测试的。

相关资料:
http://www.onlinetools.org/articles/unobtrusivejavascript/cssjsseparation.html
0 请登录后投票
   发表时间:2005-05-18  
更合理的分层应该是把客户端表示层分成:显示层,控制层,数据层。(实际上基于XHTML的三层设计在199*年就有人提出来过,当时数据层提法比较模糊)

其中显示层包含HTML/DHTML/XHTML/CSS,就是dlee说的structure、presentation
控制层是由javascript编写的,就是dlee说的behavior
还有一个数据层,是指显示给用户看的业务数据。如果要细分,数据又分为业务数据和操作逻辑数据。这些数据用XML表示,就是数据层。

这三层的关系是:javascript来控制XML数据显示到显示层,或从显示层提取数据组织成XML对象。控制层还用于客户端和服务端的数据通信。

这种客户端分层的好处:把界面组件抽象成显示层,控制层。数据层可以随业务的变化而变化。这就可以使得显示层和控制层代码可以在不同业务上使用。除了业务数据之外的代码都能复用,这也是最高限度的复用了。

缺点:抽象出来的显示层,控制层代码很难满足所有业务数据的需要。比如dlee上传的例子,如果需要在树状结构的节点处加上虚线,显得更直观。重新让第三者修改这些代码就很难了。

难点:如何抽象出通用的,可扩展性的显示层,和控制层很难。现在市面上的几个web组件都没有考虑到所有使用环境。开发者在使用组件开发过程中总会觉得缺少这样或那样的功能。
0 请登录后投票
   发表时间:2005-05-27  
引用
这三部分分离开,页面开发才有可能实现真正的重用,从而最终降低开发和维护的工作量。JS 代码是可以做自动测试的,使用 JsUnit 来做。Web 表示层代码测试困难是公认的,直到今天所有介绍 TDD 的经典教材也没有提出一个好方法。


针对于界面相关的测试,也想谈谈我自己的一些看法.

我们公司在做一个项目,是多媒体自助服务方面的,其中在自助终端上要做很多界面相关的东西,我们并没有采用所谓的Thin Client来做(这和我们当时的技术背景有关),而是采用了标准的C/S架构,不过我看过这个贴子后,觉得有些方面很有同感.

最早的时候,我们做界面程序时,也是将界面和业务逻辑放在一起的,结果在后来就遇到了一个很现实的问题,整个终端的程序没有任何好的办法测试,测试人员在测试某个业务时,只能在界面上按过来按过去来寻找业务方面的问题.说实在的那个时候我们的程序安全没有按照面向对象的方式来设计.

经过一段时间的痛苦之后,觉得这样做不行了,就又重新设计了一个结构出来,在这时,我们基本充分地考虑了测试和扩展的问题,我自己认为现在的程序基本可以完成一些自动测试的要求.我们是这么做的,在界面中不包含任何的业务处理,如果界面需要进行业务处理了,就调用一个业务处理模块的方法就可以了,而业务处理的操作全部封装在业务模块中,这样业务模块的测试可以单独进行,而且可以准备相应的测试用户便于以后进行回归测试.大家可能觉得本来就应当这么做嘛!但是对于我们确定是经历了一个这样的过程.

看到dlee的帖子,我就在想其实如果web展示层如果也能做到这样,可能有很多问题也就不是问题了(如测试,重用什么的).我对JavaScript等也是刚开始关注,但是我觉得如果JavaScript也是面向对象,那它提供的操作也一定是预先就写好的,如果能将字作为一个对象去测试的话,那就再好也不过了.这可能就是dlee提出的structure、presentation 和 behavior进行分离的意义吧,请dlee指教.
0 请登录后投票
   发表时间:2005-05-27  
我会试一下 写道
看到dlee的帖子,我就在想其实如果web展示层如果也能做到这样,可能有很多问题也就不是问题了(如测试,重用什么的).我对JavaScript等也是刚开始关注,但是我觉得如果JavaScript也是面向对象,那它提供的操作也一定是预先就写好的,如果能将字作为一个对象去测试的话,那就再好也不过了.这可能就是dlee提出的structure、presentation 和 behavior进行分离的意义吧,请dlee指教.

指教谈不上。其实有些问题我也在思考中,还不是非常成熟。
我为什么会想起这个自动测试的问题呢,就是因为 AJAX 的出现。这种开发方式的表示层完全使用 JS 来做开发,为了提高开发效率,一定要想办法实现大量表示层的组件。而由于目前各种 JS 调试器(M$ Visual InterDev、Mozilla Venkman、etc.)还不能达到 Java 调试器那样的方便和强大(例如:支持在线修改、支持重构等等),调试这些组件需要花费大量的时间。如果能够想办法提高这些组件的可测性,最终甚至采用 TDD 的方式来开发这些组件,那么就可以大幅提高开发效率。现在其实已经有 JsUnit 这样的工具可以实现对 JS 代码的自动测试,但是由于 JS 代码中大量混杂了直接设置样式的内容(style.xxx = ),这部分代码显然是不可能做自动测试的。我在阅读了上面的文章后,发现自己已经找到了一种比较理想的解决方案。
另外,还要再说一下,现在的 Web 开发者,很多人都是通过各种 Web 设计教材或者某种 WYSIWYG 工具(例如 Dreamweaver)的使用指南来学习制作 Web 页面的,因此对于各种 Web 标准的理解往往是非常肤浅的。其实把 structure、presentation 和 behavior 相分离就是 W3C 设计 XHTML、CSS、DOM 这 3 个标准的原意,因此我需要正本清源地在这里再讲一下。

其实现在为了完全达到我的目的,我建议直接使用 UltraEdit/EditPlus 这样简单的工具来制作 Web 页面,而不要依赖 WYSIWSG 的工具,因为我发现只有使用 UltraEdit/EditPlus 制作的页面最后才能达到我所要求的最简化。这仅仅是我的一个建议,大家可以参考。很多熟悉 Dreamweaver 的人可能立即会反对我的说法。一个振振有词的理由就是开发效率和成本。绝大部分的人都本能地以为制作页面是一件很低级的工作,因此容忍页面编码质量的粗制滥造,认为只要能达到漂亮的显示效果就足够了。

关于开发效率和成本,你们不能这样狭隘地理解。页面的开发成本不仅仅包括其初次制作的成本,还包括了以后修改的成本。低劣的编码导致页面以后修改困难,必须完全重新制作,还需要重新编写 JS 的成本也是非常高的。

你们可能总是以为我就是一个迂腐的空谈家,喜欢象唐僧一样唠唠叨叨。我来现身说法证明这样做是可行的。我以前所在的公司,我们所有的页面全部都是手工编写的(这是我们公司强制要求的,因为我们公司都是由程序员来制作页面的,程序员掌握起来 HTML 并不是非常困难的事情)。我们并没有感到开发效率非常低下(其实,结构非常复杂的页面还是极少的,很多时候其实是不必要的,在采用了 CSS 以后都可以得到简化。而且随着熟悉程度的加深,页面模版的增加,开发效率会越来越高)。而且由于我们在项目的页面开发初期就有意识地大量采用 CSS,当一次客户对于我们的页面样式风格提出了大的修改意见后,我们在很短的时间内(3、4 天),仅仅用两个程序员,完成了将近 1000 个页面的美化和样式修改。实际上当时我们还没有彻底地使用 CSS 做布局(仍然是完全使用 table 做布局),如果那样做,修改起来的工作量还会小的多。

现在有些专业做页面制作外包的公司,开发效率非常高,他们声称可以同时为你提供 100 套页面模版。这似乎很神奇,他们为什么能在这么短的时间内做到这一点?并且把成本降低到非常低的水平?其实就是大量采用了我现在介绍的一些技术。这 100 套页面模版,其实就是 100 套 CSS 嘛!

当然,如果有 Dreamweaver 高手使用 Dreamweaver 制作页面,能够达到我对于页面的一些基本的制作要求,我也并不反对使用 Dreamweaver。Dreamweaver MX 是目前所有这类工具中对于 Web 标准支持的最好的。建议如果必须使用 WYSIWYG 工具时大家都使用 Dreamweaver MX,而不要使用 FrontPage。FrontPage 对于 Web 标准的支持是很差的,做出来的页面很多时候只能使用  IE 才能访问。
0 请登录后投票
   发表时间:2005-05-30  
我看到另外一家做多媒体应用系统的公司,他们的方案是采用IE扩展来做界面的,其实就相当于自己做了一个容器,可以方便地完成规定格式的界面定制,而且界面和业务处理是完全分离的,开发效率很高.这段时间我一直在考虑这个问题,这样做是否也是一个方向,确实比我们现在的开发方式要好很多,虽然只是在多媒体自助服务这方面适用,但如果每个不同应用对容器做些不同的修改,使之真正能为业务服务(而且是很好的服务)不也挺好的吗?!
0 请登录后投票
   发表时间:2005-06-28  
这种将树操作的生成逻辑推至JS中来处理,for循环中嵌套for循环switch判断。

如果节点数据量极大,那么性能问题岂不是非常严重?
0 请登录后投票
   发表时间:2006-09-29  
   不知道写的怎么样,先看一下!对共享表示支持!
0 请登录后投票
   发表时间:2006-09-30  
dell你要是在北京就好了,我想请你来我公司替我项目组培训一下
0 请登录后投票
   发表时间:2007-07-11  
structure、presentation 和 behavior 分离是很好的设计,也应该是将来发展的方向,但是这种设计实现起来会有相当的难度。在目前这种浏览器各自为政的情况下,不同浏览器对同一样式的解释、显示出来的效果都是有很大差异的。而且,有时CSS无法完全实现HTML所能实现的布局等。
例如,经常会有类似下面这样的问题出现:
<style>
.tree
{
    width: 200px;
    height: 200px;
    overflow: auto;
}
.node
{
    clear: left;
}
.node div
{
    float: left;
    padding: 0px 1px;
}
.node img
{
    float: left;
    border-width: 0px;
}
.node span
{
    display: block;
    margin-left: 2px;
    white-space: nowrap;
}
</style>
<div class="tree">
    <div class="node">
        <img src="src\tree\themes\default\blank.gif"></img>
        <span>Root</span>
    </div>
    <div class="node">
        <img src="src\tree\themes\default\blank.gif"></img>
        <span>Root</span>
    </div>
    <div class="node">
        <img src="src\tree\themes\default\blank.gif"></img>
        <span>长字符串测试 测试长字符串  测试长字符串  长字符串 长字符串</span>
    </div>
</div>

上面这段代码在IE和FireFox中显示出来的效果是完全不同的。IE中,最后一个span的文本被折到了下一行,而FireFox则将文本显示在一行中。因此,为了实现文本显示在一样的效果,对于IE,不得不使用table来进行布局,而不是DIV+CSS。而这样,也就无法实现structure、presentation 和 behavior三部分分离。类似这种问题会让人非常头疼,也非常影响表示层的设计,因为我们不得不为不同的浏览器定制不同的代码。
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics