TaobaoUED博客笔记(2)

很多现代的浏览器在地址栏的右边有个搜索框,默认的安装有 Google 搜索等。

其实这是 OpenSearch 的一个应用,只要编写相应的微格式的 xml 文件,就可以制定相应的搜索框。参考 OpenSearch 的定义文档,可以基本获得基本的 xml 格式。比如某个典型的的搜索 xml 文件可以这样指定。

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
    <InputEncoding>utf-8</InputEncoding>
    <ShortName>ShortName</ShortName>
    <Description>Description</Description>
    <Image type="image/vnd.microsoft.icon">favicon</Image>
    <Url type="text/html" template="http://who.am.i/search?word={searchTerms}"/>
  </OpenSearchDescription>

上面的 xml 文件很容易理解,除了固定的 xml 根以外,其他的定义从字面上就可以理解:

  • InputEncoding 指定搜索的编码,根据网站的实际情况而定
  • ShortName 这个是搜索的短名称,比如“Google 搜索”
  • Description 针对这个搜索框的描述,比如“淘宝购物搜索 – 只有你想不到,没有你淘不到”
  • Image 类似网页的 favicon ,用于标识搜索
  • Url 这个是最重要的参数,指定搜索的链接。它有很多参数,一般使用 {searchTerms} 参数指定搜索词即可。参数 type=”text/html” 注明返回的是页面(浏览器会跳转到这个页面),如果是其他格式就会使用相应默认程序打开(比如 type=”application/rss+xml” 就会使用 RSS 阅读器打开)。

编写 OpenSearch 的 xml 格式就完成了,详细信息可以参阅其 OpenSearch 定义文档。下面要在页面中加入这个搜索,基本上可以分为两种方式。分别是页面的在 head 中加入 link 标记(类似 RSS),以及使用 Javascript 方式添加(比如定义某个按钮触发)。加入 link 标记非常简单,格式如下

<link rel="search" type="application/opensearchdescription+xml"
            href="http://who.am.i/search.xml" title="ShortName" />

与 RSS 相似,rel 和 type 是固定的,我们主要指定 href (上述 xml 的 url 路径,保险起见使用绝对路径,即 http:// 开头)以及 title (也就是搜索的短标题)即可。就这样,在 Explorer 以及 Firefox 中打开这个页面就可以看见相应的菜单了

使用 Javascript 添加比较麻烦(或许现在的情况会很好多)。我们主要会使用浏览器的扩展功能,在 Explorer 有个 window.external.AddSearchProvider 参数(详细文档)。典型的调用方法如下

window.external.AddSearchProvider('http://who.am.i/search.xml');

参数中的链接就是上述 link 中的内容。在 Firefox 下可以使用

window.sidebar.addSearchEngine(
    "http://who.am.i/search.xml", /* engine URL */
    "favicon.ico",  /* icon URL */
    "ShortName", /* engine name */
    "Description" ); /* category name */

参数和例子如示例代码中所述(官方文档)。值得注意的是在 Firefox2 版本以后已经“兼容” Explorer 的 window.external.AddSearchProvider 调用方法(详细信息)。那么我们对应的 Javascript 代码就可以这样编写(为了兼容 Firefox2 之前的版本,加入 else if 判断,如果觉得没有必要,可以不加)

function addEngine(){
    if (window.external || window.external.AddSearchProvider) {
        window.external.AddSearchProvider('http://who.am.i/search.xml');
    } else if (window.sidebar && window.sidebar.addSearchEngine) {
                window.sidebar.addSearchEngine(
                    "http://who.am.i/search.xml",
                    "favicon.ico",  /* icon URL */
                    "ShortName", /* engine name */
                    "Description" ); /* category name */
    }}

这样,就可以将这个函数注册到某个链接或者按钮的点击事件中,就会跳出个确认框,如图用户点击确认以后,就加入到浏览器搜索框中了。

原文地址:http://ued.taobao.org/blog/2008/06/opensearch-%E5%88%9D%E6%8E%A2/

前三篇文章中,明确了栅格系统的设计细节和适用范围。这一篇将集中讨论960栅格系统的技术实现。

Blueprint的实现

Blueprint是一个完整的CSS框架,栅格系统是它的一部分功能。

三栏布局的代码为:

<style type="text/css">
    .container { margin: 0 auto; width: 950px }
    .span-8 { float: left; margin-right: 10px }
    div.last { margin-right: 0 }
    hr { clear: both; height: 0; border: none }
</style>
<div class="container">
    <div class="span-8"></div>
    <div class="span-8"></div>
    <div class="span-8 last"></div>
    <hr />
</div>

上面是基本功能,Blueprint还支持append-n, prepend-m, border等“高级”功能,这些就不细说了。Blueprint的特点简单总结如下

  1. 采用浮动来实现布局,简单明了
  2. 950两侧没有margin, 最后一列的class需要加上last
  3. 采用额外标签来清除浮动

960.gs的实现

谈到960栅格系统,不得不提960.gs. Nathan Smith在这篇文章中,详细阐述了他的想法和设计思路。这里有个demo页面,核心代码很简单:

<style type="text/css">
    .container_12 { margin: 0 auto; width: 960px }
    .grid_4 { float: left; margin: 0 10px }
</style>
<div class="container_12">
    <div class="grid_4"></div>
    <div class="grid_4"></div>
    <div class="grid_4"></div>
    <div class="clear"></div>
</div>

上面就构建了三栏布局

有意思的几点:

  1. margin是均匀放在950两侧的
  2. 所有grid除了宽度不同,左右边距都一致margin: 0 10px;
  3. 代码简单清晰,起始和结束列不需要添加额外class

很明显,Blueprint和960.gs都是采用浮动来实现布局的,主容器需要添加额外标签来清除浮动(可以参考这里)。当然,这也不是什么大问题,请看这篇文章的总结,不添加额外标签也可以清除浮动。

YUI的实现

接着来看大名鼎鼎的YUI Grids CSS. YUI的CSS框架由三个文件组成:

reset.css - 样式重置
fonts.css - 版式字体控制
grids.css - 栅格系统

我们从demo开始

注意,demo链接中的宽度是750的,但我们只要将<div id="doc"></div>中的id改为doc2, 页面宽度就自动变为950宽了(YUI非常强大^o^)。来看下dom结构:

采用的也是浮动布局,简化后的CSS代码为:

<style type="text/css">
    .doc2 { margin: auto; width: 73.076em }
    .yui-u { float: left; margin-left: 1.99%; width: 32% }
    div.first { margin-left: 0 }
    #ft { clear: both }
</style>

YUI的特点是:

  1. 依旧是采用浮动布局,槽(Gutter)宽通过margin-left来控制(Blueprint采用右边距,960.gs采用均分,这三个框架对槽的处理实在有意思)
  2. 总宽度采用em, 这样可以用在弹性布局上
  3. 栏的布局用的是百分比,采用了流体布局

YUI的好处是能用来做自适应布局,在这前面两个框架里是没有的。但普通的定宽布局,YUI则显得有点麻烦,比如我们要实现四栏布局,dom得这样写:

先来两个两栏布局,再细分为四栏布局,清晰度上欠佳。

更多栅格实现

栅格化更多是一种布局思想,实现技术可以千差万别。比如今年冒出来的伪绝对定位,立刻就可以用来实现栅格系统。明城兄弟就尝试了一把

肯定还有非常多的栅格化实现方案,这里就不一一挖掘了。

双飞翼栅格系统

挺奇怪这个名字?请先阅读这篇文章:渐进增强式布局探讨. 简单说,双飞翼布局是一种布局实现技术,可以利用它来实现一整套栅格系统。

先看test页面:Grids Layout Test.

具体技术细节在渐进增强式布局探讨一文中已经阐述,这里不再重复。有几点需要说明:

  1. 这套栅格系统并不能实现所有布局。这和YUI Grids类似,只能实现预定的一些布局。比如三栏布局,目前只加入了5 : 13 : 6, 5 : 12 : 7, 9 : 9 : 6, 8 : 8 : 8四种情况,这是从淘宝的现有页面中分析总结出来的。对于同一个站点来说,太多不同的三栏比例不是好事(淘宝目前都有点多,以后可能还会进一步统一)。因 此如果采用这套栅格系统的话,需要先分析站点,定义出一套合适的比例。这里有个所有比例的自动生成工具:grids_css_generator.html.
  2. 关于命名:.grid-c2-s6表示两栏(c2: column 2)布局,sub栏的宽度是4列(s4: sub width is 4 * 40 -10). 而.grid-c2-s6f, 最后的f表示两栏布局的第二种情况,即submain互换。类似地,.grid-c3-s5e6d表示三栏布局,其中sub栏的宽度是5, extra栏的宽度是6, 最后的d表示是s5e6三栏布局中的第四种情况。
  3. 为了方便使用,将最常用的两栏布局.grid-c2-s5.grid-c2直接表示。同样的,.grid-c3表示.grid-c3-s5e6. 这是淘宝的默认值,其他站点可以根据实际情况修改。
  4. 这套布局符合渐进增强式工作流程。细心的你可能已经发现,所有两栏布局和三栏布局,HTML中的DOM结构是完全一样的,只有最外层divclass不同。如果要交换左右栏,只要非常简单的修改下class就可以。
  5. 实际使用时,两栏布局和三栏布局已经够用。其实有了两栏,其它布局就都可以组合出来。这里有一个尝试性页面:grids_test4_v0.1.html. 组合布局看起来很强大,但实际使用时会把问题搞复杂,不推荐使用,干脆忘掉吧。

最后来看下两个测试页面:两栏布局grid-c2_test.html三栏布局grid-c3_test.html.

目前除了发现在ie6下有个bug(超大图片等会撑乱布局,其实可以用overflow: hidden来解决,但考虑overflow负面影响,最后还是由布局内部的模块来自主控制的好),尚未发现其他问题。

小结

栅格系统更多的是一种布局思想,在实际使用时,根据具体需求选用合适的技术来实现即可。需要注意的是,对于栅格的技术实现来说,太灵活未必是件好事,适度灵活最难得。怎么才能适度呢?这需要疯狂实践 + 不断的反思 + 持续的重构 + 悟…

栅格搭好了页面框架,接下来很重要的一件事情就是往里面添加内容模块。让内容模块规范化,让页面生成工业化,对大型站点来说,这是栅格系统最有商业价值的地方。下一篇也是本系列最后一篇将展示栅格系统中的模块化应用。

原文链接:http://ued.taobao.org/blog/2008/11/grid_system_research_4/

3.说说掌握JavaScript语言的思想前提

无论是公司的同事还是外界的程序员朋友们,大部分人对JavaScript的高级应用不甚了解,已有的知识架构里会认为JavaScript 仅仅是一门脚本语言,其作用是给页面做一些锦上添花的效果,比如表单验证等等。潜意识里也就不会用面向对象的思想去编写JavaScript代码,也很少 会去深入了解prototype, closures等概念。这导致书写的代码经常很糟糕。

对于JavaScript的学习,可能最重要的还是要从思想上认识到JavaScript不是玩具语言。JavaScript的作用远不止增加点表单验证,我们可以看看GMail、看看Google Maps,如果开发者们没有对JavaScript足够尊敬,是不大可能写出如此优秀的Web应用的。

JavaScript门槛很低,但门槛低并不意味着容易掌握。一定程度上,JavaScript的入门容易以及其极大的灵活性,使得要掌握 JavaScript变得很难。从纯语言上讲,我个人的经验是,学习 JavaScript比学习Java更具挑战性。我们大多习惯了传统的面向对象表述方式,一定程度上甚至会认为类、封装、继承等概念都得像Java、 C++那样,可能都从来没想过没有class, extend, override等概念也能面向对象。JavaScript的面向对象打破了这种思想上的禁锢:世界是多样性的,条条大路通罗马。夸张一点说,深入学习 JavaScript,更多的是一种思想上的挑战,能活跃思路,扩大视野,甚至改变对世界的看法。

上面所说的这些,无意于夸大JavaScript的作用和难度。每个人都或多或少的会强调自己所学的知识,但在这里,我希望自己能很客观的传递一个观点:无论什么语言,想要精通,都很不容易;如果想学习某门语言,就得从思想上尊敬这门语言,在尊敬的基础上去学习,才有可能掌握这门语言的精髓。除了JavaScript,再举个HTML的例子:

经常能听到这样的话:HTML多容易,花个一两天也就会了。我自己也曾这么认为。但随着使用HTML经验的增长,慢慢感觉到, 对于Web前端开发来说,HTML可以说是最难的。HTML4.01规范中的91个元素就如汉字里的2500个常用字一样,我们读完小学后对常用字应该就 都认识了,但要用汉字写篇优秀的文章,却并不容易。HTML也是这样,大部分宣称HTML很容易的开发者,往往只停留在认识body, p, form, table, div, ul等标签上,对于dl, legend, sub, caption等并非生僻的标签甚至都不认识。在常用字还认不全的情况下,宣称HTML很容易,真的很狂妄。(HTML的难度在于如何利用标签构建出结构 良好且富含语义的代码,就如写作文一样,不能认为认识几个字就自信能妙笔生花。)

总之,语言无贵贱难易,要从思想上尊敬重视一门语言,才有可能驾驭它,否则,将永远游离在专业程序员的宝殿之外。

(注:我觉得写得很好,所以就贴过来了)

原文链接:http://ued.taobao.org/blog/2008/12/thinking_on_master_js/

3.Reset CSS研究

参考资料