2009年9月26日星期六

阮一峰的网络日志

阮一峰的网络日志


关于上海房价的政府观点

Posted: 25 Sep 2009 07:36 AM PDT

据上海市国资委的安排,上海建工集团董事长蒋志权昨日做客东方网,与广大网友交流。

他说:

1.5万-3万元/平方米价格区间的住房,不能涨得太厉害,会影响到大部分老百姓的需求。

言下之意:

  1) 大部分老百姓买得起价格1.5万-3万/平方米的住房。

  2)价格1.5万/平方米以下的住房,多涨一点没关系。

  3)只有等到房价超过3万/平方米,政府才会出手调控。

原来如此……

【背景资料】

  ■ 上海建工集团:上海国资委直属的大型建筑施工企业,在中国企业500强中排名第74位,在上海企业100强中排名第8位。

  ■ 蒋志权:1950年出生,现任上海建工(集团)总公司党委书记、董事长,中共十七大代表,中共上海市第九届委员会候补委员。

(完)

2009年9月24日星期四

阮一峰的网络日志

阮一峰的网络日志


风雨如晦,夜深似海

Posted: 23 Sep 2009 09:17 AM PDT

有网友留言,批评我在blog上不谈社会问题,尽写些技术文章。

我承认,最近对社会问题确实没有发言的愿望。

原因有两个。

一方面,想说的话已经都说过了,我不愿重复自己。(推荐重读我三年前张贴的《人吃人的中国》《民生和民权重于经济发展》,我的想法一点没变。)

另一方面,我觉得目前的局势有相当的合理性。如果你明白,政府的行为目标是确保政权稳固,商人的行为目标是追求利润最大化,然后为了达到目标,可以不择一切手段,那么现在国内发生的一切都很容易理解。

既然一切都很合理,还有什么可写的呢?与其空谈和发牢骚,不如去干些实在的事情。

总的来说,我觉得,整个局势已经没有可能挽回了,大错已经铸成,我们只能静待恶果了。这就好像火车脱轨,现在只有眼睁睁看着它坠下悬崖了。当然,悲剧是我们就在这列火车上,明知它要坠毁,却无法下车。我想,只有在发生重大危机的情况下,现行的制度才有松动的可能。但是,什么是重大危机呢?我不知道,目前看上去经济停滞和通货膨胀的可能性最大。有一个简单的事实,日本的经济增长被称为奇迹,从二战后开始,到九十年代结束,持续了40多年。中国的改革开放已经30年了,经济增长的停滞期已经不是特别遥远的事了。

至于这个Blog,从一开始就是我的网上读书笔记。由于这些年来我的兴趣爱好日趋转向技术方面,所以网志中技术的内容越来越多。我知道很多老读者对我感到失望,但是还是希望得到大家的理解,因为我的价值取向从来没有变过。这个Blog一直被我用来传播理想主义价值观、科学思考方法、以及怀疑论,今后将依然如此。不管我在做什么,我始终在做同一件事,请相信这一点。

最后,预告一下,今后我会多写一点经济学方面的内容,毕竟眼下它还是我的专业。

(完)

2009年9月20日星期日

阮一峰的网络日志

阮一峰的网络日志


对于Rails Rumble 2009的一点感想

Posted: 19 Sep 2009 07:38 AM PDT

Rails Rumble是一项年度的编程比赛。

所有参赛团队必须在2天之内,从零开始做出一个网站,然后由组委会评出优胜者。

2009年的比赛已经在上个月结束了,8月22日-23日的那个周末就是比赛时间,并且获奖名单也在上月底对外公布了。48个小时能够做出什么东西?这些网站就是最好的说明。你从中可以看到,目前国际主流的网站开发者的水准。

你会很震惊地发现,所有作品都很成熟,几乎没有任何半成品的痕迹。它们有精美的界面、完全可用的功能、简单但完整的使用说明,而且最重要的一点是,开发者确实将一个点子变成了一个可以直接推向市场的网站,在48小时之中!

比如,第一名的hi.im是一个提供个人信息聚合的网络门户,第四名的Lowdown是一个项目开发的任务管理网站,第六名的hurl是一个调试API头信息的网站,第七名的omnominator是一个找朋友聚会的网站,第九名的bartender是一个鸡尾酒调配法大全的网站。

下面,我想着重谈谈第五名ZenVDN。它的四个作者之一的Jon Dahl写了一篇很好的文章,介绍开发过程。

简单说,ZenVDN是一个视频上传网站,用户上传视频后,可以将播放器嵌入网志,与他人分享。从这点看,它与Youtube很像,但是它比Youtube更专业,用户对自己的视频有更多的输出选项和更多的管理权。

初看之下,你会觉得,这种功能的网站不可能在48个小时内做出来,它能将几十种格式的视频互相转换。只用48个小时就能支持这么多种类的视频格式,怎么可能呢?就连一个评委都提出了这样的质疑。

奥妙就在于,ZenVDN是一个组装起来的网站。它的视频转化功能由Zencoder提供,Flash播放器由Flowplayer提供,视频的储存使用了类似Amazon S3的服务,视频的分发使用了现成的CDN网络,将来的收费服务则打算使用Spreedly。因此,ZenVDN才有可能在48小时中做出来,它的开发团队实际上只是做出了一个用户界面,然后将各种第三方服务整合好就可以了。

我感到,这就是未来网站开发的方向。未来的网站,恐怕很少从头到尾都是一个团队做出来的,而更像是积木,大量使用第三方服务组合和搭建出来。这样做有许多好处,别的不说,单单是四个程序员一个周末就能做出原型,就非常吸引人了。

(完)

2009年9月14日星期一

阮一峰的网络日志

阮一峰的网络日志


用Javascript获取页面元素的位置

Posted: 14 Sep 2009 01:57 AM PDT

作网页的过程中,你有时候需要知道某个元素在网页上的确切位置。

下面的教程总结了Javascript在网页定位方面的相关知识。

一、网页的绝对大小和相对大小

首先,要明确两个基本概念。

一张网页的全部面积,就是它的绝对大小。通常情况下,网页的绝对大小由内容和CSS样式表决定。

网页的相对大小则是指在浏览器窗口中看到的那部分网页,也就是浏览器窗口的大小,又叫做viewport(视口)。

下图中央的方框就代表浏览器窗口,每次只能显示一部分网页。

(图一 网页的绝对大小和相对大小)

很显然,如果网页的内容能够在浏览器窗口中全部显示(也就是不出现滚动条),那么网页的绝对大小和相对大小是相等的。

二、获取网页的相对大小

网页上的每个元素,都有clientHeight和clientWidth属性,利用它们就可以得到网页的相对大小。这两个属性代表的大小,是指元素的内容部分再加上padding的大小,但是不包括border和滚动条占用的空间。

(图二 clientHeight和clientWidth属性)

因此,document元素的clientHeight和clientWidth属性,就代表了网页的相对大小。

  function getViewport(){
    if (document.compatMode == "BackCompat"){
      return {
        width: document.body.clientWidth,
        height: document.body.clientHeight
      }
    } else {
      return {
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight
      }
    }
  }

上面的getViewport函数就可以返回浏览器窗口的高和宽。使用的时候,有三个地方需要注意:

1)这个函数必须在页面加载完成后才能运行,否则document对象还没生成,浏览器会报错。

2)大多数情况下,都是document.documentElement.clientWidth返回正确值。但是,在IE6的quirks模式中,document.body.clientWidth返回正确的值,因此函数中加入了对文档模式的判断。

3)clientWidth和clientHeight都是只读属性,不能对它们赋值。

三、获取网页的绝对大小

document对象的scrollHeight和scrollWidth属性就是网页的绝对大小,意思就是滚动条滚过的所有长度和宽度。

仿照getViewport()函数,可以写出getPagearea()函数。

  function getPagearea(){
    if (document.compatMode == "BackCompat"){
      return {
        width: document.body.scrollWidth,
        height: document.body.scrollHeight
      }
    } else {
      return {
        width: document.documentElement.scrollWidth,
        height: document.documentElement.scrollHeight
      }
    }
  }

但是,这个函数有一个问题。前面说过,如果网页内容能够在浏览器窗口中全部显示,不出现滚动条,那么网页的绝对大小与相对大小应该相等,即clientWidth和scrollWidth应该相等。但是实际上,不同浏览器有不同的处理,这两个值未必相等。所以,我们需要取它们之中较大的那个值,因此要对getPagearea()函数进行改写。

  function getPagearea(){
    if (document.compatMode == "BackCompat"){
      return {
        width: Math.max(document.body.scrollWidth,
                document.body.clientWidth),
        height: Math.max(document.body.scrollHeight,
                document.body.clientHeight)
      }
    } else {
      return {
        width: Math.max(document.documentElement.scrollWidth,
                document.documentElement.clientWidth),
        height: Math.max(document.documentElement.scrollHeight,
                document.documentElement.clientHeight)
      }
    }
  }

四、获取网页元素的绝对位置

由于网页大小有绝对和相对之分,所以网页元素的位置也有绝对和相对之分。网页元素的左上角相对于整张网页左上角的坐标,就是绝对位置;相对于浏览器窗口左上角的坐标,就是相对位置。

Javascript语言中,网页元素的绝对坐标要通过计算才能得到。每个元素都有offsetTop和offsetLeft属性,表示该元素的左上角与父容器(offsetParent对象)左上角的距离。所以,只需要将这两个值进行累加,就可以得到该元素的绝对坐标。

(图三 offsetTop和offsetLeft属性)

下面两个函数可以用来获取绝对位置的横坐标和纵坐标。

  function getElementLeft(element){
    var actualLeft = element.offsetLeft;
    var current = element.offsetParent;

    while (current !== null){
      actualLeft += current.offsetLeft;
      current = current.offsetParent;
    }

    return actualLeft;
  }

  function getElementTop(element){
    var actualTop = element.offsetTop;
    var current = element.offsetParent;

    while (current !== null){
      actualTop += current.offsetTop;
      current = current.offsetParent;
    }

    return actualTop;
  }

由于在表格和iframe中,offsetParent对象未必等于父容器,所以上面的函数对于表格和iframe中的元素不适用。

五、获取网页元素的相对位置

有了某个元素的绝对位置以后,获得相对位置就很容易了,只要将绝对坐标减去滚动条滚动的距离就可以了。滚动条滚动的垂直距离,是document对象的scrollTop属性;滚动条滚动的水平距离是document对象的scrollLeft属性。

(图四 scrollTop和scrollLeft属性)

对上一节中的两个函数进行相应的改写:

  function getElementViewLeft(element){
    var actualLeft = element.offsetLeft;
    var current = element.offsetParent;

    while (current !== null){
      actualLeft += current.offsetLeft;
      current = current.offsetParent;
    }

    if (document.compatMode == "BackCompat"){
      var elementScrollLeft=document.body.scrollLeft;
    } else {
      var elementScrollLeft=document.documentElement.scrollLeft;
    }

    return actualLeft-elementScrollLeft;
  }

  function getElementViewTop(element){
    var actualTop = element.offsetTop;
    var current = element.offsetParent;

    while (current !== null){
      actualTop += current. offsetTop;
      current = current.offsetParent;
    }

     if (document.compatMode == "BackCompat"){
      var elementScrollTop=document.body.scrollTop;
    } else {
      var elementScrollTop=document.documentElement.scrollTop;
    }

    return actualTop-elementScrollTop;
  }

scrollTop和scrollLeft属性是可以赋值的,并且会立即自动滚动网页到相应位置,因此可以利用它们改变网页元素的相对位置。另外,element.scrollIntoView()方法也有类似作用,可以使网页元素出现在浏览器窗口的左上角。

六、获取元素位置的快速方法

除了上面的函数以外,还有一种快速方法,可以立刻获得网页元素的位置。

那就是使用getBoundingClientRect()方法。它返回一个对象,其中包含了left、right、top、bottom四个属性,分别对应了该元素的左上角和右下角相对于浏览器窗口(viewport)左上角的距离。

所以,网页元素的相对位置就是

  var X= this.getBoundingClientRect().left;

  var Y =this.getBoundingClientRect().top;

再加上滚动距离,就可以得到绝对位置

  var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;

  var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;

目前,IE、Firefox 3.0+、Opera 9.5+都支持该方法,而Firefox 2.x、Safari、Chrome、Konqueror不支持。

(完)

2009年9月12日星期六

阮一峰的网络日志

阮一峰的网络日志


小企业的生存之道

Posted: 12 Sep 2009 03:26 AM PDT

(预告:本文结尾处有好玩的东西。)

这几天,我在读Seth Godin的《创业者圣经:有创意,无资金,如何起家》(The Bootstrapper's Bible,上海译文出版社,2000)。我读的是实体书,不过译言上有网友翻译的中译本。

这本书的第一章就谈了一个很重要的问题:在与大企业的竞争中,小企业怎么活下去?

表面上看,如果市场已经被大企业占领,小企业就根本没可能活下来。

原因有以下五点:

1)经销渠道。大企业的产品无处不在,广告铺天盖地。

2)融资渠道。大企业能够借到大笔资金。

3)名牌效应。消费者信任著名品牌。

4)客户关系。客户往往不信任新公司,更愿意与以前的合作方合作。

5)优秀雇员。大企业能够吸引优秀的人才。

因为上面这些原因,所以就算小企业有非常优秀的产品,也很难与大企业竞争。这就告诉我们,创业的时候,应该避开大企业的优势领域,而选择进行侧面竞争,也就是避其锋芒,攻其不备。

具体来说,是这样的:

1)经销渠道。尽量不要采用传统的经销渠道,更多地考虑与用户面对面地推销。

2)融资渠道。不选择需要大量资金的项目进行创业。

3)名牌效应。你的产品没有人家名气大,那就只好选择比人家便宜了。

4)客户关系。先做一笔小生意,与客户建立关系,或者直接把产品送给客户试用,然后再慢慢蚕食大企业的客户。而且每次都以一个客户作为重点,开展销售工作,不分散力量。

5)优秀雇员。并非所有的雇员都追求公司的名气、稳定的工作和高报酬,事实上,很多人都喜欢带有冒险性的工作,喜欢有灵活的工作时间、关心下属的老板、认股权、方便的工作地点、没有官僚主义和复杂人际关系的工作环境,良好的发展机会等等。只要你能提供这些大企业无法提供的东西,你就能从他们手里争夺到优秀人才。

因此,只要你有一个好的产品(或服务),然后采取正确的策略,你就有很大的机会,在竞争中生存下来。

更有利的是,互联网时代的到来,使得小企业的生存环境进一步改善。

a. 小企业大多选择服务业创业,服务业的规模效应不显著,互联网加强加强了这种趋势。

b. 在新技术的帮助下,小企业能达到与大企业一样的高效率。

c. 小企业机构简单,管理灵活,更适合向顾客提供个性化的产品/服务。

所以,总的来看,巨人并不是不可战胜的,大企业的优势其实也不是那么牢不可破。如果说20世纪是大公司和大集团的世纪,那么也许21世纪就是小企业和创业者的世纪。

好了,现在是趣味时间,点击这里,然后按播放键,你就可以看到我是怎么写出这篇文章的,我觉得很有趣啊。

(完)

2009年9月9日星期三

阮一峰的网络日志

阮一峰的网络日志


关于网站备案

Posted: 09 Sep 2009 04:16 AM PDT

2004年,信息产业部要求网站备案,否则就是非法网站。

我赶紧就去备案了,ruanyifeng.com的备案号是"沪ICP备05002727号"。

后来,我把网站放到了境外服务器上,备案号就没用了。但不管怎么样,我认为我的网站依然属于合法网站,因为我履行了政府对我的要求,申请了备案,把我的真实联系方式留给了政府,好让他们随时能够找到我。

再后来,曾经为我托管服务器的那家国内公司倒闭了,由于我的备案是他们代办的,导致我在备案管理系统的用户名和密码作废,ruanyifeng.com处于被冻结状态,找回密码,需要向上海市通信管理局申请。我觉得太麻烦,就没去申请。当然,更主要的原因是,就算密码找回来了,我也不知道我要用它干什么。

此后的几年,一直太平无事。直到今年的8月22日,我收到了一封Email:

关于ICP备案信息被接入商取消接入的通知

发信人:webmaster@mail.miibeian.gov.cn

尊敬的用户(阮一峰):您备案信息中填写的接入商(中国电信集团福建省分公司ICP)经核实,认为你备案的网站非其接入,已经取消了相关接入,目前您主体下备案网站(网站名称:阮一峰的个人主页,域名:ruanyifeng.com等)已不存在任何接入信息,具体情况您可再向接入商进行确认。请尽快联系你的新接入商为你填加接入信息。特此通知!

政府要求我提供网站接入商信息,可是我的网站是由美国公司提供互联网接入的,那家公司不在政府目前认可的1141家ISP之列,事实上所有外国ISP都不在其中。那样的话,即使我修改了ISP,也不会审核通过的。备案成功的基本规则就是,你的接入商必须在政府的名单中。所以,我没有办法,只能对着那封Email干瞪眼,束手无策。

今天,我又收到了第二封Email。

关于ICP备案信息不符合备案要求退回修正的通知

发信人:webmaster@mail.miibeian.gov.cn

尊敬的用户[阮一峰],很遗憾的通知您,您的ICP备案申请(ruanyifeng.com),经[上海市通信管理局0]审核,不符合备案要求,现退回修改,原因请登陆系统查询。

政府发现我的备案不符合他们的要求,再一次要求我修改。但是正如我前面说的,我的用户名和密码已经作废,现在连备案系统都无法登录,所以根本没法修改。退一步说,就算能修改的话,又能怎么修改呢?把服务器搬回境内?算了吧。

这就是整件事情荒谬的地方。现行的网站备案制度,其实是一种"双绑定"制度,一方面将网站和它的所有人绑定在一起,另一方面将网站和它的接入商绑定在一起。一旦出事的话,政府不仅要找到网站的所有人,还要找到网站的接入商。为什么要找接入商呢?说穿了,就是为了第一时间把网线拔掉

所以,对于网站主来说,服务器放在境内是很可怕的事情。你的网线随时有可能被拔,你的硬盘随时有可能被破坏,甚至整台服务器都会被搬走,再也要不回来。(我一点没有夸张,这是每天都在发生的事情。)此外,如果你想更换接入商的话,就需要很麻烦地申请修改备案。因此,网站有了合法身份,反而会让你觉得很不安全,好像法律不是在保护你,而是在迫害你一样。

六十大庆一天天临近,工信部加快速度,清理备案不合格网站。我不知道接下来会发生什么事情,屏蔽所有未备案或备案不合格的网站?也许吧。经过这一年,我觉得什么事情都有可能发生。

今天,我写这件事情,就是想跟大家打个招呼,说一声这里有可能被屏蔽。如果这真的发生了,你可以翻墙或通过Feed阅读我的文章。另外,为了防止万一,我启用了一个备份网址:http://ruanyf.blogspot.com/(大陆读者需要翻墙)。

最后我想说,几十年以后,或者几个世纪以后,回顾这段历史的时候,大家会觉得网站备案、GFW、绿坝软件、诸如此类的事情,都是好事,因为它们让许多中国青年认清了这个社会的本质,不再对旧制度抱有幻想,开始期盼新制度的到来,从而大大加快了社会变革的速度。要是没有它们,许多人也许要过许多年才会对现行制度产生怀疑,从而进行彻底的反思,新制度就会因此少了许多支持者。统治者越是凶恶,其实越表明他的恐慌和虚弱,而历史就像印度诗人泰戈尔所说,"总是在耐心地等待被侮辱和被压迫者的胜利"。

(完)