2009年6月

垂直栅格与渐进式行距

准备工作
去年的时候,青云发表过 关于栅格系统的文章   . 我们知道网页的栅格系统是运用固定的格子设计版面布局,使其风格工整简洁. 视觉上来说,栅格系统能够将大块区域分割成小区域,清楚地展示页面的布局,并能够引导视觉线在各个板块之间扫描、阅读. 从信息上来说,栅格系统让信息的呈现方式更加直观,从而有效提高易读性.
但是大部分栅格系统是在水平方向上的布局,其实,我们的垂直方向也是有栅格系统的——也就是我们的“垂直韵律”.
垂直韵律的就像好比我们手上拿着的线格本子,有着一行行的网格线,安排着垂直方向上的文字排版。“排版中的空间就像是音乐里的节拍. ”音乐的节拍虽然有许多变化,但是几乎每首歌都会有一个固定的节拍来掌握整个歌曲的节奏. 这就是为什么栅格系统一般用固定宽度的网格阵列来指导和规范网页中的版面布局以及信息分布.
其实,那么,在网页里,垂直韵律应由三个因素控制:

  • 字体大小(font-size)
  • 行距(line-height)
    具体定义可以参照我的《字体、排版简明入门》 中行距这一节
  • 间距(margin,padding)
    认真考量这三个因素的值,才能实现垂直韵律.

开工
基础行距
在垂直韵律中,基本的单位是行距. 在整个页面上设定一个合适的行距是垂直韵律之所以能够成为韵律的必要条件. 这个行距,我们将应用于整个页面的所有文字上,包括正文、标题、侧边栏等. 例如,我们现在设定我们的字体大小(css font-size)为12px,行距(css line-height)为18px. (对于中文宋体来说,12px是能够清晰显示的最小字号. 为了保证可读性,12px的1.5倍行距就是18px. 同时12px/18px也是中文互联网上最常用的字号和行距. )我们在空白页面的垂直方向上以18px为单位做垂直网格,就像我们线格本子上的线条,每条网格线也就是基线的对齐线. 接着,我们放上三个段落(12px/18px)作为例子讲解.


(demo-1.html)

段落间距
段落间加上段间距不但美观,而且容易在视觉上区别各段落. 但是要注意的是,垂直韵律最容易被打破的地方就是两个元素在垂直方向上的空白了. 所以,为了让下一段的文字内容落在网格内,我们要将段落间距设置为基础的倍数. 例如:我们可以设置段前距为9px,段后距为9px,9px+9px=18px;或者设置段前距(css margin-top)为0,段后距(css margin-bottom)为18px;或者段前距和段后距都是18px. 这里,我们选取第二种方案,即,设置段前距为0,段后距为18px. 图中可以看到,每段段落的文字都落在了格子内. 关闭网格可以发现,段落清晰明了,比之前容易阅读多了.


(demo-2.html)

添加标题
使用浏览器默认的样式,你会发现,大多数情况下,垂直韵律都被打破了. 所以,添加标题,我们需要选择正确的行距和间距才可以.
有了添加段间距的经验,相信添加标题也不是一件难事了. 标题的文字要比正文的文字要大的多. 例如,我们现在选择h1的字体大小为24px.
那么,根据附录结论有:

  • 行距和全部垂直间距之和为基础行距的倍数。

那么,我们假设行距为36px,则可以设置段前距为9px,段后距为9px (验证有:36 + 9 + 9 = 54 = 3 * 18).
同样,我们也可以设置h2:字体大小18px,行高24px,段前距3px,段后距9px(验证有:24 + 3 + 9 = 36 = 2 * 18)。


(demo-3.html)

添加边注
网站我们常常有侧边栏,我们这里就用右边的边注来代表。在这里的例子中,我们和正文一样设定边注的排版:字体12px,行距18px。正是由于我们前面的努力,我们可以看到,边注的基线和正文的基线是对齐的。关闭网格可以看到,由于基线的对齐,整个排版有条不紊,十分美观。


(demo-4.html)

添加边框
添加边框道理相同,无非要的就是最后要求基线与网格对齐。这里的例子中,我们来给边注加个边框吧。给他加上1px边框(css border)后,还要再加上8px的补白(css padding).细心的同学们一定发现了,为什么补白是8px呢?其实很简单,这就是保证垂直方向上的补白和边框之和,是我们的基础行高18px的倍数:垂直方向上两个补白两个边框,那么1 + 8 + 8 + 1 = 18.


加上去后,我们发现,恩?怎么没有右边文字没有对齐到网格上呢?原来加上了补白和边框后,边注下移了9px,所以网格就没有对齐啦。那么,我们就要把边注上移9px。现在,我们可以看到右边的文字已经对齐到网格。是不是感觉不错?


(demo-5.html)

不同字体大小的正文
如果有一天,老板告诉你,正文的字体太小啦,他看得眼花。你因此不得不将左边的正文设置成14px大小的字体,右边的边注保持12px。由于正文字体变大,我们也同时加大行距。根据我们前面学到的知识,我重新设计了间距:

  • 正文:字体大小14px,行距24px,段后距24px
  • h1:字体大小24px,行距24px,段前距24px,段后距24px
  • h2:字体大小:18px,行距24px,段前距12px,段后距12px
  • 边注正文:字体大小12px,行距24px,段后距24px
  • 边注边框:边框粗1px,内补白11px——别忘了还要把它上移12px

效果见:


(demo-6.html)

完工
OK,最后,我们来做个使用前使用后的对比,来张合照吧:
使用前:


使用后:


附录 基本垂直韵律对行距、间距的要求的推导
根据之前的经验,不难得出:
设行距为 dl px ,设垂直方向上的间距和为 ∑ds = dst (段前距) + dsb (段后距) (px) ①,假设基础行距为k px,则
n*k = dl + ∑ds (n为自然数) 即行距和间距之和应当是18的倍数 ②
由方程①、② 得出:
行距和全部垂直间距之和为18的倍数。

Gearman使用简介

Gearman1月16日发布了c语言的0.2 版本,gearman提供了一个work传递其他机器,或者调用其他机器功能的框架,通过gearman你可以实现并行的工作,负载均衡处理,调用其他语言的函数。它可以应用在多种场合,从高可用性的web服务到数据库复制,换句话说,它是分布式处理的中枢神经。gearman早期是sixpart实现的perl语言开发的版本,名字来源于"Manager",这一框架只负责分发要做的工作,本身并不做任何实际的工作。(这点与spread toolkit相同 译者注)。

怎样使用 Gearman?


一个简单的gearnan的体系包括三个部分,一个client,一个worker,一个job server,client负责创建并发起一个job请求,job server负责找到合适的worker,worker当然就是负责执行job,事实上是worker完成了实际的任务。gearman提供一个api从而你的client与worker能够与job server通信。我们来看一个简单的gearman应用实例。这一实例只完成一个功能,将一串字符串reverse。
首先我们要写一个client, “reverse_client”,代码实际上就是负责发起job请求,并返回结果。代码实际上就是连接job server,并发起一个请求 reverse函数,代码部分如下:

gearman_client_create(&client);
gearman_client_add_server(&client, "127.0.0.1", 0);
result= gearman_client_do(&client, "reverse", "Hello world!",
strlen("Hello world!"), &result_size, &ret);

这段代码首先初始化一个client实例,配置并连接一个本地的job server ,然后发起了一个reverse的请求,参数是 "Hello world!"函数名称与参数,这些与gearman的要求一致。现在gearman的将这个请求数据打包发给job server,job server会自动寻找合适的worker来执行。
让我们来看看worker的代码:

void *reverse_function(gearman_job_st *job, void *cb_arg,
size_t *result_size, gearman_return_t *ret_ptr)
{
const uint8_t *workload;
uint8_t *result;
size_t x;
size_t y;

workload= gearman_job_workload(job);
*result_size= gearman_job_workload_size(job);
result= malloc(*result_size);
for (y= 0, x= *result_size; x; x--, y++)
result[y]= workload[x - 1];
*ret_ptr= GEARMAN_SUCCESS;
return result;
}

gearman_worker_create(&worker);
gearman_worker_add_server(&worker, "127.0.0.1", 0);
gearman_worker_add_function(&worker, "reverse", 0, reverse_function, NULL);
while (1) gearman_worker_work(&worker);

这段代码定义了一个函数 “reverse_function” ,这个函数接收一个字符串,然后反向这个字符串的顺序,并且用一个worker的实例向job server注册了一个reverse函数。
当job server收到请求reverse的时候,就会传递相关的数据给这个worker,worker会执行reverse_functio,将执行结果返回job server,最后传递给初始请求者。
实际上client与worker提供了job管理系统的交互与管理的大部分工作,你需要做的不过是完成client与worker的部分代码。在这一版本的examples目录下,提供了以上这个例子。

gearman都能用来干什么?

gearman可以用在各个方面,最简单就是在不同语言之间架起一座桥梁。比如你可能希望你的php程序调用一个c 函数,那么用gearman就可以实现了,当然了实际你可以通过写一个php扩展来实现同样的工作,但是比如你要php调用java,perl,或者python那么,gearman就非常棒了。
gearman另一个应用方面是负载分担,你可以将worker放在不同的服务器(或者一些列服务器)上,比如你的php程序需要图片转换,但是不希望本地服务器有太多的这样图片转换的进程,那么你可以建立一系列服务器,在上面加载worker处理图片转换。这样你的web服务器将不受图片转换的影响,同时你得到了负载均衡的功能,因为job server会在请求到来的时候,将这个请求发给空闲的worker.同样对于多核的服务器,你可以在同一机器上创建同样数目的worker. 你可能担心,job server处于一个中心,那么这会是一个单点的瓶颈,如果死了,会怎么样?对于这样的情况,你可以运行多个job server。这样如果一个job server down了,client和worker会自动迁移到另一台job server上。

Version 0.2 of the Gearman Server and C library released! You can find it on the downloads page or at Launchpad. You can also find new MySQL UDFs on the downloads page or in Launchpad.

Gearman使用简介

Gearman1月16日发布了c语言的0.2 版本,gearman提供了一个work传递其他机器,或者调用其他机器功能的框架,通过gearman你可以实现并行的工作,负载均衡处理,调用其他语言的函数。它可以应用在多种场合,从高可用性的web服务到数据库复制,换句话说,它是分布式处理的中枢神经。gearman早期是sixpart实现的perl语言开发的版本,名字来源于"Manager",这一框架只负责分发要做的工作,本身并不做任何实际的工作。(这点与spread toolkit相同 译者注)。

怎样使用 Gearman?


一个简单的gearnan的体系包括三个部分,一个client,一个worker,一个job server,client负责创建并发起一个job请求,job server负责找到合适的worker,worker当然就是负责执行job,事实上是worker完成了实际的任务。gearman提供一个api从而你的client与worker能够与job server通信。我们来看一个简单的gearman应用实例。这一实例只完成一个功能,将一串字符串reverse。
首先我们要写一个client, “reverse_client”,代码实际上就是负责发起job请求,并返回结果。代码实际上就是连接job server,并发起一个请求 reverse函数,代码部分如下:

gearman_client_create(&client);
gearman_client_add_server(&client, "127.0.0.1", 0);
result= gearman_client_do(&client, "reverse", "Hello world!",
strlen("Hello world!"), &result_size, &ret);

这段代码首先初始化一个client实例,配置并连接一个本地的job server ,然后发起了一个reverse的请求,参数是 "Hello world!"函数名称与参数,这些与gearman的要求一致。现在gearman的将这个请求数据打包发给job server,job server会自动寻找合适的worker来执行。
让我们来看看worker的代码:

void *reverse_function(gearman_job_st *job, void *cb_arg,
size_t *result_size, gearman_return_t *ret_ptr)
{
const uint8_t *workload;
uint8_t *result;
size_t x;
size_t y;

workload= gearman_job_workload(job);
*result_size= gearman_job_workload_size(job);
result= malloc(*result_size);
for (y= 0, x= *result_size; x; x--, y++)
result[y]= workload[x - 1];
*ret_ptr= GEARMAN_SUCCESS;
return result;
}

gearman_worker_create(&worker);
gearman_worker_add_server(&worker, "127.0.0.1", 0);
gearman_worker_add_function(&worker, "reverse", 0, reverse_function, NULL);
while (1) gearman_worker_work(&worker);

这段代码定义了一个函数 “reverse_function” ,这个函数接收一个字符串,然后反向这个字符串的顺序,并且用一个worker的实例向job server注册了一个reverse函数。
当job server收到请求reverse的时候,就会传递相关的数据给这个worker,worker会执行reverse_functio,将执行结果返回job server,最后传递给初始请求者。
实际上client与worker提供了job管理系统的交互与管理的大部分工作,你需要做的不过是完成client与worker的部分代码。在这一版本的examples目录下,提供了以上这个例子。

gearman都能用来干什么?

gearman可以用在各个方面,最简单就是在不同语言之间架起一座桥梁。比如你可能希望你的php程序调用一个c 函数,那么用gearman就可以实现了,当然了实际你可以通过写一个php扩展来实现同样的工作,但是比如你要php调用java,perl,或者python那么,gearman就非常棒了。
gearman另一个应用方面是负载分担,你可以将worker放在不同的服务器(或者一些列服务器)上,比如你的php程序需要图片转换,但是不希望本地服务器有太多的这样图片转换的进程,那么你可以建立一系列服务器,在上面加载worker处理图片转换。这样你的web服务器将不受图片转换的影响,同时你得到了负载均衡的功能,因为job server会在请求到来的时候,将这个请求发给空闲的worker.同样对于多核的服务器,你可以在同一机器上创建同样数目的worker. 你可能担心,job server处于一个中心,那么这会是一个单点的瓶颈,如果死了,会怎么样?对于这样的情况,你可以运行多个job server。这样如果一个job server down了,client和worker会自动迁移到另一台job server上。

Version 0.2 of the Gearman Server and C library released! You can find it on the downloads page or at Launchpad. You can also find new MySQL UDFs on the downloads page or in Launchpad.

Gearman使用简介

Gearman1月16日发布了c语言的0.2 版本,gearman提供了一个work传递其他机器,或者调用其他机器功能的框架,通过gearman你可以实现并行的工作,负载均衡处理,调用其他语言的函数。它可以应用在多种场合,从高可用性的web服务到数据库复制,换句话说,它是分布式处理的中枢神经。gearman早期是sixpart实现的perl语言开发的版本,名字来源于"Manager",这一框架只负责分发要做的工作,本身并不做任何实际的工作。(这点与spread toolkit相同 译者注)。

怎样使用 Gearman?


一个简单的gearnan的体系包括三个部分,一个client,一个worker,一个job server,client负责创建并发起一个job请求,job server负责找到合适的worker,worker当然就是负责执行job,事实上是worker完成了实际的任务。gearman提供一个api从而你的client与worker能够与job server通信。我们来看一个简单的gearman应用实例。这一实例只完成一个功能,将一串字符串reverse。
首先我们要写一个client, “reverse_client”,代码实际上就是负责发起job请求,并返回结果。代码实际上就是连接job server,并发起一个请求 reverse函数,代码部分如下:

gearman_client_create(&client);
gearman_client_add_server(&client, "127.0.0.1", 0);
result= gearman_client_do(&client, "reverse", "Hello world!",
strlen("Hello world!"), &result_size, &ret);

这段代码首先初始化一个client实例,配置并连接一个本地的job server ,然后发起了一个reverse的请求,参数是 "Hello world!"函数名称与参数,这些与gearman的要求一致。现在gearman的将这个请求数据打包发给job server,job server会自动寻找合适的worker来执行。
让我们来看看worker的代码:

void *reverse_function(gearman_job_st *job, void *cb_arg,
size_t *result_size, gearman_return_t *ret_ptr)
{
const uint8_t *workload;
uint8_t *result;
size_t x;
size_t y;

workload= gearman_job_workload(job);
*result_size= gearman_job_workload_size(job);
result= malloc(*result_size);
for (y= 0, x= *result_size; x; x--, y++)
result[y]= workload[x - 1];
*ret_ptr= GEARMAN_SUCCESS;
return result;
}

gearman_worker_create(&worker);
gearman_worker_add_server(&worker, "127.0.0.1", 0);
gearman_worker_add_function(&worker, "reverse", 0, reverse_function, NULL);
while (1) gearman_worker_work(&worker);

这段代码定义了一个函数 “reverse_function” ,这个函数接收一个字符串,然后反向这个字符串的顺序,并且用一个worker的实例向job server注册了一个reverse函数。
当job server收到请求reverse的时候,就会传递相关的数据给这个worker,worker会执行reverse_functio,将执行结果返回job server,最后传递给初始请求者。
实际上client与worker提供了job管理系统的交互与管理的大部分工作,你需要做的不过是完成client与worker的部分代码。在这一版本的examples目录下,提供了以上这个例子。

gearman都能用来干什么?

gearman可以用在各个方面,最简单就是在不同语言之间架起一座桥梁。比如你可能希望你的php程序调用一个c 函数,那么用gearman就可以实现了,当然了实际你可以通过写一个php扩展来实现同样的工作,但是比如你要php调用java,perl,或者python那么,gearman就非常棒了。
gearman另一个应用方面是负载分担,你可以将worker放在不同的服务器(或者一些列服务器)上,比如你的php程序需要图片转换,但是不希望本地服务器有太多的这样图片转换的进程,那么你可以建立一系列服务器,在上面加载worker处理图片转换。这样你的web服务器将不受图片转换的影响,同时你得到了负载均衡的功能,因为job server会在请求到来的时候,将这个请求发给空闲的worker.同样对于多核的服务器,你可以在同一机器上创建同样数目的worker. 你可能担心,job server处于一个中心,那么这会是一个单点的瓶颈,如果死了,会怎么样?对于这样的情况,你可以运行多个job server。这样如果一个job server down了,client和worker会自动迁移到另一台job server上。

Version 0.2 of the Gearman Server and C library released! You can find it on the downloads page or at Launchpad. You can also find new MySQL UDFs on the downloads page or in Launchpad.

jquery插件-任意位置浮动固定层

可以让指定的层浮动到网页上的任何位置,当滚动条滚动时它会保持在当前位置不变,不会产生闪动
作者:没剑
本地下载:jquery-floatdiv
源码及调用方法:

  1. /*任意位置浮动固定层*/
  2. /*没剑(http://regedit.cnblogs.com) 2009-03-04*/
  3. /*说明:可以让指定的层浮动到网页上的任何位置,当滚动条滚动时它会保持在当前位置不变,不会产生闪动*/
  4. /*2009-03-04修改:重新修改插件实现固定浮动层的方式,使用一个大固定层来定位
  5. 从gmail的信息浮动窗口中偷来的,呵呵
  6. 经多次测试,基本上没bug~
  7. 有问题的朋友欢迎到偶的博客http://regedit.cnblogs.com上提出
  8. */
  9. /*调用:
  10. 1 无参数调用:默认浮动在右下角
  11. $("#id").floatdiv();
  12. 2 内置固定位置浮动
  13. //右下角
  14. $("#id").floatdiv("rightbottom");
  15. //左下角
  16. $("#id").floatdiv("leftbottom");
  17. //右下角
  18. $("#id").floatdiv("rightbottom");
  19. //左上角
  20. $("#id").floatdiv("lefttop");
  21. //右上角
  22. $("#id").floatdiv("righttop");
  23. //居中
  24. $("#id").floatdiv("middle");
  25. 另外新添加了四个新的固定位置方法
  26. middletop(居中置顶)、middlebottom(居中置低)、leftmiddle、rightmiddle
  27. 3 自定义位置浮动
  28. $("#id").floatdiv({left:"10px",top:"10px"});
  29. 以上参数,设置浮动层在left 10个像素,top 10个像素的位置
  30. */
  31. jQuery.fn.floatdiv=function(location){
  32. //判断浏览器版本
  33. varisIE6=false;
  34. varSys={};
  35. varua=navigator.userAgent.toLowerCase();
  36. vars;
  37. (s=ua.match(/msie ([\d.]+)/))?Sys.ie=s[1]:0;
  38. if(Sys.ie&&Sys.ie=="6.0"){
  39. isIE6=true;
  40. }
  41. varwindowWidth,windowHeight;//窗口的高和宽
  42. //取得窗口的高和宽
  43. if(self.innerHeight){
  44. windowWidth=self.innerWidth;
  45. windowHeight=self.innerHeight;
  46. }elseif(document.documentElement&&document.documentElement.clientHeight){
  47. windowWidth=document.documentElement.clientWidth;
  48. windowHeight=document.documentElement.clientHeight;
  49. }elseif(document.body){
  50. windowWidth=document.body.clientWidth;
  51. windowHeight=document.body.clientHeight;
  52. }
  53. returnthis.each(function(){
  54. varloc;//层的绝对定位位置
  55. if(location==undefined||location.constructor==String){
  56. switch(location){
  57. case("rightbottom")://右下角
  58. loc={right:"0px",bottom:"0px"};
  59. break;
  60. case("leftbottom")://左下角
  61. loc={left:"0px",bottom:"0px"};
  62. break;
  63. case("lefttop")://左上角
  64. loc={left:"0px",top:"0px"};
  65. break;
  66. case("righttop")://右上角
  67. loc={right:"0px",top:"0px"};
  68. break;
  69. case("middletop")://居中置顶
  70. loc={left:windowWidth/2-$(this).width()/2+"px",top:"0px"};
  71. break;
  72. case("middlebottom")://居中置低
  73. loc={left:windowWidth/2-$(this).width()/2+"px",bottom:"0px"};
  74. break;
  75. case("leftmiddle")://左边居中
  76. loc={left:"0px",top:windowHeight/2-$(this).height()/2+"px"};
  77. break;
  78. case("rightmiddle")://右边居中
  79. loc={right:"0px",top:windowHeight/2-$(this).height()/2+"px"};
  80. break;
  81. case("middle")://居中
  82. varl=0;//居左
  83. vart=0;//居上
  84. l=windowWidth/2-$(this).width()/2;
  85. t=windowHeight/2-$(this).height()/2;
  86. loc={left:l+"px",top:t+"px"};
  87. break;
  88. default://默认为右下角
  89. location="rightbottom";
  90. loc={right:"0px",bottom:"0px"};
  91. break;
  92. }
  93. }else{
  94. loc=location;
  95. }
  96. $(this).css(loc).css("position","fixed");
  97. /*fied ie6 css hack*/
  98. if(isIE6)
  99. {
  100. $(this).css(loc).css("position","absolute");
  101. /*设置浮动层的位置*/
  102. //var offset=$(this).offset();
  103. //$(this).css({top:offset.top+"px",left:offset.left+"px"});
  104. $("body").css({margin:"0px",height:"100%",overflow:"auto"}).css("overflow_y","auto");
  105. $("html").css({overflow:"hidden"}).css("overflow_x","auto").css("overflow_y","hidden");
  106. /*修正ie6下浮动层在右边显示时出现在滚动条上的问题*/
  107. if(isIE6&&loc.right=="0px"){
  108. $(this).css("right","18px");
  109. }
  110. }
  111. });
  112. };