tag:blogger.com,1999:blog-202645752009-03-02T22:19:47.957+08:00Who is Anson ?Who is Anson ?Ansonnoreply@blogger.comBlogger70125tag:blogger.com,1999:blog-20264575.post-19822146444326676652008-01-30T16:18:00.000+08:002008-01-31T16:23:03.365+08:00关于企业开博的五大疑问在<a href="http://www.anseo.cn/seo/">SEO</a>业界的绝大多数人都认为,<a href="http://www.gdqiye.org/">企业</a>开博是不明智的。许多大型的在线零售商也没有接受这种观念,即通过博客拓展其在线业务。<br />  从纯<a href="http://www.anseo.cn/seo/catalog.asp?tags=seo">SEO</a>的角度看,博客有许多的优点。搜索引擎,特别是谷歌等对博客钟爱有加。与电子交易网站相比,一个博客在搜索结果中的排名更好一些,因为博客具有电子交易网络不具备的新鲜东西。<br />  通过设计,博客可以实现搜索的最优化。但是,一开始不要在Blogger或是MySpace上开博客。<br />  一开始你要用 Moveable Type或是WordPress建立你的博客,设定公司域名,至少要把域名整合到现有的网站中。<br />  由于搜索引擎爬虫只对两到三层内容进行深度索引,因此,它可以对绝大多数的博客进行快速而有效的索引。这就帮助网站指数水平不断刷新,特别是如果发的帖子是首推内容时,更是如此。<br />  与企业电子交易网站相比,博客通常被视为更真实和更可信。在博客、相关博客作者以及博客内容中,很少的直接的经济激励。所有的要素都是平等的,一篇出色的博客,被读者认可,也被搜索<br />  引擎认可。鉴于其交互本性,好的博客可以极大地增强品牌、商品和服务的可视度。<br />  那么,什么是一个好的博客?如何才能使博客做好?好的博客必须能给读者带来什么。如果博客网站与读者产生共鸣,用户就会恋上这个博客。不断的访问会导致更多的RSS反馈订阅,这一切通过<br />  不断的努力激励用户可以实现。如果你对客户感到担心,担心用户对品牌、商品和服务的意见,你就最好把博客建立成一个好的博客。<br />  好的博客也会增强自然链接,博客作者喜欢交朋友,希望链接到其它博客。通过建立一个真实而新颖的博客,即使是一个企业博客或是主要品牌都能在博客社区赢得信任。你也可能成为博客的其中一分子,博客作者更喜欢链接你的网站,提供关于他们博客的有关报道。作为一名有思考见解的领导者,博客作者只要不断地发布相关的,而且是有见识的内容,就可以建立自己的信誉度。<br />  一个出色的博客能增强企业的在线名誉,吸引新的用户,提升网站流量,成为网站长期链接战略的一个重要组成部分。<br />  建立一个新的博客可能是最困难的事,选择主题,设计博客,确定投放标准,开发可编辑的日历以确保有足够的内容,等等,这些都需要时间,需要适度的投资,更为重要的是需要精心规划。许多在线企业发现,在建立博客前,以下五个问题是最难回答的。<br />  一、博客内容是关于什么的?博客的主题应该与企业的产品和服务是一致的,一个只链接到电子交易网站的博客在博客社区不会走的太远。珠宝零售网站ice.com开设了一个叫Sparkle Like the<br />  Stars博客,这个博客讨论流行话题,讨论名人穿什么珠宝以及如何复制等内容。它比“here's what's new in stock“博客人气更旺。而SeenON博客,则避免讨论名人对珠宝的需求等内容。这两<br />  个博客对于不同的零售商来说,都起很大的作用。<br />  二、谁写博客?企业博客内容可以由员工、非正式职工或是品牌行销者编写。如果博客作者不在企业内部,就要明白博客由<a href="http://www.gdqiye.org/">企业赞助</a>,以避免出现关于企业的负面报道。业界指责,一些博客是在愚弄读者。员工可以成为出色的博客作者,因为他们理解品牌的方向,可以更有效地控制信息。非企业人员也可以成为出色的博客作者,因为他们希望得到信任,对一个产品作评论时不会发表片面的意见。谁写博客要根据你的博客主题而决定。<br />  三、博客要花多少时间?每天都一更新博客是最理想的,但是,一周几数更新也是有效的。发布内容质量越高,你发布的频率就越低。如果每个帖子需要30-60分钟来编写,则每周需要五分之一的时间写博客。当第一次发布内容时,最好平均分配对其它博客作者内容发表评论的时间。每周写博客和评论的时间约为10小时,除非发布博客程序十分繁杂。如果法律部门要对每个帖子都进行审查,就要进行重写和删除等,这样每周的时间就为30个小时。<br />  四、博客要花多少钱?许多博客服务都是免费的,但非免费的博客服务在关键词可视度和链接流行度方面没有实现最优化。<a href="http://www.gdqiye.org/">企业</a>博客应该代表企业的声音,企业的设计风格和企业的品牌形象。企业博客应建立在一个坚实的战略基础之上,应能为企业电子商务网站带来最大利益,而不要成为企业的一个工具。如果要品牌因素考虑进去的话,一开始建立博客花不了太多的钱。同理,技术平台的建立也相对便宜。<br />  五、博客真的有帮助吗?如果博客的开发和维护实现了最优化,具有透明度,传达亲切的声音,做出真切的承诺,则博客有很大的帮助。帮助有多大,这主要取决于你对博客的投入力度,以及你对博客年景的分析程度。如果博客作者缺乏忠诚,对客户不诚实,则博客会事得其先,损害<a href="http://www.gdqiye.org/">企业利益</a>。如果你对企业的在线起声誉存在争论,意见不一,则需要更多的时间,而不光是建立博客,来修复存在的问题。<br />  从SEO的角度看,建立博客只是一种策略。一个体现品牌形象的新博客,应该被视为你的SEO整体战略的一部分。一个博客只是这个整体战略的一大部分或是一小部分。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-1982214644432667665?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-56649778019491679172007-05-23T21:35:00.000+08:002007-05-23T21:39:12.245+08:00什么是CDN?CDN加速简介  随着互联网的发展,用户在使用网络时对网站的浏览速度和效果愈加重视,但由于网民数量激增,网络访问路径过长,从而使用户的访问质量受到严重影响。特别是当用户与网站之间的链路被突发的大流量数据拥塞时,对于异地互联网用户急速增加的地区来说,访问质量不良更是一个急待解决的问题。如何才能让各地的用户都能够进行高质量的访问,并尽量减少由此而产生的费用和网站管理压力呢?内容发布网络(Content Delivery Network,<strong>CDN</strong>)诞生了。<br />一、<strong>CDN是什么</strong>?<br /><br />---- <strong>CDN</strong>的全称是<strong>Content Delivery Network</strong>,即内容分发网络。其目的是通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的网络“边缘”,使用户可以就近取得所需的内容,提高用户访问网站的响应速度。CDN有别于镜像,因为它比镜像更智能,或者可以做这样一个比喻:CDN=更智能的镜像+缓存+流量导流。因而,CDN可以明显提高Internet网络中信息流动的效率。从技术上全面解决由于网络带宽小、用户访问量大、网点分布不均等问题,提高用户访问网站的响应速度。<br /><br />---- 为更好地理解CDN,让我们看一下CDN的工作流程。当用户访问已经加入CDN服务的网站时,首先通过DNS重定向技术确定最接近用户的最佳CDN节点,同时将用户的请求指向该节点。当用户的请求到达指定节点时,<strong>CDN</strong>的服务器(节点上的高速缓存)负责将用户请求的内容提供给用户。具体流程为: 用户在自己的浏览器中输入要访问的网站的域名,浏览器向本地DNS请求对该域名的解析,本地DNS将请求发到网站的主DNS,主DNS根据一系列的策略确定当时最适当的CDN节点,并将解析的结果(IP地址)发给用户,用户向给定的CDN节点请求相应网站的内容。<br /><br />二、<strong>CDN的相关技术</strong><br /><br />---- <span style="font-size:130%;"><strong>CDN</strong></span>的实现需要依赖多种网络技术的支持,其中负载均衡技术、动态内容分发与复制技术、缓存技术是比较主要的几个,下面让我们简单看一下这几种技术。<br /><br />---- <strong>负载均衡技术</strong><br />---- 负载均衡技术不仅仅应用于CDN中,在网络的很多领域都得到了广泛的应用,如服务器的负载均衡、网络流量的负载均衡。顾名思义,网络中的负载均衡就是将网络的流量尽可能均匀分配到几个能完成相同任务的服务器或网络节点上,由此来避免部分网络节点过载。这样既可以提高网络流量,又提高了网络的整体性能。在CDN中,负载均衡又分为服务器负载均衡和服务器整体负载均衡(也有的称为服务器全局负载均衡)。服务器负载均衡是指能够在性能不同的服务器之间进行任务分配,既能保证性能差的服务器不成为系统的瓶颈,又能保证性能高的服务器的资源得到充分利用。而服务器整体负载均衡允许Web网络托管商、门户站点和企业根据地理位置分配内容和服务。通过使用多站点内容和服务来提高容错性和可用性,防止因本地网或区域网络中断、断电或自然灾害而导致的故障。在CDN的方案中服务器整体负载均衡将发挥重要作用,其性能高低将直接影响整个CDN的性能。<br /><br />---- <strong>动态内容分发与复制技术</strong><br />---- 大家都知道,网站访问响应速度取决于许多因素,如网络的带宽是否有瓶颈、传输途中的路由是否有阻塞和延迟、网站服务器的处理能力及访问距离等。多数情况下,网站响应速度和访问者与网站服务器之间的距离有密切的关系。如果访问者和网站之间的距离过远的话,它们之间的通信一样需要经过重重的路由转发和处理,网络延误不可避免。一个有效的方法就是利用内容分发与复制技术,将占网站主体的大部分静态网页、图像和流媒体数据分发复制到各地的加速节点上。所以动态内容分发与复制技术也是CDN所需的一个主要技术。<br /><br />---- <strong>缓存技术</strong><br />---- 缓存技术已经不是一种新鲜技术。Web缓存服务通过几种方式来改善用户的响应时间,如代理缓存服务、透明代理缓存服务、使用重定向服务的透明代理缓存服务等。通过Web缓存服务,用户访问网页时可以将广域网的流量降至最低。对于公司内联网用户来说,这意味着将内容在本地缓存,而无须通过专用的广域网来检索网页。对于Internet用户来说,这意味着将内容存储在他们的ISP的缓存器中,而无须通过Internet来检索网页。这样无疑会提高用户的访问速度。CDN的核心作用正是提高网络的访问速度,所以,缓存技术将是CDN所采用的又一个主要技术。<br /><br />三、<strong>谁需要CDN</strong>?<br /><br />---- 既然CDN的核心作用是提高网络的访问速度,那么其用户也就是访问量很大的网站,例如ICP 、ISP、大型企业、电子商务网站和政府网站等。利用CDN技术,这些网站无需投资昂贵的各类服务器,设立分站点。通过采用CDN,CDN将负责信息传递工作,保证信息正常传输,而技术人员只需要维护网站内容,不需要考虑流量问题。这样,网站可保证用户得到更多的新业务,可以快速访问网络上的内容,获得更好的服务质量。举个例子来讲,对于访问量比较大,而被访问内容更新周期比较长的网站,如政府网站,用户往往进行大量的查询工作。这类网站比较适合采用CDN。还有,大家是否注意到,在所谓的宽带社区中,瓶颈是社区的对外出口。这样,如果采用CDN无疑对社区用户使用视频点播、网络教育等宽带应用提供了保证。<br /><br />四、<strong>CDN的不足</strong><br /><br />---- 任何一个新事物,在给现有模式带来改进的同时,也必然存在一定的局限,CDN也是这样。据互联通网络有限公司的技术经理郭广中讲,实时性不太好是CDN的致命缺陷。随着对CDN需求的逐渐升温,这一缺陷将得到改进,使来自于远程服务器的网络内容网页与复本服务器或缓存器中的网页保持同步。解决方法是在网络内容发生变化时将新的网络内容从服务器端直接传送到缓存器,或者当对网络内容的访问增加时将数据源服务器的网络内容尽可能实时地复制到缓存服务器。<br /><br />五、<strong>CDN产品</strong><br /><br />---- 目前,推出比较成熟的CDN产品的厂家有Cisco、F5和互联通公司等,前两者的CDN是以硬件系统为主,而后者的CDN是以软件为主的通用平台,很好地结合了线路和服务优势。下面简单分析一下互联通的CDN——<strong>Smart CDN</strong>。<br /><br />---- 互联通采用整体负载均衡(<strong>GSLB</strong>)、缓存技术(<strong>Cache</strong>)及镜像技术(<strong>Mirror</strong>)相结合的方法,为客户提供异地网络加速服务。具体方案是在网站主站点以外的用户集中城市、地区使用互联通的网络加速服务,互联通智能GSLB系统通过互联通专网,引导网站用户访问“最佳”Cache/Mirror服务器,从而绕过互联网拥堵链路,减轻主站点服务器负载,实现异地网络加速,并解决了单纯Cache/Mirror不能解决的难题。<br /><br />---- <strong>Smart CDN</strong>通过DNS解析或HTTP重定向两种方式工作,通过Cache服务器或异地的镜像站点完成内容的传送与同步更新。DNS方式用户位置判断准确率大于85%,HTTP方式准确率为99%以上。经实际测算,各Cache服务器群的用户访问流入数据量与Cache服务器到原始网站取内容的数据量之比在2:1到3:1之间,即分担50%~70%的到原始网站重复访问数据量(主要是图片、流媒体文件等内容)。对于镜像,除数据同步的流量,其余均在本地完成,不访问原始服务器。<br /><br />---- Smart CDN系统基于用户实际访问的IP地址判断用户位置,直接将用户访问指向响应速度最快的站点。整个系统管理简单,用户可通过GUI确定有哪些内容需要做分布式分发,系统会自动完成内容的复制、更新及数据库同步的全过程。并且,系统具有自诊断、负载均衡的能力,任何环节发生故障,不会影响整个系统的可访问性。<br /><br />---- 可以说,负载均衡技术在CDN中发挥着重要的作用,其能力高低对CDN的性能产生直接影响。Smart CDN所采用的负载均衡具有一定的优势,主要体现在如下几个方面。<br /><br />---- 1. 高智能化<br />---- 运用虚拟IP(VIP)地址代表目标服务器和应用,Smart CDN将会话分配到最高可用性的服务器,全程监控每个会话。服务恢复后自动重新登记,并在转发客户机和服务器信息包时提供全地址转换。Smart CDN采用了包括循环法、最少连接法、散列法或最少失误法等多种不同的负载均衡方法,并对个别服务器配置最大连接数量阈值和加权值,这样可以有效避免服务器超载。<br /><br />---- 2. 高可靠性<br />---- Smart CDN架构在互联通专用的高速骨干网之上,该主干网络提供延迟极小的网络连通性,从而保障GSLB的功能正常发挥和高性能,优于基于公网的GSLB。并且,当主站点机房的Internet出口出现故障时,Smart CDN还能将用户自动、透明地从其他分站点Internet入口导向主站点服务器,从而提高了网络的可靠性。<br /><br />---- 3. 高可用性<br />---- 采用热备份方法,在极短时间内对服务器链路、交换端口和交换机进行检测和故障转移,使应用免受故障影响。一旦任何一个服务器或服务器群发生故障或阻塞,用户将被自动引导到下一个最佳备份服务器或站点,从而更进一步提高了服务和内容的可用性。<br /><br />---- 4. 高冗余性<br />---- Smart CDN运行在互联通“三环嵌套”网络主干架构之上,具有高冗余特点,从而保证了高可靠性和高可用性,这一点和其他基于公网的GSLB解决方案有很大差别。<br /><br />---- 另外,Smart CDN在服务上的优势体现在: 通过互联通专有链路系统,可提高用户访问的响应速度;保证了两岸三地区域内多点多地服务器内容同步;消除了峰值访问(Peak Load)对出口链路及服务器性能的压力;提高了租用链路的带宽利用率; 降低了原始Web/FTP网站的负载等。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-5664977801949167917?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-39038730144145658402007-04-25T15:11:00.000+08:002007-04-25T15:14:15.376+08:00企业为什么要上市?企业上市属于股权融资、直接融资,与向银行贷款等间接融资方式相比,具有明显的优势:<br /><br />上市融入的资金具有永久性,无需归还,可以大幅度降低企业财务成本,免受国家收缩银根等金融政策的影响;募集资金数量大、速度快。如果企业以20倍市盈率发行股票,意味着需要用20年时间积累的资金可以通过上市一次性募集到位;企业上市后就获得了在资本市场持续融资的通道,可以通过配股、增发、发行可转债等方式多次融资。丝绸股份通过新股上市和发行二次可转债共募集资金14.4亿元;上市融入的资金可以作为其它融资方式的基础,提高企业举债能力;企业上市还有助于完善企业的法人治理结构,在市场竞争中发挥管理优势和制度优势;上市还可以提升企业形象,提高公信力和知名度,获得更多发展契机。<br /><br />1、提供企业股份的流动性,使股东的股份可以买卖和套现<br /><br />2、有助企业规范结构和管理<br /><br />3、使企业能更快,更容易集资和融资<br /><br />4、有利于企业兼并,资产重组和收购<br /><br />5、提高企业公众形象及对客户的信誉<br /><br />6、有助于企业获得银行贷款<br /><br />7、便于企业向员工发行福利股票,使员工的积极性与企业利益紧密联系<br /><br />8、使企业发展更上一层楼<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-3903873014414565840?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-15872605448962453532007-04-25T15:08:00.000+08:002007-04-25T15:10:35.079+08:00Google介绍Google 的使命是整合全球范围的信息,使人人皆可访问并从中受益。<br />完成该使命的第一步就是 <a href="http://www.google.cn">Google</a> 的创始人 Larry Page 和 Sergey Brin 共同开发的全新的在线搜索引擎。该技术诞生于斯坦福大学的一个学生宿舍里,然后迅速传播到全球的信息搜索者。 Google 目前被公认为全球最大的搜索引擎,它提供了简单易用的免费服务,用户可以在瞬间返回相关的搜索结果。<br />在访问 Google 主页时,您可以使用多种语言查找信息、查看新闻标题、搜索超过 10 亿幅的图片,并能够细读全球最大的 Usenet 消息存档,其中提供的帖子超过 10 亿个,时间可以追溯到 1981 年。<br />用户不必特意访问 Google 主页,也可以访问所有这些信息。使用 Google 工具栏可以从网上任何一个位置进行 Google 搜索。即使身边没有 PC 机,您也可以通过 WAP 和 i-mode 手机等无线平台使用 Google。<br />Google 的实用性及便利性赢得了众多用户的青睐,它几乎完全是在用户的交口称颂下成为全球最知名的品牌之一。作为一个企业,Google 通过提供广告服务来获取收入,使广告客户能够刊登与特定网页内容相关的、重要而又经济实效的在线广告。这不仅为您提供了实用的广告信息,同时也给刊登广告的广告客户带来了好处。我们认为,您有权知道在您面前展示的消息是否为付费的,因此我们始终将搜索结果或网页上的其他内容与广告区分开来。我们不出售搜索结果中的排名,也不允许有人付费来获取搜索结果中的较高排名。<br />成千上万的广告客户加入了我们的 Google AdWords 计划,利用针对性强的广告在网上推广自己的产品和服务,同时我们相信 AdWords 是同类服务中规模最大的一个。此外,成千上万的网站管理人员利用我们的 Google AdSense 计划,刊登与其网站内容相关的广告,以增加收入和改善用户的体验。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-1587260544896245353?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.comtag:blogger.com,1999:blog-20264575.post-26419109656245364152007-03-26T16:42:00.000+08:002007-03-26T16:45:06.607+08:00雅虎专利:我们发明了Web 2.0<div>看到这则消息,非常震惊。 而且很鄙视雅虎把广泛应用的技术占为自由的行为。虽然yahoo在web2.0上作了不少贡献,但是也不能把其作为自有。对雅虎的素质感到失望了。:( 正文如下<br />------------------------------------------------<br />继去年中旬将自家网站改版为Web 2.0风格后,雅虎近日递交了一份专利申请,在其中声称是他们发明了Web 2.0技术。<br /><a href="http://www.patentmonkey.com/PM/PatentID/7171414.aspx">这份编号7171414的专利</a>描述的是一种“动态页面生成器”(Dynamic Page Generator),可以让用户自定义网页模板,以显示其他消息来源的数据,主要用于新闻页面服务,方便用户定制新闻头条、股市行情、赛事比分、天气预报等信息。<br />奇怪的是,专利文档中给出的实例包括各种Web 2.0应用,完全可以看成是在说Google自定义主页、Pageflakes、Netvibes等典型Web 2.0网站,甚至在线RSS阅读器。雅虎称,他们早在二十世纪九十年代末就开始研究Web 2.0技术了。<br />可以想象,如果这份专利获得批准,各家Web 2.0公司和网站就不得不面临雅虎律师了。<br /><a href="http://file9.mydrivers.com/newsothers/other/7171414.pdf">点击查看雅虎专利文档(PDF)</a> </div><br /><img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://news.mydrivers.com/img/20070226/04002731.gif" border="0" /><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-2641910965624536415?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-19944272491190697662007-03-26T16:38:00.000+08:002007-03-26T16:40:50.161+08:00很不错的 CSS HackCSS Hack<br />height:20px; /*For Firefox*/<br />*height:25px; /*For IE7 & IE6*/<br />_height:20px; /*For IE6*/<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-1994427249119069766?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-44884855554115825412007-01-24T12:21:00.000+08:002007-01-25T14:49:02.989+08:00李开复:身在微软 心在中国  2005年7月19日,一个令微软和比尔·盖次愤怒的日子。<br />  这一天,Google宣布:“李开复担任Google中国区总裁,并将负责Google中国研发中心的运营”。此言一出,业界哗然,微软更是大为震惊,盖次甚至亲自跑到李开复的直接上司雷斯特副总裁那里去咆哮:“你的部门里到底还有多少人想离开?”可见,李的离去,在微软造成了多大的震荡。甚至,在大洋彼岸的中国都听到了比尔·盖次的怒吼。<br />  随即,微软一纸诉状,将Google和李开复一并告上微软总部所在地——华盛顿州西雅图市的帝王县法庭。因为一个人的跳槽,终于让两家世界上最具影响的互联网公司面对面的开“火”了。<br />  很长时间以来,李开复就是微软中国研究院(以下简称软院)的代名词。因为他创办了软院,也是因为他软院才得到了发展,并使后者成为世界上最具影响的研究院之一,甚至连比尔·盖次都多次重申,微软最优秀的研究中心在中国,现在为微软服务的最杰出的人才很多都来自于这里。<br />  正是因为软院(后来升格为微软亚洲研究院)的杰出成就,2000年李开复荣升为微软全球副总裁,奉调到美国工作,成为微软高层里职位最高的华人。<br />  但,悲剧就在这里埋下。<br />  从内心里说,李开复对微软还是极为认可的。虽然,随着时间的推移,微软在中国的业务时起时伏,加上李身在微软总部,没有了如鱼得水的感觉,这也为日后李开复“反水”埋下了隐患。<br />  离开了中国,李开复有如希腊<br />神话中的安泰离开了大地,即便身居高位却再也找不到感觉了。Google插足成功,正是看准了这个弱点。<br />  自1998年以来,李开复就在中国各高校巡回演讲,网罗人才。演讲内容不仅涉及纯学术的计算机研究、科学、教育等,更多的是教导中国大学生如何做人、做事。在给中国大学生写信的同时,李开复还开办了针对中国大学生的网站,现在他的网站上每月有超过10000人来访。有时,李也网站上回答问题,形成互动。在年轻一代的学子心中,李开复一度就是他们的楷模。<br />  其实,在5年前李被奉调美国时,这场跳槽就已经注定,只争早晚。李虽然身在西雅图,然而,他更关注国内的发展,甚至一直就在暗中寻找回国的机会。也许,只有回到了中国,李开复才有一种真正的成就感,而这一切,微软的“老爷们”却一无所知。<br />  2005年5月的一天,李开复打开新浪网,Google要建中国公司的字幕立即跃入眼中,李开复大为惊喜,当即与自己的旧识——Google CEO 埃里克进行了联系,表达了自己的想法。<br />  果然,埃里克不负所望,立即安排了所有的面试。总裁、副总裁、以及Google的创始人,一个都不拉下,该见的李开复全都见了。<br />  面试之后的李开复并没有立即作出承诺,而是展开了一场调查。调查Google是不是其描述的那样,有没有必要值得自己冒险一跳。<br />  现在,Google在中国的各项业务正全面展开,微软的起诉也秘密和解。<br />  李开复事件从反面来看,一方面表明微软作为一家有影响力的公司在全球的吸引力正在下降,另一方面也说明了微软内部的管理出了纰漏。从吴士宏离开微软算起,以及唐骏的反叛,到现在的李开复跳槽,多少都说明了一点问题。<br />  作为一个将理想和事业都寄托在中国的人,让李开复离开自己的土地,多少说明了微软官僚们的失察。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-4488485555411582541?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-30105748618339585512007-01-14T14:52:00.000+08:002007-01-30T14:53:36.305+08:00学以致用 驳“ASP低能论”很多人错误地认为ASP是简单、低效的代名词,认为ASP是低能的,不足挂齿的,也很简单,一学就会,一琢磨就精通。<br /><br />有人讲ASP不安全,写ASP的程序的时候如果严格按照书写安全的代码的规范去写,写出来的程序也没有什么理由不安全。那些人说ASP不安全,好像PHP、JSP的程序就不会出现SQL Injection似的。<br /><br />有人讲ASP不高效,真的想要高效的话你可以结合COM,在Win32平台下COM的效率Java是永远追不上的。单纯讲速度有什么意义呢?Java的速度绝对算不上高,论速度的话好多技术方案的速度都比Java高,这一点学Java的人最清楚了,可是谁在乎过这一点了?Java的胜出绝对不是因为它的速度。抛开具体的应用环境单纯地讲速度是不理性的。<br /><br />有人讲ASP这个不能做,那个做不了,功能很局限。其实只要你明白Web的原理的话你就会明白,写ASP程序表面看是在玩一种脚本语言,但你指挥的是Web Server,有很多复杂的功能ASP也照样能完成的很好,有些功能ASP假如因为Web应用的先天局限做不了,你不要以为JSP、PHP就能做到。<br /><br />再提到功能。要说功能的话ASP+SQL Server肯定比PHP+MySQL强百倍,MySQL不支持事务处理,就这一条让PHP开发者吃了多少亏,没有视图,没有存储过程和触发器,没有数据库端的用户自定义函数,不能完全使用标准的SQL语法,这都是MySQL的缺点。可是PHP程序员在乎这一点了吗?没有!因为他们最在乎的是MySQL很快。(注意,是MySQL很快,不是PHP很快。同样,是MySQL不支持事务处理,而不是PHP的过错。)在面对PHP+MySQL的时候,人们就如此的理性。面对ASP的时候很多人就缺乏这种理性的认识。<br /><br /><br />还有人提到MVC,是的我知道JSP可以把MVC发挥得很好。但是MVC这种编程思想不是Java或某种方案的专利,只要掌握了MVC的程序构架思想,你一样能写出这样的ASP程序、PHP程序。<br /><br />许多人单纯地做一些语言本身的比较,有什么意义呢?就好像你谈JSP的时候不谈JavaBeans,不谈EJB,那么你谈JSP有什么意义呢?同理谈ASP的时候你不谈COM,有什么意义呢?不要忘了ASP的核心就是COM。谈PHP的时候如果不谈它强大的平台——Unix/Linx,PHP照样什么也不是。<br /><br />不过有一点是可以肯定的,那就是:ASP的入门门槛最低。这按理说应该算ASP的优点,它秉承了微软技术一贯的作风——简单,入门门槛低。也正是因为这一点,使得大量的Web开发领域的新手能够很快地开发网站。但也正因为这一点,使许多掌握了ASP的一点皮毛知识的人自认为对ASP很懂,结果写出很垃圾的程序,让别人看了ASP的笑话。其实我接触过的一些JSP程序员也很垃圾,他们处理数据库操作的时候低级错误百出,但是因为他们是用Java开发的,所以给别人的感觉好像就高人一等。其实真的优秀的程序员如果明白了ASP的一些原理的话也能把ASP驾驭得很好。有些人玩不转ASP,你不能因此说这是ASP的问题。玩不转ASP的人大多是没有正确理解Web,而不是没有正确理解ASP中的语法。<br /><br />ASP的语法很简单,Java的语法也复杂不到哪里去,C++和C虽然复杂但是只要是一个智力正常的人也没有理由学不会。<br /><br />问题是语法本身很简单,但是Web很复杂。我们不是在这里浅尝辄止地玩弄一下某种脚本语言,我们是在做Web开发。<br /><br />Web开发虽然有不同的解决方案,但是基本的原理是相通的。如果你清楚Web端程序的一些运行原理,你就会明白你使用的开发技术的语法难度只不过是一种入门级的难度,真正的难度不在于你用什么技术方案去开发Web应用程序,真正的难度在于错综复杂的Web应用自身 。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-3010574861833958551?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-70451572302038295652007-01-12T17:06:00.000+08:002007-01-29T17:07:40.699+08:00英语12个月的来历  公历一年有12个月,但不少人并不知道12 个月的英语名称的来历。公历起源于古罗马历法。罗马的英语原来只有10 个月,古罗马皇帝决定增加两个月放在年尾,后来朱里斯*凯撒大帝把这两个月移到年初,成为1月.2月,原来的1月.2月便成了3月.4月,依次类推。这就是今天世界沿用的公历。<br /><br />  January——1月<br /><br />  在罗马传说中,有一位名叫雅努斯的守护神,生有先后两副脸,一副回顾过去,一副要眺望未来。人们认为选择他的名字作为除旧迎新的第一个月月名,很有意义。英语January,便是由这位守护神的拉丁文名字January演变而来的。<br /><br />  February——2月<br /><br />  每年2 月初,罗马人民都要杀牲饮酒,欢庆菲勃卢姆节。这一天,人们常用一种牛、草制成的名叫Februa的鞭子,抽打不育的妇女,以求怀孕生子。这一天,人们还要忏悔自己过去一年的罪过,洗刷自己的灵魂,求得神明的饶恕,使自己成为一个贞洁的人。英语2月February,便是由拉丁文Februar-ius(即菲勃卢姆节)演变而来。<br /><br />  March-----3月<br /><br />  3月,原是罗马旧历法的1 月,新年的开始。凯撒大帝改革历法后,原来的1月变成3月,但罗马人仍然把3 月看做是一年的开始。另外,按照传统习惯,3月是每年出征远战的季节。为了纪念战神玛尔斯,人们便把这位战神的拉丁名字作为3月的月名。英语3月March,便是由这位战神的名字演变而来的。<br /><br />  April——4月<br /><br />  罗马的4月,正是大地回春.鲜花初绽的美好季节。英文4月April便由拉丁文April(即开花的日子)演变而来。<br /><br />  May——5月<br /><br />  罗马神话中的女神玛雅,专门司管春天和生命。为了纪念这位女神,罗马人便用她的名字——拉丁文Maius命名5月,英文5月May便由这位女神的名字演变而来。<br />  <br />  June——6月<br /><br />罗马神话中的裘诺,是众神之王,又是司管生育和保护妇女的神。古罗马对她十分崇敬,便把6月奉献给她,以她的名字——拉丁文Junius来命名6 月。英语6月June便由这位女神的名字演变而来。也有学者认为,Junius可能是个代拉丁家族中一个显赫贵族的姓氏。<br /><br />  July——7月<br /><br />  罗马统治者朱里斯*凯撒大帝被刺死后,著名的罗马将军马克*按东尼建议将凯撒大帝诞生的7月,用凯撒的名字——拉丁文Julius(即朱里斯)命名之。这一建议得到了元老院的通过。英语7月July由此演变而来。<br /><br />  August——8月<br />  <br />  朱里斯*凯撒死后,由他的甥孙屋大维续任罗马皇帝。为了和凯撒齐名,他也想用自己的名字来命名一个月份。他的生日在9月,但他选定8月。因为他登基后,罗马元老院在8 月授予他Augustus(奥古斯都)的尊号。于是,他决定用这个尊号来命名8月。原来8月比7月少一天,为了和凯撒平起平坐,他又决定从2月中抽出一天加在8月上。从此,2月便少了一天。英语8月August便由这位皇帝的拉丁语尊号演变而来。<br /><br />  September——9月<br /><br />  老历法的7月,正是凯撒大帝改革历法后的9月,拉丁文Septem是“7”月的意思。虽然历法改革了,但人们仍袭用旧名称来称呼9月。英语9月September,便由此演变而来。<br /><br />  October——10月<br /><br />  英语10月,来自拉丁文Octo,即“8”的意思。它和上面讲的9月一样,历法改了,称呼仍然沿用未变。<br /><br />  November——11月<br /><br />  罗马皇帝奥古斯都和凯撒都有了自己名字命名的月份,罗马市民和元老院要求当时的罗马皇帝梯比里乌斯用其名命名11月。但梯比里乌斯没有同意,他明智地对大家说,如果罗马每个皇帝都用自己的名字来命名月份,那么出现了第13个皇帝怎么办?于是,11月仍然保留着旧称Novem,即拉丁文“9”的意思。英语11月November便由此演变而来。<br /><br />  December——12月<br /><br />罗马皇帝琉西乌斯要把一年中最后一个月用他情妇的Amagonius的名字来命名,但遭但元老院的反对。于是,12月仍然沿用旧名Decem,即拉丁文“10”的意思。英语12月December,便由此演变而来。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-7045157230203829565?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1167099370135773532006-12-24T10:11:00.000+08:002006-12-26T10:16:10.136+08:00网站站长SEO工具大集合主流搜索引擎登陆<br /><a href="http://www.baidu.com/search/url_submit.html" target="_blank">百 度登 录</a><br /><a href="http://www.google.com/intl/zh-CN/add_url.html" target="_blank">Google 登 录</a><br /><a href="http://thumbnails.alexa.com/update_thumbnail" target="_blank">Alexa排名提交</a><br /><a href="http://pages.alexa.com/help/webmasters/" target="_blank">Alexa 登 陆</a><br /><a href="http://cn.yahoo.com/docs/info/suggest.html" target="_blank">雅 虎 登 录</a><br /><a href="http://www.yisou.com/search_submit.html?source=yisou_www_hp" target="_blank">一 搜 登 录</a><br /><a href="https://www.google.com/webmasters/sitemaps/stats?hl=zh_CN" target="_blank">Google Sitemaps</a><br /><a href="http://db.sohu.com/regurl/regform.asp?Step=REGFORM" target="_blank">搜 狐/搜狗 登 录</a><br /><a href="http://service.chinasearch.com.cn/NetSearch/pageurlrecord/frontpageurl.jsp" target="_blank">中 搜 登 陆</a><br /><a href="http://ch.dmoz.org/World/Chinese_Simplified/" target="_blank">Dmoz 登 录</a><br /><br />主流搜索引擎关键字访问量查询<br /><a href="http://www2.baidu.com/inquire/rsquery.php" target="_blank">百 度 关 键 字</a><br /><a href="https://adwords.google.com/select/KeywordSandbox" target="_blank">Google 关 键 字</a><br /><a href="http://inventory.overture.com/d/searchinventory/suggestion/" target="_blank">Overture关 键 字</a><br /><a href="http://adpsearch.163.com/find_price.php" target="_blank">网 易搜索关键字</a><br /><a href="http://db.sohu.com/regurl/pv_price/query_consumer.asp" target="_blank">搜 狐 关 键 字</a><br /><br />主流搜索引擎<br /><br />关键词<br /><br />排行榜<br /><a href="http://buzz.yahoo.com/" target="_blank">yahoo关键词排行榜</a><br /><a href="http://sp.ask.com/docs/about/jeevesiq.html?o=0%20" target="_blank">ask关键 词排行榜</a><br /><a href="http://top.baidu.com/" target="_blank">baidu关键词排行榜</a><br /><a href="http://www.google.com/press/intl-zeitgeist.html" target="_blank">google关键 词排行</a><br /><a href="http://50.lycos.com/" target="_blank">lycos关键词排行</a><br /><a href="http://www.yisou.com/top_index.html" target="_blank">一搜关键 词排行榜</a><br /><a href="http://so.163.com/list.html" target="_blank">网 易关键词排行榜</a><br /><a href="http://dir.sohu.com/dir/popular/search/" target="_blank">搜 狐关键 字排行榜</a><br /><a href="http://www.sogou.com/top/index.html" target="_blank">搜狗关键 字排行榜</a><br /><a href="http://www.zhongsou.com/zs_phb/html_top/index.htm" target="_blank">中搜关键 字排行榜</a><br /><br />网站优化工具<br /><br /><a href="http://www.webconfs.com/search-engine-spider-simulator.php" target="_blank">蜘蛛模拟器</a><br /><a href="http://www.seotoolkit.co.uk/keyword_density_analyser.asp" target="_blank">Keywords密度检查</a><br /><a href="http://www.webconfs.com/similar-page-checker.php" target="_blank">相似页面检测工器</a><br /><a href="http://www.seobbs.net/siteinfo/index.php" target="_blank">网站PR值查询</a><br /><a href="http://www.webrankinfo.com/english/tools/Googledance.php" target="_blank">检查Google Dance</a><br /><a href="http://www.webconfs.com/search-engine-spider-simulator.php" target="_blank">搜索引擎抓取内容模拟(英)</a><br /><a href="http://www.iwbuy.com/seo/spider.asp" target="_blank">搜索引擎抓取内容模拟(中)</a><br /><a href="http://www.marketleap.com/siteindex/" target="_blank">搜索引擎抓取页面量统计</a><br /><a href="http://www.marketleap.com/publinkpop/" target="_blank">链接广泛度检测器</a><br /><a href="http://forums.digitalpoint.com/" target="_blank">DigitalPoint搜索论坛</a><br /><a href="http://www.google.com/googleblog/" target="_blank">google博客</a><br /><br />其他相关地址收集<br /><br /><a href="http://www.baidu.com/search/spamreport.html" target="_blank">百 度 垃圾网页投诉中心</a><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-116709937013577353?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1167099080355830352006-12-16T10:06:00.000+08:002006-12-26T10:11:20.356+08:00SEO常用作弊手法一览SEO常用作弊手法一览<br />优化的方式形形色色,一般无外乎按照一定的关键词,通过对网站结构,页面因素和外部链接的优化,使网站得到最佳的搜索引擎排名。但事实上我们发现,有一些网站由于采取了不正确的优化策略,不但未能有效提升网站的排名,反而使网站排名惨跌甚至遭到搜索引擎删除。在此我们列出被Google明令禁止的属SPAM 性质的优化技术供大家借鉴。<br />一:隐藏文本/隐藏链接<br />一般指网页专为搜索引擎所设计,但普通访问者无法看到的文本内容或链接。在形形色色的隐藏技术中,最常见的就是把文本或链接文字的字体颜色设置为与背景色相同或十分接近。<br />隐藏文本内容(Invisable/hidden text) 意欲在不影响网站美观的前提下通过包含大量关键词的网页提高关键词相关性得分,从而达到改善搜索引擎排名的目的。<br />隐藏链接(Invisable/hidden links) 意欲在不影响网站美观的前提下通过在其它页面添加指向目标优化页的隐形链接,通过提升链接得分而改善搜索引擎排名。<br />现在大多数搜索引擎都能检测隐藏技术,并视为作弊。因而包含隐含文本的网页面临被搜索引擎降低排名甚至删除列表的惩罚。虽然在Google上不乏使用隐形技术而侥幸逃脱的网站,但多数人还是认为不值得冒这个险。其实通过添加可视文本内容并保证一定的关键词密度可达到相同的优化效果。<br />二:网页与Google描述不符<br />一般发生于先向搜索引擎提交一个网站,等该网站被收录后再以其它页面替换该网站。“诱饵行为(Bait-&amp;-Switch)”就属于此类偷梁换柱之举--创建一个优化页和一个普通页,然后把优化页提交给搜索引擎,当优化页被搜索引擎收录后再以普通页取而代之。<br />三:误导性或重复性关键词<br />误导性关键词(Misleading Words) 在页面中使用与该网页毫不相干的误导性关键词来吸引查询该主题的访问者访问网站。这种做法严重影响了搜索引擎所提供结果的相关性和客观性,为搜索引擎所深恶痛绝。<br />重复性关键词(Repeated Words) 这种作弊技术也被称为“关键词堆砌欺骗(Keyword Stuffing)”,它利用搜索引擎对网页正文和标题中出现的关键词的高度关注来对关键词进行不合理的(过度)重复。类似的其它做法还包括在HTML元标识中大量堆砌关键字或使用多个关键字元标识来提高关键词的相关性。这种技术很容易被搜索引擎察觉并受到相应惩罚。<br />四:隐形页面(Cloaked Page)<br />对实际访问者或搜索引擎任一方隐藏真实网站内容,以向搜索引擎提供非真实的搜索引擎友好的内容提升排名。<br />五:欺骗性重定向(Deceptive redirects)<br />指把用户访问的第一个页面(着陆页)迅速重定向至一个内容完全不同的页面。<br />“鬼域(Shadow Domain)”这是最常见的欺骗性重定向技术,通过欺骗性重定向使用户访问另外一个网站或页面。一般利用HTML刷新标识(Meta Refresh)来实现。大多搜索引擎都不会索引使用该标识的页面。如果你使用刷新标识来检测浏览器或分辨率,那么就请使用Javascript,且尽可能延长重定向时间。如果一定要使用重定向功能,那么请务必确保刷新周期不少于10秒钟。<br />还有一种情况就是当用户打开一个网站,该网站声称其网站已移至新域名下,并请用户点击新域名链接进入网站。但当用户进去后才发现,这个链接是一个“会员”链接。这也属欺骗性重定向行为。<br />六:门页(Doorway Page)<br />也叫 “Bridge/Portal/Jump/Entry Page”。是为某些关键字特别制作的页面,专为搜索引擎设计,目的是提高特定关键词在搜索引擎中的排名所设计的富含目标关键词的域名,且重定向至另一域名的真实网站。搜索引擎的Spiders往往忽略对那些自动重定向到其它页的页面的检索。<br />七:复制的站点或网页<br />最常见的当属镜象站点 (Mirror Sites)。通过复制网站或?页的内容并分配以不同域名和服务器,以此欺骗搜索引擎对同一站点或同一页面进行多次索引。现在大多数搜索引擎都提供有能够检测镜象站点的适当的过滤系统,一旦发觉镜象站点,则源站点和镜象站点都会被从索引数据库中删除。<br />八:作弊链接技术/恶意链接(Link Spamming)<br />典型的作弊链接技术包括:<br />链接工厂(link farms)<br />大宗链接交换程序(bulk link exchange programs)<br />交叉链接(Cross Link) “链接工厂”(亦称“大量链接机制”)指由大量网页交叉链接而构成的一个网络系统。这些网页可能来自同一个域或多个不同的域,甚至可能来自不同的服务器。一个站点加入这样一个“链接工厂”后,一方面它可得到来自该系统中所有网页的链接,同时作为交换它需要“奉献”自己的链接,籍此方法来提升链接得分,从而达到干预链接得分的目的。如今搜索引擎发现它们已然不费吹灰之力。只要发现,不管属有意还是无意, “链接工厂”中的所有站点都难逃干系。<br />九:其它<br />日志欺骗行为 通过对一些页面等级较高的站点进行大量的虚假点击以求名列这些站点的最高引用者日志中,从而获得它们的导入链接。Google已然意识到这种行为并将对利用这种途径获得导入链接的站点采取相应措施。<br />门域(Doorway Domain) 专为提高特定关键词在搜索引擎中的排名所设计的富含目标关键词的域名,然后重定向至其它域名的主页。由于搜索引擎一般忽略自动重定向至其它页的页面的检索,所以不提倡使用这种技术。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-116709908035583035?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1167098430414740232006-12-11T09:58:00.000+08:002006-12-26T10:00:30.426+08:00Google SEO优化技术的12个要点总结Google SEO优化技术的12个要点总结<br />一、选择服务器放在哪个区域<br />对于Google而言,不同的区域,搜索结果的就不同.一些英文关键词, 你在中国用Google搜索,发现你网站的排名非产靠前,但是如果你在国外用Google, 你可能翻十页都找不到你的网站.<br /><br />我们做Google排名的排名效果不是让我们自己看的, 而是让我们的潜在客户看的. 所以服务器的区域选择应选择潜在客户群体所在的区域。<br /><br /><br />二、检查服务器的IP是否被Google处罚过<br />1、检查一下这台服务器上放了多少网站呢? 如何查呢?这里我们给你大家一个工具,可以很轻松的查出来有多少域名共同指向一个IP:(http://whois.webhosting.info/ip/)<br />例如: 如果你要查219.235.226.75 这个IP你只要在IT地址栏入:<br />http://whois.webhosting.info/219.235.226.75/<br />点击回车, 以后就可以看到这个有多少域名指向了这个IP<br /><br />2、选择几个www.###.com 然后你在Google中输入:site:www.###.com 然后看一看Google收录了这个网<br />站多少页面。如果发现Google还没有收录它,就多查几个,如果大部分都是没有被Google收录的话,那么很有可能这台服务器是被Google处罚过的。为了保险期间,最好别用。<br />一般而言,被google处罚的域名比较多,被Google处罚的服务器相对比较少!<br /><br />三、服务器运行一定要稳定<br /><br />四、选择好的域名,合理设计网站路径和文件名<br />域名/路径/文件名的设计原则:<br />1、那就是要包含关键词。排英文关键词的话,你可以选择与关键词相关的域名.排中文关键词的话,可以用汉语拼音域名,中文网站别人用中文路径和文件名<br />2、静态的路径比动态的路径有利于排名<br />3、顶级域名比二级域名有路径排名(知名网站,权威网站的二级域名除外)<br />4、abc.web.com比www.web.com/abc/有排名优势<br />5、www.web.com/abc/比www.web.com/abc.html这样的路径有排名优势.<br /><br />五、合理设计网页标题与标签:<br />标题和标签主要是指网页源代码中与中间的部分内容. 例如我们的网络营销策划网的首页的标题和标签如下:<br /><br /><br /><br /><br /><br /><br /><br />1、网页标题设计原则:<br />a、每个网页的标题都要不同,并且要与自身网页的内容像符合;<br />b、网页标题设计简介明了,每个页面的标题最好只终点突出1-2个关键词,不要太多;<br />c、标题设计不要太长,最好不要超过25个汉字, 50个英文字母。<br /><br />2、网页描述标签的设计:<br />网页描述标签,它主要是给搜索引擎看的,这个标签设计追求简单明了,与该网页内容相符合。为了提高排名,可以适当在里面提高关键词的密度。<br /><br />3、关键词标签的设计:<br />目前对Google已经没有什么作用了,不过对其他搜索引擎的排名还有一定的作用,这个标签的设计原则和是简介明了,如果是多个关键词,可以用英文逗号格开,无关的关键词最好别用,容易被一些搜索引擎当作左臂来处理。<br /><br />4、网页编码和语言注释标签设计:<br />主要是给浏览器看的。不同语言的编码都不同,所以做外文网站的时候一定要注意,最好用潜在客户使用的操作系统的编码,要不然潜在客户看到的网页将是乱码。如果你的网站是英文网站,你的潜在客户是针对西欧的,你可以用以下代码:<br /><br />六、提高PR值<br /><br />PageRank 技术:通过对由超过 50,000 万个变量和 20 亿个词汇组成的方程进行计算,PageRank 能够对网页的重要性做出客观的评价。PageRank 并不计算直接链接的数量,而是将从网页 A 指向网页 B 的链接解释为由网页 A 对网页 B 所投的一票。这样,PageRank 会根据网页 B 所收到的投票数量来评估该页的重要性。<br /><br />PageRank 还会评估每个投票网页的重要性,因为某些网页的投票被认为具有较高的价值,这样,它所链接的网页就能获得较高的价值。重要网页获得的 PageRank(网页排名)较高,从而显示在搜索结果的顶部。Google 技术使用网上反馈的综合信息来确定某个网页的重要性。搜索结果没有人工干预或操纵,这也是为什么 Google 会成为一个广受用户信赖、不受付费排名影响且公正客观的信息来源。<br /><br />七、合理设计网站链接结构<br />合理的网站链接结构有一下特点:<br />1、拥有一个网站地图,网站地图链接向所有的网页,所有的网页上有一个链接指向网站地图页面;内容要小于100K。<br />2、网站导航清晰明了,方便用户浏览;<br />3、链接不用FLASH按钮和图片,而是使用文本。<br /><br />八、增加反向链接策略<br />1、查看反向链接:在搜索框中输入:link:www.web136.net<br />2、增加网页的反向链接的方法:<br />和相关网站进行链接交换<br />到相关网站可以添加反向链接的网页上添加<br />将网站加入到世界著名分类目录网站中<br /><br />3、选择链接网页的原则:<br />PR值非常高的页面<br />PR值不是太高,但是导出链接比较少的页面<br />权威网站的主要页面<br /><br />九、网站内容与网页设计<br /><br />优秀的网站内容主要包括以下一种:<br />1、原创内容较多,容易被众多网站引用,引用的过程中一般都会给这个页面加有链接,所以这个页面可以获得较好的评分,排名自然会好;<br />2、网站内容丰富:丰富的网站内容会让Google收录网站许多内容,网站各个页面之间的链接有利于其提高网站各个页面的在Google中的评分;<br />3、网站结构清晰明了,页面设计合理,容易被用户浏览和被Google搜索引擎爬虫爬行;<br />4、将asp转化成html,并且压缩减肥 每个页面不要大于100K, 导出链接要小于100个。<br /><br />HTML格式的静态页面容易被搜索引擎收录,并且容易获得较好排名;<br />HTML格式的静态页面比较节省你的服务器资源,不怕你网站人气增加的快;<br />Html格式的静态页面不需要调用数据库、用户浏览起来速度非常快。<br /><br />目前,大部分网站都采取用了新的技术,那就是后来是动态程序,前台是静态页面。虽然前台是html的,但是他们也可以通过后台来修改。<br />如果你的网站是商城系统或者其他的系统,很难断时间内改版,你还可以采取以下策略:那就是通过技术手段把news.asp?id=234 这样的链接映射成 news/234.html<br />这个技术非常简单,你只需要在服务器上装一个 ISAPI REWRITE (Google888.com 有免费下载)、然后进行相应的参数设置就OK<br /><br />十、突出网页中的关键词:<br />1、大标题中要包含关键词:大标题是网页头部用<br />注释的网页标题;<br />2、<{#imeinline} style="LINE-HEIGHT: 150%" align="left">网页文本中的关键词要专门突出:可以用来突出,也可以用醒目的颜色来突出;<br />3、合理调整页面的中关键词出现的频率,一般而言,关键词在网页中出现的频率保持在<br />3%-5%比较好。<br /><br />十一、写好robots.txt文件<br /><br />一个放在网站根目录下面给搜索引擎爬虫指路的文件,如果你一不小心写错了,有可能Google把你所有的网页都给删除掉了。关于这个文件内容的写法,Google网站有详细的说明:http://www.google.com/intl/zh-CN/remove.html<br /><br />十二、增加超链接注释<br /><br />title=”注释内容”<br />不加注释的代码:<br />电子商务指南<br />加注释后的代码::<br />电子商务指南<br /><br /><br />图片注释标签:一般网页中插入一张图片在html的代码如下:<br /><br /><br />可以将图片加上注释,如下:<br /><br /><br />ALT注释一定简介明了,千万不要写的太过冗长,这样会被一些搜索引擎当作作弊来对待的.<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-116709843041474023?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1160893567547514622006-10-15T14:22:00.000+08:002006-10-15T14:26:07.563+08:00李开复论网络创新的未来本文著作权归原作者(李开复),本人仅是引用而已!以下是引用文章:<br />***************************************************************<br /><br /><strong>论网络创新的未来<br /></strong>  在最新、最酷也最绚丽夺目的网络经济中,什么样的创新才能创造出最大的价值?对一家将创新视为灵魂的新技术企业来说,如何充分发挥文化因素的价值,以便更有效也更直接地激励企业的创新精神?<br />  毫无疑问,创新是今天这个时代里最有激情也最有活力的字眼之一。单独地审视创新,人们也许会把与之相关的事物看成是脑力菁英们在好奇心或功利心的驱使下所完成的超乎寻常的工作的总和,但如果把创新放在产业环境、经济布局、时代精神等更大、更广的语境中考察,我们就不难发现,创新其实是一种融汇了科学技术的阶梯状累进形式、社会经济的自我更新规律以及历史文化因素在新经济中的内在映射等更深层内涵的“立体”现象。<br />  尽管人人都倡导并鼓励创新,但却很少有人深入剖析过这种“立体”现象背后的规律性内容。比如,不同类型的企业总是会选择不尽相同的创新模式,其中有什么规律可循吗?如果说创新本身和产业、时代以及经济运行有着紧密的联系,那么在最新、最酷也最绚丽夺目的网络经济中,什么样的创新才能创造出最大的价值?对一家将创新视为灵魂的新技术企业来说,如何充分发挥文化因素的价值,以便更有效也更直接地激励企业的创新精神呢?<br />  笔者打算借助自己在IT产业中积累的丰富的研发、运营和管理经验,深入浅出地探讨一下IT业内最为流行的几种创新模式,并向大家介绍一种与网络时代的精神内涵契合得最好的“创新理念”或日“创新文化”。<br />  <strong>创新模式与“时代精神”</strong><br />  作为人类社会和历史活动的重要组成部分,科学技术的创新也不可避免地带有强烈的“时代色彩”。以物理学的发展为例,当年轻的牛顿在1666年回到乡下老家并独立完成了几项开天辟地般的研究成果的时候,他一定不会想到,两百多年后,麦克斯韦、J.J.汤姆逊或是卢瑟福等人的科学研究竟会如此强烈地依赖于同一时期的产业革命进程,他更不会想到,三百多年后,盖尔曼、霍金、杨振宁等人的工作方式会与大范围的国际协作以及计算机和网络技术的迅猛发展产生密切的关联......<br />将这种“时代色彩”套用到IT产业中来,我们大概可以这样断言:<br />  科技创新推动产业进程,产业进程决定企业的经营模式,而企业的经营模式反过来又进一步影响或决定厂同一时期、同一领域的创新理念。<br />  举例来说,在因特网的浪潮到来之前,IT产业中先后出现了四种主流的创新模式??“象牙塔式”的创新、“单向输出式”的创新、“脑力出租式”的创新以及“研发互动式”的创新。它们在不同的历史时期缔造出了辉煌的科技成果和企业典范,虽然无法更好地适应网络时代的全新挑战,但直至今天,它们仍然在各自熟悉的领域里发挥着重要的价值。<br />  <strong>“象牙塔式”的创新</strong><br />  在IT技术发展的早期阶段,技术本身和产业链条之间的关系还不是特别紧密。软、硬件研发人员更习惯于单纯考虑研发目标的科技含量,而不重视或暂时不考虑其产业价值。这种“象牙塔式”的创新模式从某种意义上也可以被称为“拍脑袋式”的创新??研发人员有了灵感,就写出论文,发表到核心期刊,然后得到同行的认可。<br />  很显然,这种创新模式可以较好地发挥研发人员的创造力和想像力,但也同时具有与产业需求距离较远、研发成果难以转化为实际产品的缺陷。<br />  <strong>“单向输出式”的创新<br /></strong>  有部美国电影讲了这样一个故事:一个人突然梦想要建造一个棒球场,同时他坚定地认为,球场建好后人们一定蜂拥而至,“Build it and they will come!”当然,最终的结果可能并不像他想像得那么好。<br />  这种先发明创造、后招徕用户的做法在1980年代至1990年代的IT界非常普遍。许多著名的企业或研究机构依靠这种创新模式??先由科学家或技术人员主导产品的设计过程,然后再花力气将产品推向市场??取得了显著的成功,但也有不少采用类似做法的企业或是因为错误地理解了潜在的用户需求,或是因为市场推广不利而步履蹒跚。今天,采用这种创新模式的企业已经越来越少了。<br />  <strong>“脑力出租式”的创新<br /></strong>  .COM泡沫破灭的时候,许多公司意识到,为了用最小的花费最大限度地满足用户需求,就必须因市场而变,因客户而变。他们纷纷将研发工作转型为市场或客户导向的“研发服务”:客户的需求直接体现在市场调查的结果中,而市场调查的结果决定了企业要研发什么样的产品和技术,研发部门必须紧密围绕着这一原则贡献自己的“脑力劳动”??所以,这种创新模式也被叫做“脑力出租式”的创新。<br />  这种创新模式的优点是反应速度快,产品设计的针对性强,研发成果转化效率高。但反过来看,因为研发人员几乎直接面对来自市场和客户的压力,在他们的工作中,服务性和定制性的内容越来越多,真正属于“创新”的部分必然越来越少。<br />  <strong>“研发互动式”的创新<br /></strong>  为了解决研究与开发的矛盾,一些在PC浪潮中迅速成长起来的公司在产品部门之外专门设立了研究院或类似的研究机构。研究院拥有独立的架构,不需要在市场或产品部门的压力下工作,其使命就是创造出最新的技术;而产品部门则负责响应市场需求,并在适当的时候将研究院获得的成果转化为优秀的产品。同时,公司高层会统一协调研究院和产品部门之间的关系,使二者达到最好的“互动”状态。<br />  “研发互动式”的创新使许多公司摆脱了研、发脱节的困扰,并同时保持了对市场需求的响应速度以及对未来技术的不懈探索。当然,这种创新模式也有它的问题,比如,研究院和产品部门之间沟通的成本较高,公司对二者的管理投入也相对较大。<br />  <strong>网络时代的新挑战<br /></strong>  近年来,在摆脱了网络泡沫的困扰之后,IT业和因特网已经迎来了一个前所未有的发展机遇:一些长期处于探索阶段的商务模式开始盈利并飞速发展,新的市场需求和新的用户群体不断涌现,新技术和新产品的上市和生存周期大大缩短,资本市场对技术创新的依赖程度越来越高......在这个真正的网络时代里,以网络服务和网络产品为主要方向的企业需要一种崭新的创新模式,只有这样,企业才能在新的挑战面前保持最大的灵活度和最高的工作效率。<br />  <strong>“网络生存”的新型创新<br /></strong>  作为最成功的网络服务和网络产品提供商之一,Google公司从创立的那一天起就走上了一条与传统模式截然不同的创新之路。可以说,Google公司的创新模式在今天的IT产业中具有重要的典型意义:它既成功地解决了研究与开发脱节的问题,又在管理成本和研发效率上达到了最优??Google公司在因特网上取得的成功就是这种创新模式的价值的最好见证。<br />  <strong>研发一体<br /></strong>  早在1930年代,德国哲学家海德格尔在论述科学与真理的关系时就曾预言:“研究者必然自发地涌向根本意义上的技术人员的本质形态的范围中。只有这样,他才能保持活动能力,从而才能在其时代意义上确实地存在,不至于落伍。” (马丁?海德格尔,《世界图像的时代》,1938)客观地说,研究与开发之间的界限在最近50年里已经相当模糊了,而这种模糊??更确切地说是“融合”??正是产业发展的内在需要。<br />  在Google公司里,没有截然分开的研究部门和产品部门,所有工程师的头上都戴着R(研究)和D(开发)两顶帽子。Google要求每位工程师既要有不断创新的勇气和才智,又要有把自己的创意变为现实的技能和经验。在这个创新加实践的乐园里,任何人都可以在任何时候提出一个绝妙无比的创意,任何入也都有机会(或有义务)亲手将自己的创意变为现实。这种研发一体的做法彻底消除了创新与实践之间的隔阂,同时也最大限度地节省了管理和沟通成本,提高了工作效率。<br />  <strong>个人自由</strong><br />  许多人都知道,Google为每一位员工提供了20%可以自主支配的时间。但人们也许并不知道,这20%的时间其实是Google的创新模式中至关重要的一环。一旦有了这20%可支配的时间,蕴藏在工程师头脑中的创意就会层出不穷地“奔涌”出来,在创造力和想像力的指引下,工程师们的价值可以得到最大的体现??许多令Google引以为豪的产品,如Gmail和Google News,就是由工程师在20%的时间里创造出来的。<br />  此外,Google并不会像一般的企业那样,设法将工程师固定在一个项目或一个产品组内。工程师可以随时到自己感兴趣的小组工作,也可以同时加入好几个产品的开发过程。显然,这种管理方式上的灵活性也可以更好地激发大家的创新意识。<br />  <strong>平等参与<br /></strong>  研发过程中的平等参与是Google产品不断创新的另一块基石。Google在公司内部建立了拥有评比和排序机制的“点子库”。员工们可以将自己想到的产品或技术创意放到“点子库”里,然后由其他员工投票评选。公司从“点子排行榜”中选出未来的研发方向,并根据每个“点子”受欢迎的程度决定该项目的规模和重要性。对每个具体的项目,工程师们不仅可以在“点子库”中用手投票,还可以直接用“脚”投票,即亲身参与到该项目的研究与开发中去,与同事??起实现自己的技术梦想。<br />  此外,Google几乎每一件产品的用户都是分布在世界各地的“网民”。产品问世后,立即就会接受全世界数以亿计的用户的考验,用户对产品的好恶马上就能体现到点击率或下载率上。Google深深懂得,这种来自最终用户的“投票”是最平等也最能指导研发进程的“优选法”。<br />  <strong>尖时高效</strong><br />  以往的产品研发总会经历市场调查、产品设计、开发测试、产品封装、市场推广等诸多流程,不但要消耗大量的时间和资源,工程师们对最终用户的响应速度也不会特别快。<br />  Google的产品研发几乎可以被称为“实时”的过程:工程师们有了新的创意,就立即动手实现产品的最初版本,然后将它放在Google实验室里接受用户的检验就在第一批用户试用产品的同时,用户对产品的感受和建议已经通过网络源源不断地反馈到工程师那里;工程师总是能利用实时获取的信息修正或升级产品,让实验室中的产品尽快成熟;而Google则会根据用户的反馈决定哪些产品可以从实验室中“毕业”。<br />  很多软件企业都遵循用户优先的准则,但“用户”这个词在Google公司又多了一层含义。Google的员工其实也是因特网的用户,也就是说,工程师们在研发产品的同时,也能够以最终用户的身份审视和评价产品。这样一来,Google绝大多数产品的研发过程都会有最终用户直接地和全程地参与:在产品设计阶段,最终用户的需求可以毫无障碍地反映到研发小组;在开发阶段,处于迭代周期中的软件产品不停地接受着最终用户的测试;在产品稳定和发布阶段,来自公司内部的工程师和来自全世界的用户共同组成了高效的测试团队......由此得到的产品自然会在用户满意度方面取得优异的成绩。<br />  <strong>使命清晰</strong><br />  和所有最成功的企业一样,Google公司拥有清晰、明确的企业使命,那就是“整合全球信息,服务所有用户”。<br />  面对因特网上数量惊人却明显缺乏有序性的信息内容,普通网络用户总会有无所适从的感觉。如何使最有用的信息以最恰当的形式展现在最需要它的用户面前,这应当是网络时代面临的最大挑战。Google公司正是看到了这一挑战背后蕴藏的巨大机遇,才不遗余力地将研发力量投入到信息整合和网络服务中来。Google的目标是为分布在世界各地的文字、图片、新闻、邮件、商品、音乐、视频等不同形式的信息提供一个统一、便捷的组织方式和检索渠道,这一目标也正是Google在规划和制定创新方向时最为重要的决策依据。<br />  让文化成为创新“源动力”可以说,Google公司的创新模式为网络时代的IT产业开创了一条崭新的发展道路。但是,如果继续探究下去,以便进一步寻找潜藏在这种创新背后的驱动力量,我们又能发现些什么呢?<br />  我认为,Google公司对创新的敏感以及对建立新一代创新模式的渴望从根本上源自Google公司特有的企业文化。其实,每家公司的企业文化都会或多或少地影响该公司的行为模式,只不过在Google,许多企业文化本身就有着极强的“创新”色彩。<br />  <strong>平等、互重</strong><br />  有一次,一位新加入Google的秘书不知道如何使用公司里的传真机,于是就请身后等着发传真的一位先生教自己怎样操作。成功地发出传真后,新来的秘书对那位热心人感谢不已,二人分别报出了自己的姓名。让秘书小姐惊讶万分的是,那位热心人竟然就是Google公司的CEO施密特。<br />  在Google,任何人都要亲自动手处理自己的事情。正因为有了这样企业文化,Google公司的研发人员才自然而然地形成了研发一体的创新理念。<br />  <strong>创新、实干</strong><br />  著名的Google News其实是源自?位工程师的“灵机一动”:他希望看到最热门的新闻,但又不满意门户网站编辑的筛选结果,于是就亲自动手,实现了一个由软件自动编选、排序的“新闻中心”。这种创新加上实干的企业文化直接影响厂Google公司对新产品和新技术的思考方式。<br />  <strong>透明,客观</strong><br />  在Google,所有员工,所有研发小组的工作进程、工作业绩都会在内部网上公布,每个人都可以看到其他人在做什么,做得怎么样。考核员工业绩时,Google并不仅仅依赖管理者的评价,反而更看重与该员工一同工作的其他人的意见。透明和客观的管理方式可以营造出公平的竞争环境,并进而最大限度地激励员工的创新热情。<br />  <strong>利众、不作恶<br /></strong>  利众、不作恶是Google自成立之初就始终坚守的信条。美国“卡特里娜”飓风过后,一家与Google Map合作的卫星公司得到了最新的灾区卫星图片,并将图片发给Google。当时,Google Map小组的所有人都一致认为,尽快将这些卫星图片免费发布到网上,可以解决政府机构和灾区民众的燃眉之急。于是,他们彻夜不眠,用最快的速度更新了服务器中的地图信息,为救灾工作做出了贡献。<br />  <strong>激情、风趣</strong><br />  Google的员工都喜欢在愚人节那天开玩笑。有一年4月1日,居然有位Google员工在eBay上叫卖Google牌的彩色汽水。这种提倡激情和趣味的企业文化体现在研发上面,就成了无数新点子、新创意的最好源泉。<br />  当然,开玩笑过多也会留下“后遗症”。例如,著名的Gmail将发布日期选在了4月1日,结果,许多用户都误认为那又是Google和大家开的愚人节玩笑,因为当时还没有哪个Email服务商可以提供如此大容量的邮箱。<br />  <strong>以人为本<br /></strong>  企业员工是Google的主人,工程师是Google的灵魂。在Google工作的工程师可以享受到最好的开发环境(性能最好的计算机和两台大屏幕的液晶显示器),可以在工作之余尽情放松(伸手可得的食物、游戏机和健身器材、由知名厨师料理的免费餐点......),但更为重要的是,工程师可以非常容易地找到机会,以便把自己的技术理想变成千万人使用的热点产品??对那些渴望在轻松、愉悦的环境中实现自身价值的技术天才来说,这样的人文环境该有多么强烈的诱惑呀!<br />  正是因为有优秀的企业文化,Google才实践出了一条符合网络时代特点的创新之路。希望这种集研发?体、个人自由、平等参与、实时高效、用户优先和使命清晰等特点为一身的创新模式能够为更多的IT企业所借鉴,希望大家都能根据企业自身的特点,研发出最适合企业发展需要,也最能满足未来时代要求的新技术和新产品。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-116089356754751462?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1153902259711254602006-07-26T16:22:00.000+08:002006-07-26T16:24:19.720+08:00搜索综合_搜索引擎下一战场:改变用户搜索习惯Google在搜索领域的老大地位无可置疑,甚至现在“Google”已经成为了英语词典收录的一个词条。但讽刺的是,搜索业务做得越好,开展其他业务的难度却越大。<br /><br />  Google的成功迫使其竞争对手如Yahoo、MSN Search和Ask Jeeves等不得不推出新的功能,改进搜索控制和后台程序。这使到用户可以享受到比以前更多的搜索功能。<br /><br />  但除了改善功能,要令用户满意的话,最大的障碍是如何改变他们的搜索习惯。<br /><br />  事实上,压力并不仅仅来自于Google。2003年4月,Ask Jeeves就在其引擎中加入了“智能搜索”功能,能像百科全书一样回答一些常识性的问题。同一个月,Yahoo将最常被进行搜索的关键词列在其主页上。现在,AOL Search还能提供来自于其合作伙伴的数据库的内容。类似地,MSN Search也能提供来自MSN Music、msnbc.com和微软百科全书的内容。<br /><br />  MSN Search的程序主管经理Ramez Naam表示:“有了可靠的数据,我们就能轻松地找到用户需要的资料,不再是大海捞针,这对用户来说是很大的受益。”<br /><br />  Ask Jeeves今年春天会推出新的技术,改进其“智能搜索”功能。这一称为“直接回答”的新功能,可以辨别用户以问句方式(而不是关键词方式)提出的问题,然后从整个网络上搜寻答案。搜索功能更具人性化。<br /><br />  Google的其他对手则着重于为用户提供更简便和可靠的搜索方式。<br /><br />  为了提供更简单的搜索操作,MSN Search引入关键词逻辑控制功能,能自动决定搜索范围。同时,“NearMe”按钮可以帮助找出最靠近搜索用户所在地的链接。<br /><br />  最近,Amazon的A9搜索引擎亦加入了新的功能,可以把网络上的内容对其数据库进行补充。搜索结果不再仅仅是链接,而加入了动态图片的可视化内容。<br /><br />  而Google本身,亦在不断创新。Google Video能根据剧本内容搜索到电视节目;Google Map则能提供动态更新的航海地图;去年推出的1G容量的Gmail更是掀起了大容量电子邮箱的风潮。<br /><br />  专门统计网站表现的研究机构Keynote Systems的研究总监Bonny Brown博士表示,“令搜索引擎用户最不满的是,搜索结果不够人性化,杂乱无章,甚至有时离题万丈。如果一个网站从现实出发,以人类的心理为指引开展工作,必定能使用户十分满意。”<br /><br />  根据最近的一份研究报告,若要网络用户真正享受到搜索给他们带来的便利,必须首先改变他们的行为模式。该报告的作者Deborah Fallows博士认为,如果搜索网站能更专注于改变大部分搜索用户的搜索习惯,搜索服务的效率将会得到很大的提高。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-115390225971125460?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1150780275174356532006-06-20T13:10:00.000+08:002006-06-20T13:11:15.180+08:00处理文件有两种主要的文件处理类型:<br /><br />创建、添加或删除数据,以及读取文件 <br />移动、复制和删除文件 <br />创建文件<br />创建空文本文件(有时被叫做“文本流”)有三种方法。<br />第一种方法是用 CreateTextFile 方法。 下面的示例示范了在 VBScript 中如何用这种方法来创建文本文件:<br /><br /><br />Dim fso, f1<br />Set fso = CreateObject("Scripting.FileSystemObject")<br />Set f1 = fso.CreateTextFile("c:\testfile.txt", True)<br /><br />要在 JScript 中用这种方法,则使用下面的代码:<br /><br />var fso, f1;<br />fso = new ActiveXObject("Scripting.FileSystemObject");<br />f1 = fso.CreateTextFile("c:\\testfile.txt", true);<br /><br />请考察示例代码,来领会如何在 FileSystemObject 中使用 CreateTextFile 方法。<br />创建文本文件的第二种方法是,使用 FileSystemObject 对象的 OpenTextFile 方法,并设置 ForWriting 标志。在 VBScript 中,代码就像下面的示例一样: <br /><br />Dim fso, ts<br />Const ForWriting = 2<br />Set fso = CreateObject("Scripting. FileSystemObject")<br />Set ts = fso.OpenTextFile("c:\test.txt", ForWriting, True)<br /><br />要在 JScript 中使用这种方法来创建文本文件,则使用下面的代码:<br /><br />var fso, ts;<br />var ForWriting= 2;<br />fso = new ActiveXObject("Scripting.FileSystemObject");<br />ts = fso.OpenTextFile("c:\\test.txt", ForWriting, true);<br /><br />创建文本文件的第三种方法是,使用 OpenAsTextStream 方法,并设置 ForWriting 标志。要使用这种方法,在 VBScript 中使用下面的代码:<br /><br />Dim fso, f1, ts<br />Const ForWriting = 2<br />Set fso = CreateObject("Scripting.FileSystemObject")<br />fso.CreateTextFile ("c:\test1.txt")<br />Set f1 = fso.GetFile("c:\test1.txt")<br />Set ts = f1.OpenAsTextStream(ForWriting, True)<br /><br />在 JScript 中,则使用下面示例中的代码:<br /><br />var fso, f1, ts;<br />var ForWriting = 2;<br />fso = new ActiveXObject("Scripting.FileSystemObject");<br />fso.CreateTextFile ("c:\\test1.txt");<br />f1 = fso.GetFile("c:\\test1.txt");<br />ts = f1.OpenAsTextStream(ForWriting, true);<br /><br />添加数据到文件中<br />一旦创建了文本文件,使用下面的三个步骤向文件添加数据:<br /><br />打开文本文件。 <br />写入数据。 <br />关闭文件。 <br />要打开现有的文件,则使用 FileSystemObject 对象的 OpenTextFile 方法或 File 对象的 OpenAsTextStream 方法。<br />要写数据到打开的文本文件,则根据下表所述任务使用 TextStream 对象的 Write、WriteLine 或 WriteBlankLines 方法。<br /><br />任务 方法 <br />向打开的文本文件写数据,不用后续一个新行字符。 Write <br />向打开的文本文件写数据,后续一个新行字符。 WriteLine <br />向打开的文本文件写一个或多个空白行。 WriteBlankLines <br /><br /><br />请考察示例代码,来领会如何在 FileSystemObject 对象中使用 Write、WriteLine 和 WriteBlankLines 方法。<br /><br />要关闭一个打开的文件,则使用 TextStream 对象的 Close 方法。<br /><br />请考察示例代码,来领会如何在 FileSystemObject 中使用 Close 方法。<br /><br /><br />--------------------------------------------------------------------------------<br /><br />注意 新行字符包含一个或几个字符(取决于操作系统),以把光标移动到下一行的开始位置(回车/换行)。注意某些字符串末尾可能已经有这个非打印字符了。 <br /><br />--------------------------------------------------------------------------------<br /><br /><br /><br />下面的 VBScript 例子示范了如何打开文件,和同时使用三种写方法来向文件添加数据,然后关闭文件:<br /><br /><br />Sub CreateFile()<br /> Dim fso, tf<br /> Set fso = CreateObject("Scripting.FileSystemObject")<br /> Set tf = fso.CreateTextFile("c:\testfile.txt", True)<br /> ' 写一行,并且带有新行字符。<br /> tf.WriteLine("Testing 1, 2, 3.") <br /> ' 向文件写三个新行字符。 <br /> tf.WriteBlankLines(3) <br /> ' 写一行。<br /> tf.Write ("This is a test.") <br /> tf.Close<br />End Sub<br />这个示例示范了在 JScript 中如何使用这三个方法:<br /><br />function CreateFile()<br />{<br /> var fso, tf;<br /> fso = new ActiveXObject("Scripting.FileSystemObject");<br /> tf = fso.CreateTextFile("c:\\testfile.txt", true);<br /> // 写一行,并且带有新行字符。<br /> tf.WriteLine("Testing 1, 2, 3.") ;<br /> // 向文件写三个新行字符。 <br /> tf.WriteBlankLines(3) ;<br /> // 写一行。<br /> tf.Write ("This is a test.");<br /> tf.Close();<br />}<br />读取文件<br />要从文本文件读取数据,则使用 TextStream 对象的 Read、ReadLine 或 ReadAll 方法。下表描述了不同的任务应使用哪种方法。<br />任务 方法 <br />从文件读取指定数量的字符。 Read <br />读取一整行(一直到但不包括新行字符)。 ReadLine <br />读取文本文件的整个内容。 ReadAll <br /><br /><br />请考察示例代码,来领会如何在 FileSystemObject 中使用 ReadAll 和 ReadLine 方法。<br /><br />如果使用 Read 或 ReadLine 方法,并且想跳过数据的特殊部分,则使用 Skip 或 SkipLine 方法。read 方法的结果文本存在一个字符串中,该字符串可以显示在一个控件中,也可以用字符串函数(如 Left、Right 和 Mid)来分析,连接等等。<br /><br />下面的 VBScript 示例示范了如何打开文件,和如何写数据到文件中并从文件读取数据:<br /><br /><br />Sub ReadFiles<br /> Dim fso, f1, ts, s<br /> Const ForReading = 1<br /> Set fso = CreateObject("Scripting.FileSystemObject")<br /> Set f1 = fso.CreateTextFile("c:\testfile.txt", True)<br /> ' 写一行。<br /> Response.Write "Writing file <br>"<br /> f1.WriteLine "Hello World"<br /> f1.WriteBlankLines(1)<br /> f1.Close<br /> ' 读取文件的内容。<br /> Response.Write "Reading file <br>"<br /> Set ts = fso.OpenTextFile("c:\testfile.txt", ForReading)<br /> s = ts.ReadLine<br /> Response.Write "File contents = '" & s & "'"<br /> ts.Close<br />End Sub<br /><br />下面的代码示范了在 JScript 中做同样的事:<br /><br />function ReadFiles()<br />{<br /> var fso, f1, ts, s;<br /> var ForReading = 1;<br /> fso = new ActiveXObject("Scripting.FileSystemObject");<br /> f1 = fso.CreateTextFile("c:\\testfile.txt", true);<br /> // 写一行。<br /> Response.Write("Writing file <br>");<br /> f1.WriteLine("Hello World");<br /> f1.WriteBlankLines(1);<br /> f1.Close();<br /> // 读取文件的内容。<br /> Response.Write("Reading file <br>");<br /> ts = fso.OpenTextFile("c:\\testfile.txt", ForReading);<br /> s = ts.ReadLine();<br /> Response.Write("File contents = '" + s + "'");<br /> ts.Close();<br />}<br /><br />移动、复制和删除文件<br />FSO 对象模式各有两种方法移动、复制和删除文件,如下表所述。<br />任务 方法 <br />移动文件 File.Move 或 FileSystemObject.MoveFile <br />复制文件 File.Copy 或 FileSystemObject.CopyFile <br />删除文件 File.Delete 或 FileSystemObject.DeleteFile <br /><br /><br />请考察示例代码,来领会在 FileSystemObject 中删除文件的两种方法。<br /><br />下面的 VBScript 示例,在驱动器 C 的根目录中创建一个文本文件,向其中写一些信息,然后把它移动到 \tmp 目录中,并在 \temp 中做一个备份,最后把它们从两个目录中删掉。<br /><br />要运行下面的示例,需要先在驱动器 C 的根目录中创建 \tmp 和 \temp 目录:<br /><br /><br />Sub ManipFiles<br /> Dim fso, f1, f2, s<br /> Set fso = CreateObject("Scripting.FileSystemObject")<br /> Set f1 = fso.CreateTextFile("c:\testfile.txt", True)<br /> Response.Write "Writing file <br>"<br /> ' 写一行。<br /> f1.Write ("This is a test.")<br /> ' 关闭文件。<br /> f1.Close<br /> Response.Write "Moving file to c:\tmp <br>"<br /> ' 获取 C 的根目录(C:\)中的文件的句柄。<br /> Set f2 = fso.GetFile("c:\testfile.txt")<br /> ' 把文件移动到 \tmp 目录。<br /> f2.Move ("c:\tmp\testfile.txt")<br /> Response.Write "Copying file to c:\temp <br>"<br /> ' 把文件复制到 \temp 目录。<br /> f2.Copy ("c:\temp\testfile.txt")<br /> Response.Write "Deleting files <br>"<br /> ' 获得文件当前位置的句柄。<br /> Set f2 = fso.GetFile("c:\tmp\testfile.txt")<br /> Set f3 = fso.GetFile("c:\temp\testfile.txt")<br /> ' 删除文件。<br /> f2.Delete<br /> f3.Delete<br /> Response.Write "All done!"<br />End Sub<br /><br />下面的代码示范了在 JScript 中做同样的事:<br /><br />function ManipFiles()<br />{<br /> var fso, f1, f2, s;<br /> fso = new ActiveXObject("Scripting.FileSystemObject");<br /> f1 = fso.CreateTextFile("c:\\testfile.txt", true);<br /> Response.Write("Writing file <br>");<br /> // 写一行。<br /> f1.Write("This is a test.");<br /> // 关闭文件。<br /> f1.Close();<br /> Response.Write("Moving file to c:\\tmp <br>");<br /> // 获取 C 的根目录(C:\)中的文件的句柄。<br /> f2 = fso.GetFile("c:\\testfile.txt");<br /> // 把文件移动到 \tmp 目录。<br /> f2.Move ("c:\\tmp\\testfile.txt");<br /> Response.Write("Copying file to c:\\temp <br>");<br /> // 把文件复制到 \temp 目录。<br /> f2.Copy ("c:\\temp\\testfile.txt");<br /> Response.Write("Deleting files <br>");<br /> // 获得文件当前位置的句柄。<br /> f2 = fso.GetFile("c:\\tmp\\testfile.txt");<br /> f3 = fso.GetFile("c:\\temp\\testfile.txt");<br /> // 删除文件。<br /> f2.Delete();<br /> f3.Delete();<br /> Response.Write("All done!");<br />}<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-115078027517435653?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com1tag:blogger.com,1999:blog-20264575.post-759763120570836382006-06-19T14:45:00.000+08:002008-01-31T16:38:13.577+08:00prototype.js 1.4版开发者手册(强烈推荐)<h3>prototype.js是什么?</h3><br /><p>万一你没有使用过大名鼎鼎的prototype.js,那么让我来告诉你,prototype.js是由Sam Stephenson写的一个javascript类库。这个构思奇妙,而且兼容标准的类库,能帮助你轻松建立有高度互动的web2.0特性的富客户端页面。</p><br /><p>如果你最近尝试使用它,你大概了解到文档并不是作者的一个强项。和在我以前使用这个类库的不少开发者一样,一开始,我不得不一头扎进阅读prototype.js的源代码和实验它的功能中。我想,在我学习完它之后,把我学到的东西分享给大家是件不错的事。 </p><br /><p>同时,在本文中,我也将提供一个关于这个类库提供的objects,classes,functions,extensions这对东东的非官方参考</p><br /><p>在阅读这个文档时,熟悉Ruby的开发者将会注意到Ruby的一些内建类和本类库扩展实现之间非常相似。 </p><br /><h3>相关文章</h3><br /><p>Advanced JavaScript guide. </p><!-- ************************************************************************************************************************************* --><br /><h3>一些实用的函数</h3><br /><p>这个类库带有很多预定义的对象和实用函数,这些东东的目的显然是把你从一些重复的打字中解放出来 。 </p><!-- ------------------------------------------------------------------------------------------- --><br /><h4>使用$()方法</h4><br /><p>$() 方法是在DOM中使用过于频繁的 document.getElementById() 方法的一个便利的简写,就像这个DOM方法一样,这个方法返回参数传入的id的那个元素。</p><br /><p>比起DOM中的方法,这个更胜一筹。你可以传入多个id作为参数然后 $() 返回一个带有所有要求的元素的一个 Array 对象。</p><pre class="programlisting">&lt;HTML&gt;<br />&lt;HEAD&gt;<br />&lt;TITLE&gt; Test Page &lt;/TITLE&gt;<br />&lt;script src="prototype-1.3.1.js"&gt;&lt;/script&gt;<br />&lt;script&gt;<br />function test1()<br />{<br />var d = $('myDiv');<br />alert(d.innerHTML);<br />}<br />function test2()<br />{<br />var divs = $('myDiv','myOtherDiv');<br />for(i=0; i&lt;divs.length; i++)<br />{<br />alert(divs[i].innerHTML);<br />}<br />}<br />&lt;/script&gt;<br />&lt;/HEAD&gt;<br />&lt;BODY&gt;<br />&lt;div id="myDiv"&gt;<br />&lt;p&gt;This is a paragraph&lt;/p&gt;<br />&lt;/div&gt;<br />&lt;div id="myOtherDiv"&gt;<br />&lt;p&gt;This is another paragraph&lt;/p&gt;<br />&lt;/div&gt;<br />&lt;input type="button" value=Test1 onclick="test1();"&gt;&lt;br&gt;<br />&lt;input type="button" value=Test2 onclick="test2();"&gt;&lt;br&gt;<br />&lt;/BODY&gt;<br />&lt;/HTML&gt;</pre><br /><p>另外一个好处是,这个函数能传入用string表示的对象ID,也可以传入对象本身,这样,在建立其它能传两种类型的参数的函数时非常有用。</p><!-- ------------------------------------------------------------------------------------------- --><br /><h4>使用$F()函数</h4><br /><p>$F()函数是另一个大收欢迎的“快捷键”,它能用于返回任何表单输入控件的值,比如text box,drop-down list。这个方法也能用元素id或元素本身做为参数。 </p><pre class="code">&lt;script&gt;<br />function test3()<br />{<br />alert( <span class="highlite">$F('userName')</span> );<br />}<br />&lt;/script&gt;<br />&lt;input type="text" id="userName" value="Joe Doe"&gt;&lt;br&gt;<br />&lt;input type="button" value=Test3 onclick="test3();"&gt;&lt;br&gt;<br /><!-- ------------------------------------------------------------------------------------------- --></pre><br /><h4>使用<span class="functionName">$A()</span>函数</h4><br /><p>$A()函数能把它接收到的单个的参数转换成一个Array对象。</p><br /><p>这个方法,结合被本类库扩展了的Array类,能方便的把任何的可枚举列表转换成或拷贝到一个Array对象。一个推荐的用法就是把DOM Node Lists转换成一个普通的Array对象,从而更有效率的进行遍历,请看下面的例子。</p><pre class="code">&lt;script&gt;<br />function showOptions(){<br />var someNodeList = $('lstEmployees').getElementsByTagName('option');<br />var nodes = $A(someNodeList);<br />nodes.each(function(node){<br />alert(node.nodeName + ': ' + node.innerHTML);<br />});<br />}<br />&lt;/script&gt;<br />&lt;select id="lstEmployees" size="10" &gt;<br />&lt;option value="5"&gt;Buchanan, Steven&lt;/option&gt;<br />&lt;option value="8"&gt;Callahan, Laura&lt;/option&gt;<br />&lt;option value="1"&gt;Davolio, Nancy&lt;/option&gt;<br />&lt;/select&gt;<br />&lt;input type="button" value="Show the options" onclick="showOptions();" &gt;<br /></pre><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>使用 <span class="functionName">$H()</span> 函数</h4><br /><p>$H()函数把一些对象转换成一个可枚举的和联合数组类似的Hash对象。</p><pre class="code">&lt;script&gt;<br />function testHash()<br />{<br />//let's create the object<br />var a = {<br />first: 10,<br />second: 20,<br />third: 30<br />};<br />//now transform it into a hash<br />var h = <span class="highlite">$H(a)</span>;<br />alert(h.toQueryString()); //displays: first=10&amp;second=20&amp;third=30<br />}<br />&lt;/script&gt;<br /></pre><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>使用<span class="functionName">$R()</span>函数</h4><br /><p>$R()是new ObjectRange(lowBound,upperBound,excludeBounds)的缩写。</p><br /><p>跳到ObjectRange 类文档可以看到一个关于此类的完整描述. 此时,我们还是先来看一个例子以展示这个缩写能代替哪些方法吧。其它相关的一些知识可以在Enumerable 对象文档中找到。</p><pre class="code">&lt;script&gt;<br />function demoDollar_R(){<br />var range = <span class="highlite">$R(10, 20, false)</span>;<br />range.each(function(value, index){<br />alert(value);<br />});<br />}<br />&lt;/script&gt;<br />&lt;input type="button" value="Sample Count" onclick="demoDollar_R();" &gt;<br /></pre><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>使用<span class="functionName">Try.these()</span>函数</h4><br /><p><tt class="literal">Try.these()</tt> 方法使得实现当你想调用不同的方法直到其中的一个成功正常的这种需求变得非常容易, 他把一系列的方法作为参数并且按顺序的一个一个的执行这些方法直到其中的一个成功执行,返回成功执行的那个方法的返回值。</p><br /><p>在下面的例子中, <tt class="literal">xmlNode.text</tt>在一些浏览器中好用,但是<tt class="literal">xmlNode.textContent</tt>在另一些浏览器中正常工作。 使用<tt class="literal">Try.these()</tt>方法我们可以得到正常工作的那个方法的返回值。</p><br /><p>&lt;script&gt;<br />function getXmlNodeValue(xmlNode){<br />return Try.these(<br />function() {return xmlNode.text;},<br />function() {return xmlNode.textContent;)<br />);<br />}<br />&lt;/script&gt;<br /></p><br /><p><!-- ************************************************************************************************************************************* --></p><br /><h3><span class="objectClass">Ajax</span>对象</h3><br /><p>上面提到的共通方法非常好,但是面对它吧,它们不是最高级的那类东西。它们是吗?你很可能自己编写了这些甚至在你的脚本里面有类似功能的方法。但是这些方法只是冰山一角。</p><br /><p>我很肯定你对prototype.js感兴趣的原因很可能是由于它的AJAX能力。所以让我们解释当你需要完成AJAX逻辑的时候,这个包如何让它更容易。</p><br /><p><tt class="literal">Ajax</tt> 对象是一个预定义对象,由这个包创建,为了封装和简化编写AJAX 功能涉及的狡猾的代码。 这个对象包含一系列的封装AJAX逻辑的类。我们来看看其中几个类。<!-- ------------------------------------------------------------------------------------------- --><br /><h4>使用<span class="objectClass">Ajax.Request</span>类</h4><br /><p>如果你不使用任何的帮助程序包,你很可能编写了整个大量的代码来创建<tt class="literal">XMLHttpRequest</tt>对象并且异步的跟踪它的进程, 然后解析出响应 然后处理它。当你不需要支持多于一种类型的浏览器时你会感到非常的幸运。</p><br /><p>为了支持 AJAX 功能。这个包定义了 <tt class="literal">Ajax.Request </tt>类。</p><br /><p>假如你有一个应用程序可以通过url <span class="emphasis"><em>http://yoursever/app/get_sales?empID=1234&amp;year=1998</em></span>与服务器通信。它返回下面这样的XML 响应。</p><pre class="code">&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />&lt;ajax-response&gt;<br />&lt;response type="object" id="productDetails"&gt;<br />&lt;monthly-sales&gt;<br />&lt;employee-sales&gt;<br />&lt;employee-id&gt;1234&lt;/employee-id&gt;<br />&lt;year-month&gt;1998-01&lt;/year-month&gt;<br />&lt;sales&gt;$8,115.36&lt;/sales&gt;<br />&lt;/employee-sales&gt;<br />&lt;employee-sales&gt;<br />&lt;employee-id&gt;1234&lt;/employee-id&gt;<br />&lt;year-month&gt;1998-02&lt;/year-month&gt;<br />&lt;sales&gt;$11,147.51&lt;/sales&gt;<br />&lt;/employee-sales&gt;<br />&lt;/monthly-sales&gt;<br />&lt;/response&gt;<br />&lt;/ajax-response&gt;<br /></pre><br /><p>用 <tt class="literal">Ajax.Request</tt>对象和服务器通信并且得到这段XML是非常简单的。下面的例子演示了它是如何完成的。</p><pre class="code">&lt;script&gt;<br />function searchSales()<br />{<br />var empID = $F('lstEmployees');<br />var y = $F('lstYears');<br />var url = 'http://yoursever/app/get_sales';<br />var pars = 'empID=' + empID + '&amp;year=' + y;<br /><div class="highlite"><br />var myAjax = new Ajax.Request(<br />url,<br />{<br />method: 'get',<br />parameters: pars,<br />onComplete: showResponse<br />});<br /></div><br />}<br />function showResponse(originalRequest)<br />{<br />//put returned XML in the textarea<br />$('result').value = originalRequest.responseText;<br />}<br />&lt;/script&gt;<br />&lt;select id="lstEmployees" size="10" onchange="searchSales()"&gt;<br />&lt;option value="5"&gt;Buchanan, Steven&lt;/option&gt;<br />&lt;option value="8"&gt;Callahan, Laura&lt;/option&gt;<br />&lt;option value="1"&gt;Davolio, Nancy&lt;/option&gt;<br />&lt;/select&gt;<br />&lt;select id="lstYears" size="3" onchange="searchSales()"&gt;<br />&lt;option selected="selected" value="1996"&gt;1996&lt;/option&gt;<br />&lt;option value="1997"&gt;1997&lt;/option&gt;<br />&lt;option value="1998"&gt;1998&lt;/option&gt;<br />&lt;/select&gt;<br />&lt;br&gt;&lt;textarea id=result cols=60 rows=10 &gt;&lt;/textarea&gt;<br /></pre><br /><p>你注意到传入 <tt class="literal">Ajax.Request</tt>构造方法的第二个对象了吗? 参数<tt class="literal">{method: 'get', parameters: pars, onComplete: showResponse}</tt> 表示一个匿名对象的真实写法。他表示你传入的这个对象有一个名为 <tt class="literal">method</tt> 值为 <tt class="literal">'get'的属性,</tt>另一个属性名为 <tt class="literal">parameters</tt> 包含HTTP请求的查询字符串,和一个<tt class="literal">onComplete</tt> 属性/方法包含函数<tt class="literal">showResponse</tt>。 </p><br /><p>还有一些其它的属性可以在这个对象里面定义和设置,如 <tt class="literal">asynchronous</tt>,可以为<tt class="literal">true</tt> 或 <tt class="literal">false</tt> 来决定AJAX对服务器的调用是否是异步的(默认值是 <tt class="literal">true</tt>)。</p><br /><p>这个参数定义AJAX调用的选项。在我们的例子中,在第一个参数通过HTTP GET命令请求那个url,传入了变量 <tt class="literal">pars</tt>包含的查询字符串, <tt class="literal">Ajax.Request </tt>对象在它完成接收响应的时候将调用<tt class="literal">showResponse</tt> 方法。</p><br /><p>也许你知道, <tt class="literal">XMLHttpRequest</tt>在HTTP请求期间将报告进度情况。这个进度被描述为四个不同阶段:<span class="emphasis"><em>Loading</em></span>, <span class="emphasis"><em>Loaded</em></span>, <span class="emphasis"><em>Interactive</em></span>, 或 <span class="emphasis"><em>Complete</em></span>。你可以使 <tt class="literal">Ajax.Request</tt> 对象在任何阶段调用自定义方法 ,<span class="emphasis"><em>Complete</em></span> 是最常用的一个。想调用自定义的方法只需要简单的在请求的选项参数中的名为 <tt class="literal">onXXXXX</tt> 属性/方法中提供自定义的方法对象。 就像我们例子中的 <tt class="literal">onComplete</tt> 。你传入的方法将会被用一个参数调用,这个参数是 <tt class="literal">XMLHttpRequest</tt> 对象自己。你将会用这个对象去得到返回的数据并且或许检查包含有在这次调用中的HTTP结果代码的 <tt class="literal">status</tt> 属性。</p><br /><p>还有另外两个有用的选项用来处理结果。我们可以在<tt class="literal">onSuccess</tt> 选项处传入一个方法,当AJAX无误的执行完后调用, 相反的,也可以在<tt class="literal">onFailure</tt>选项处传入一个方法,当服务器端出现错误时调用。正如<tt class="literal">onXXXXX</tt> 选项传入的方法一样,这两个在被调用的时候也传入一个带有AJAX请求的<tt class="literal">XMLHttpRequest对象。</tt></p><br /><p>我们的例子没有用任何有趣的方式处理这个 XML响应, 我们只是把这段XML放进了一个文本域里面。对这个响应的一个典型的应用很可能就是找到其中的想要的信息,然后更新页面中的某些元素, 或者甚至可能做某些XSLT转换而在页面中产生一些HTML。</p><br /><p>在1.4.0版本中,一种新的事件回传外理被引入。如果你有一段代码总是要为一个特殊的事件执行,而不管是哪个AJAX调用引发它,那么你可以使用新的Ajax.Responders对象。</p><br /><p>假设你想要在一个AJAX调用正在运行时,显示一些提示效果,像一个不断转动的图标之类的,你可以使用两个全局事件Handler来做到,其中一个在第一个调用开始时显示图标,另一个在最后一个调用完成时隐藏图标。看下面的例子。</p><pre class="code">&lt;script&gt;<br />var myGlobalHandlers = {<br />onCreate: function(){<br />Element.show('systemWorking');<br />},<br />onComplete: function() {<br />if(Ajax.activeRequestCount == 0){<br />Element.hide('systemWorking');<br />}<br />}<br />};<br /><span class="highlite">Ajax.Responders.register(myGlobalHandlers);</span><br />&lt;/script&gt;<br />&lt;div id='systemWorking'&gt;&lt;img src='spinner.gif'&gt;Loading...&lt;/div&gt;<br /></pre><br /><p>更完全的解释,请参照 Ajax.Request 参考 和 Ajax选项参考。</p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>使用<span class="objectClass">Ajax.Updater</span>类</h4><br /><p>如果你的服务器的另一端返回的信息已经是HTML了,那么使用这个程序包中 <tt class="literal">Ajax.Updater</tt> 类将使你的生活变得更加得容易。用它你只需提供哪一个元素需要被AJAX请求返回的HTML填充就可以了,例子比我写说明的更清楚。 </p><pre class="code">&lt;script&gt;<br />function getHTML()<br />{<br />var url = 'http://yourserver/app/getSomeHTML';<br />var pars = 'someParameter=ABC';<br /><div class="highlite"><br />var myAjax = new Ajax.Updater(<br />'placeholder',<br />url,<br />{<br />method: 'get',<br />parameters: pars<br />});<br /></div><br />}<br />&lt;/script&gt;<br />&lt;input type=button value=GetHtml onclick="getHTML()"&gt;<br />&lt;div id="placeholder"&gt;&lt;/div&gt;<br /></pre><br /><p>你可以看到,这段代码比前面的例子更加简洁,不包括 <tt class="literal">onComplete</tt> 方法,但是在构造方法中传入了一个元素id。 我们来稍稍修改一下代码来描述如何在客户端处理服务器段错误成为可能。</p><br /><p>我们将加入更多的选项, 指定处理错误的一个方法。这个是用 <tt class="literal">onFailure</tt> 选项来完成的。我们也指定了一个 <tt class="literal">placeholder</tt> 只有在成功请求之后才会被填充。为了完成这个目的我们修改了第一个参数从一个简单的元素id到一个带有两个属性的对象, <tt class="literal">success</tt> (一切OK的时候被用到) 和 <tt class="literal">failure</tt> (有地方出问题的时候被用到) 在下面的例子中没有用到<tt class="literal">failure</tt>属性,而仅仅在 <tt class="literal">onFailure</tt> 处使用了 <tt class="literal">reportError</tt> 方法。</p><br /><p>&lt;script&gt;<br />function getHTML()<br />{<br />var url = 'http://yourserver/app/getSomeHTML';<br />var pars = 'someParameter=ABC';<br /></p><pre class="code"><div class="highlite"><br />var myAjax = new Ajax.Updater(<br />{success: 'placeholder'},<br />url,<br />{<br />method: 'get',<br />parameters: pars,<br />onFailure: reportError<br />});<br /></div><br />}<br />function reportError(request)<br />{<br />alert('Sorry. There was an error.');<br />}<br />&lt;/script&gt;<br />&lt;input type=button value=GetHtml onclick="getHTML()"&gt;<br />&lt;div id="placeholder"&gt;&lt;/div&gt;<br /></pre><br /><p>如果你的服务器逻辑是连同HTML 标记返回JavaScript 代码, <tt class="literal">Ajax.Updater</tt>对象可以执行那段JavaScript代码。为了使这个对象对待响应为JavaScript,你只需在最后参数的对象构造方法中简单加入<tt class="literal">evalScripts: true</tt>属性。但是值得提醒的是,像这个选项名evalScripts暗示的,这些脚本会被执行,但是它们不会被加入到Page的脚本中。“有什么区别?”,可能你会这样问。我们假定请求地址返回的东东像这样:</p><pre class="code">&lt;script language="javascript" type="text/javascript"&gt;<br />function sayHi(){<br />alert('Hi');<br />}<br />&lt;/script&gt;<br />&lt;input type=button value="Click Me" onclick="sayHi()"&gt;<br /></pre><br /><p>如果你以前这样尝试过,你知道这些脚本不会如你所期望的那样工作,原因是这段脚本会被执行,但像上面这样的脚本执行并不会创建一个名叫sayHi的函数,它什么也不做。如果要创建一个函数,我们应当把代码改成下面这个样子:</p><pre class="code">&lt;script language="javascript" type="text/javascript"&gt;<br /><div class="highlite">sayHi = function(){<br />alert('Hi');<br />};</div><br />&lt;/script&gt;<br />&lt;input type=button value="Click Me" onclick="sayHi()"&gt;<br /></pre><br /><p>为什么我们在上面的代码中不使用var关键字来声明这个变量呢(指sayHi ),因为那样做创建出来的函数将只是当前脚本块的一个局部变量(至少在IE中是这样)。不写var关键字,创建出来的对象的作用域就是我们所期望的window。</p><br /><p>更多相关知识,请参看 Ajax.Updater reference 和options reference. </p><br /><h3>枚举... 噢!噢!</h3><br /><p>你知道,我们都是这样来做循环的,建一个Array,用elements组织它们,再建一个循环结构(例如for,foreach,while)通过index数字来访问每一个element,再用这个element做一些动作。 </p><br /><p>当你想到这时,你会发现几乎每次写循环代码你都会迟早用到一个Array。那么,如果Array对象能够提供更多的功能给它们的迭代器使用不是很爽吗?确实是这样,事实上很多的编程语言都在它们的Array或其它类似的结构中(如Collections,Lists)提供一些这样的功能。 </p><br /><p>现在好了,prototype.js了给我们一个 Enumerable对象,它实现了很多和可迭代数据进行交互的窍门。和原有的JS对象相比prototype.js更上一层楼,它对<span class="code">Array</span> 类s扩展了所有枚举要用的函数。 </p><br /><h4>循环, Ruby样式的</h4><br /><p>在标准的javascript中,如果你想把一个array中的所有elements显示出来,你可以像下面代码这样写得很好: </p><pre class="code">&lt;script&gt;<br />function showList(){<br />var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg'];<br /><div class="highlite"> for(i=0;i&lt;simpsons.length;i++){<br />alert(simpsons[i]);<br />}</div><br />}<br />&lt;/script&gt;<br />&lt;input type="button" value="Show List" onclick="showList();" &gt;<br /></pre><br /><p>使用我们新的最好的朋友,prototype.js,我们可以把它生写成这样 </p><pre class="code"> function showList(){<br />var simpsons = ['Homer', 'Marge', 'Lisa', 'Bart', 'Meg'];<br /><div class="highlite"> simpsons.each( function(familyMember){<br />alert(familyMember);<br />});</div><br />}<br /></pre><br /><p>你可能会想“非常奇怪的方式...相对旧的,这种语法太怪异了”。哦,在上面的例子,确实什么也没有,在这个简单得要死例子中,也没有改变太多啊,尽管如此,请继续读下去。 </p><br /><p>在继续下面内容之前,你注意到那个被做为一个参数传递给each函数的函数?我们把它理解成迭代器函数。 </p><br /><h4>Your arrays on steroids</h4><br /><p>就如我们上面提到的,把你的Array中的elements当成相同的类型使用相同的属性和函数是很通用(Common,不知该翻译成通用还是庸俗)的。让我们看看怎么样利用我们新的马力强劲的Arrays的迭代功能吧。 </p><br /><p>依照标准找到一个element。<br /><p><pre class="code">&lt;script&gt;<br />function findEmployeeById(emp_id){<br />var listBox = $('lstEmployees')<br />var options = listBox.getElementsByTagName('option');<br />options = $A(options);<br />var opt = options.<span class="highlite">find</span>( <strong>function(employee){<br />return <span class="highlite">(employee.value == emp_id)</span>;<br />}</strong>);<br />alert(opt.innerHTML); //displays the employee name<br />}<br />&lt;/script&gt;<br />&lt;select id="lstEmployees" size="10" &gt;<br />&lt;option value="5"&gt;Buchanan, Steven&lt;/option&gt;<br />&lt;option value="8"&gt;Callahan, Laura&lt;/option&gt;<br />&lt;option value="1"&gt;Davolio, Nancy&lt;/option&gt;<br />&lt;/select&gt;<br />&lt;input type="button" value="Find Laura" onclick="findEmployeeById(8);" &gt;<br /></pre><br /><p>现在我们再下一城,看看如何过滤一个Array中的元素,从每个元素中得到我们想要的成员。<br /><p><pre class="code">&lt;script&gt;<br />function showLocalLinks(paragraph){<br />paragraph = $(paragraph);<br />var links = $A(paragraph.getElementsByTagName('a'));<br />//find links that do not start with 'http'<br />var localLinks = links.<span class="highlite">findAll</span>( function(link){<br />var start = link.href.substring(0,4);<br />return start !='http';<br />});<br />//now the link texts<br />var texts = localLinks.<span class="highlite">pluck('innerHTML')</span>;<br />//get them in a single string<br />var result = texts.<span class="highlite">inspect()</span>;<br />alert(result);<br />}<br />&lt;/script&gt;<br />&lt;p id="someText"&gt;<br />This &lt;a href="http://othersite.com/page.html"&gt;text&lt;/a&gt; has<br />a &lt;a href="#localAnchor"&gt;lot&lt;/a&gt; of<br />&lt;a href="#otherAnchor"&gt;links&lt;/a&gt;. Some are<br />&lt;a href="http://wherever.com/page.html"&gt;external&lt;/a&gt;<br />and some are &lt;a href="#someAnchor"&gt;local&lt;/a&gt;<br />&lt;/p&gt;<br />&lt;input type=button value="Find Local Links" onclick="showLocalLinks('someText')"&gt;<br /></pre><br /><p>上面的代码仅仅是一点小小的实践让人爱上这种语法。请参看 Enumerable和Array的所有函数 </p><br /><p><!-- ************************************************************************************************************************************* --></p><br /><hr /><br /><br /><p></p><br /><h3>prototype.js参考</h3><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>JavaScript类扩展</h4><br /><p>prototype.js 类库实现强大功能的一种途径是扩展已有的JavaScript 类。 </p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>对 <span class="code">Object的扩展</span></h4><br /><p><br /><table class="reference" id="Table1" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>extend(destination, source)</td><br /><td><nobr>static</nobr></td><br /><td>destination: any object, source: any object</td><br /><td class="refDescription">提供一种通过拷贝所有源以象属性和函数到目标函数实现继承的方法</td></tr><br /><tr><br /><td>inspect(targetObj)</td><br /><td>static</td><br /><td>targetObj: any object</td><br /><td class="refDescription">返回可读性好关于目标对象的文字描述,如果对象实例没有定义一个inspect函数,默认返回toString函数的值。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4><span class="code">对Number的扩展</span></h4><br /><p><br /><table class="reference" id="Table2" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th><nobr>Kind</nobr></th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>toColorPart()</td><br /><td><nobr>instance</nobr></td><br /><td>(none)</td><br /><td class="refDescription">返回数字的十六进制表示形式。在把一个RGB数字转换成HTML表现形式时很有用。</td></tr><br /><tr><br /><td>succ()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回下一个数字,这个方法可用于迭代调用场景中。 </td></tr><br /><tr><br /><td>times(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(index)</td><br /><td class="refDescription">Calls the <span class="code">iterator</span> function repeatedly passing the current index in the <span class="code">index</span> argument. 反复调用iterator函数并传递当前index到iterator的index参数。 </td></tr></tbody></table></p><br /><p>下面的例子用提示框显示0-9。 </p><pre class="code">&lt;script&gt;<br />function demoTimes(){<br />var n = 10;<br />n.times(function(index){<br />alert(index);<br />});<br />/***************************<br />* you could have also used:<br />* (10).times( .... );<br />***************************/<br />}<br />&lt;/script&gt;<br />&lt;input type=button value="Test Number.times()" onclick="demoTimes()"&gt;<br /></pre><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>对 <span class="code">Function扩展</span></h4><br /><p><br /><table class="reference" id="Table3" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>bind(object)</td><br /><td><nobr>instance</nobr></td><br /><td>object: the object that owns the method</td><br /><td class="refDescription">返回function的实例,这个实例和源function的结构一样,但是它已被绑定给了参数中提供的object,就是说,function中的this指针指向参数object。</td></tr><br /><tr><br /><td>bindAsEventListener(object)</td><br /><td>instance</td><br /><td>object: the object that owns the method</td><br /><td class="refDescription">用法和上面的bind一样,区别在于用来绑定事件。</td></tr></tbody></table></p><br /><p>让我们看看如何运用这些扩展。 </p><pre class="code">&lt;input type=checkbox id=myChk value=1&gt; Test?<br />&lt;script&gt;<br />//declaring the class<br />var CheckboxWatcher = Class.create();<br />//defining the rest of the class implementation<br />CheckboxWatcher.prototype = {<br />initialize: function(chkBox, message) {<br />this.chkBox = $(chkBox);<br />this.message = message;<br />//assigning our method to the event<br /><div class="highlite"><br />this.chkBox.onclick =<br />this.showMessage.bindAsEventListener(this);<br /></div><br />},<br />showMessage: function(evt) {<br />alert(this.message + ' (' + evt.type + ')');<br />}<br />};<br />var watcher = new CheckboxWatcher('myChk', 'Changed');<br />&lt;/script&gt;<br /></pre><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4><span class="code">对String的扩展</span></h4><br /><p><br /><table class="reference" id="Table4" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>stripTags()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回一个把所有的HTML或XML标记都移除的字符串。</td></tr><br /><tr><br /><td>stripScripts()</td><br /><td><nobr>instance</nobr></td><br /><td>(none)</td><br /><td class="refDescription">返回一个把所有的script都移除的字符串。</td></tr><br /><tr><br /><td>escapeHTML()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回一个把所有的HTML标记合适的转义掉的字符串。</td></tr><br /><tr><br /><td>unescapeHTML()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription"><span class="code">escapeHTML()的反转。</span></td></tr><br /><tr><br /><td>extractScripts()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回一个包含在string中找到的所有&lt;script&gt;的数组。</td></tr><br /><tr><br /><td>evalScripts()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">执行在string中找到的所有&lt;script&gt;。</td></tr><br /><tr><br /><td>toQueryParams()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">把querystring分割才一个用parameter name做index的联合Array,更像一个hash。</td></tr><br /><tr><br /><td>parseQuery()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription"><span class="code">和toQueryParams()一样</span>.</td></tr><br /><tr><br /><td>toArray()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">把字符串转换成字符数组.</td></tr><br /><tr><br /><td>camelize()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">转换一个以连字符连接的字符串成一个骆驼法样式的字符串。比如,这个函数在写代码时,把它做为一个样式工具使用是很有用的。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>对 <span class="code">Array</span>的扩展</h4><br /><p>因为array扩展于enumerable,所以所有enumberable对象的函数,array都是可以使用的,除此之外,下面的这些也是已经实现了的。 </p><br /><p><br /><table class="reference" id="Table5" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>clear()</td><br /><td><nobr>instance</nobr></td><br /><td>(none)</td><br /><td class="refDescription">清空。</td></tr><br /><tr><br /><td>compact()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回一个不包括源array中null或undefined元素的array,此方法不改变源array。</td></tr><br /><tr><br /><td>first()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回array的第一个对象。</td></tr><br /><tr><br /><td>flatten()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">通过递归组合array每个元素的子元素(如果该元素也是array)来返回一个“扁平的”一维的array。</td></tr><br /><tr><br /><td>indexOf(value)</td><br /><td>instance</td><br /><td>value: what you are looking for.</td><br /><td class="refDescription">返回给出数字位置(从0算起)的元素,如果在该位置没有找到对象,返回-1。 </td></tr><br /><tr><br /><td>inspect()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">重载inspect(),返回更好格式的反映Array每个元素的字符描述。</td></tr><br /><tr><br /><td>last()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回最后一个元素。</td></tr><br /><tr><br /><td>reverse([applyToSelf])</td><br /><td>instance</td><br /><td>applyToSelf: indicates if the array itself should also be reversed.</td><br /><td class="refDescription">反转Array中元素的顺序,如果没有给出参数,或参数为true,则源Array中元素的顺序也反转,否则源Array保持不变。 </td></tr><br /><tr><br /><td>shift()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回Array的第一个元素并从Array中移除它,Array的Length-1。</td></tr><br /><tr><br /><td>without(value1 [, value2 [, .. valueN]])</td><br /><td>instance</td><br /><td>value1 ... valueN: values to be excluded if present in the array.</td><br /><td class="refDescription">返回一个把参数列表中包含的元素从源Array中排除的Array。 </td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4><span class="code">document</span> DOM扩展</h4><br /><p><br /><table class="reference" id="Table6" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>getElementsByClassName(className [, parentElement])</td><br /><td><nobr>instance</nobr></td><br /><td>className: name of a CSS class associated with the elements, parentElement: object or id of the element that contains the elements being retrieved.</td><br /><td class="refDescription">返回所有CSS className属性等于className参数的元素,如果没有给出parentElement,那么将搜索document body。(此处使用document.body我觉得不如使用document,因为有时有的页面没有body) </td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4><span class="code">Event</span>扩展</h4><br /><p><br /><table class="reference" id="Table7" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Description</th></tr><br /><tr><br /><td>KEY_BACKSPACE</td><br /><td><nobr>Number</nobr>Number</td><br /><td class="refDescription">8: Constant. Code for the Backspace key.</td></tr><br /><tr><br /><td>KEY_TAB</td><br /><td>Number</td><br /><td class="refDescription">9: Constant. Code for the Tab key.</td></tr><br /><tr><br /><td>KEY_RETURN</td><br /><td>Number</td><br /><td class="refDescription">13: Constant. Code for the Return key.</td></tr><br /><tr><br /><td>KEY_ESC</td><br /><td>Number</td><br /><td class="refDescription">27: Constant. Code for the Esc key.</td></tr><br /><tr><br /><td>KEY_LEFT</td><br /><td>Number</td><br /><td class="refDescription">37: Constant. Code for the Left arrow key.</td></tr><br /><tr><br /><td>KEY_UP</td><br /><td>Number</td><br /><td class="refDescription">38: Constant. Code for the Up arrow key.</td></tr><br /><tr><br /><td>KEY_RIGHT</td><br /><td>Number</td><br /><td class="refDescription">39: Constant. Code for the Right arrow key.</td></tr><br /><tr><br /><td>KEY_DOWN</td><br /><td>Number</td><br /><td class="refDescription">40: Constant. Code for the Down arrow key.</td></tr><br /><tr><br /><td>KEY_DELETE</td><br /><td>Number</td><br /><td class="refDescription">46: Constant. Code for the Delete key.</td></tr><br /><tr class="privateMember"><br /><td>observers:</td><br /><td>Array</td><br /><td class="refDescription">List of cached observers. Part of the internal implementation details of the object.</td></tr></tbody></table></p><br /><p><br /><table class="reference" id="Table8" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>element(event)</td><br /><td>static</td><br /><td>event: an Event object</td><br /><td class="refDescription">返回事件源对象。</td></tr><br /><tr><br /><td>isLeftClick(event)</td><br /><td>static</td><br /><td>event: an Event object</td><br /><td class="refDescription">如果点击了鼠标左键,返回true.</td></tr><br /><tr><br /><td>pointerX(event)</td><br /><td>static</td><br /><td>event: an Event object</td><br /><td class="refDescription">返回鼠标的X座标。 </td></tr><br /><tr><br /><td>pointerY(event)</td><br /><td>static</td><br /><td>event: an Event object</td><br /><td class="refDescription">返回鼠标的Y座标。</td></tr><br /><tr><br /><td>stop(event)</td><br /><td>static</td><br /><td>event: an Event object</td><br /><td class="refDescription">使用此函数来中断事件的默认行为并阻止传递(冒泡)。</td></tr><br /><tr><br /><td>findElement(event, tagName)</td><br /><td>static</td><br /><td>event: an Event object, tagName: name of the desired tag.</td><br /><td class="refDescription">从事件源对象开始向上搜索DOM树,直到找到第一个符合tagName的元素</td></tr><br /><tr><br /><td>observe(element, name, observer, useCapture)</td><br /><td>static</td><br /><td>element: object or id, name: event name (like 'click', 'load', etc), observer: function to handle the event, useCapture: if <span class="code">true</span>, handles the event in the <em>capture</em> phase and if <span class="code">false</span> in the <em>bubbling</em> phase.</td><br /><td class="refDescription">为对象的某个事件增加一个处理函数。</td></tr><br /><tr><br /><td>stopObserving(element, name, observer, useCapture)</td><br /><td>static</td><br /><td>element: object or id, name: event name (like 'click'), observer: function that is handling the event, useCapture: if true handles the event in the <em>capture</em> phase and if false in the <em>bubbling</em> phase.</td><br /><td class="refDescription">和上面的函数相反。</td></tr><br /><tr class="privateMember"><br /><td>_observeAndCache(element, name, observer, useCapture)</td><br /><td>static</td><br /><td></td><br /><td class="refDescription">私有函数,别管它。</td></tr><br /><tr class="privateMember"><br /><td>unloadCache()</td><br /><td><nobr>static</nobr></td><br /><td>(none)</td><br /><td class="refDescription">私有函数,别管它。从内存中清除所有的observers缓存。</td></tr></tbody></table></p><br /><p>下面代码演示如何给window添加一个load事件处理函数。 </p><pre class="code">&lt;script&gt;<br /><span class="highlite">Event.observe(window, 'load', showMessage, false);</span><br />function showMessage() {<br />alert('Page loaded.');<br />}<br />&lt;/script&gt;<br /></pre><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>在prototype.js中定义新的对象和类</h4><br /><p>另一个这个程序包帮助你的地方就是提供许多既支持面向对象设计理念又有共通功能的许多对象。 </p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">PeriodicalExecuter</span> object</h4><br /><p>这个对象提供一定间隔时间上重复调用一个方法的逻辑。 </p><br /><p><br /><table class="reference" id="Table9" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>[ctor](callback, interval)</td><br /><td><nobr>constructor</nobr></td><br /><td>callback: a parameterless function, interval: number of seconds</td><br /><td class="refDescription">创建这个对象的实例将会重复调用给定的方法。</td></tr></tbody></table></p><br /><p><br /><table class="reference" id="Table10" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Description</th></tr><br /><tr><br /><td>callback</td><br /><td><nobr>Function()</nobr></td><br /><td class="refDescription">被调用的方法,该方法不能传入参数。</td></tr><br /><tr><br /><td>frequency</td><br /><td>Number</td><br /><td class="refDescription">以秒为单位的间隔。</td></tr><br /><tr class="privateMember"><br /><td>currentlyExecuting</td><br /><td>Boolean</td><br /><td class="refDescription">表示这个方法是否正在执行。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Prototype</span> object</h4><br /><p><tt class="literal">Prototype</tt> 没有太重要的作用,只是声明了该程序包的版本 。 </p><br /><p><br /><table class="reference" id="Table11" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Description</th></tr><br /><tr><br /><td>Version</td><br /><td>String</td><br /><td class="refDescription"><span style="font-family:宋体;">版本。</span></td></tr><br /><tr><br /><td>emptyFunction</td><br /><td><nobr>Function()</nobr></td><br /><td class="refDescription">空函数。</td></tr><br /><tr><br /><td>K</td><br /><td>Function(obj)</td><br /><td class="refDescription">一个仅仅回传参数的函数。</td></tr><br /><tr class="privateMember"><br /><td>ScriptFragment</td><br /><td>String</td><br /><td class="refDescription">识别script的正则式。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Enumerable</span> object</h4><br /><p>Enumberable对象能够已更优雅的方式实现对列表样式的结构进行枚举。 </p><br /><p>很多其它的对象通过扩展自Enumberable对象来得到这些有用的接口。</p><br /><p><br /><table class="reference" id="Table12" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>each(iterator)</td><br /><td><nobr>instance</nobr></td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">把每个element做为第一个参数,element的index作为第一个参数调用iterator函数。</td></tr><br /><tr><br /><td>all([iterator])</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">这个函数会用给出的iterator测试整个集合,如果集合中任一元素在iterator函数测试中返回false或null,那么这个函数返回false,否则返回true。如果没有给出iterator,那么就会测试所有的元素是不是不等于false和null。你可以简单的把它看成是“检测每个元素都为非空非负”。 </td></tr><br /><tr><br /><td>any(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index), optional.</td><br /><td class="refDescription">这个函数会用给出的iterator测试整个集合,如果集合中任一元素在iterator函数测试中返回true,那么这个函数返回true,否则返回false。如果没有给出iterator,那么就会测试所有的元素是不是有一个不等于false和null。你可以简单的把它看成是“检测元素中是不是有非空非负的”。 </td></tr><br /><tr><br /><td>collect(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">调用iterator函数根据集合中每个元素返回一个结果,然后按照原来集合中的顺序,返回一个Array。 </td></tr><br /><tr><br /><td>detect(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">集合中每个元素调用一次Iterator,返回第一个使Iterator返回True的元素,如果最终都没有为true的调用,那么返回null。 </td></tr><br /><tr><br /><td>entries()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription"><span class="code">等于toArray()</span>. </td></tr><br /><tr><br /><td>find(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">等于 <span class="code">detect()</span>. </td></tr><br /><tr><br /><td>findAll(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">集合中每个元素调用Iterator,返回一个由所有调用Iterator返回结果等于true的元素组成的数组。和reject()相反。 </td></tr><br /><tr><br /><td>grep(pattern [, iterator])</td><br /><td>instance</td><br /><td>pattern: a RegExp object used to match the elements, iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">用pattern参数正则表达式测试集合中的每个元素,返回一个包含所有匹配正则式的元素的Array,如果给出了Iterator,那个每个结果还要经过一下Iterator处理。 </td></tr><br /><tr><br /><td>include(obj)</td><br /><td>instance</td><br /><td>obj: any object</td><br /><td class="refDescription">判断集合中包不包含指定对象。 </td></tr><br /><tr><br /><td>inject(initialValue, iterator)</td><br /><td>instance</td><br /><td>initialValue: any object to be used as the initial value, iterator: a function object conforming to Function(accumulator, value, index)</td><br /><td class="refDescription">用Iterator联接所有集合中的元素。Iterator在被调用时把上一次迭代的结果做为第一个参数传给accumulator。第一次迭代时,accurmelator等于initialValue,最后返回accumulator的值。 </td></tr><br /><tr><br /><td>invoke(methodName [, arg1 [, arg2 [...]]])</td><br /><td>instance</td><br /><td>methodName: name of the method that will be called in each element, arg1..argN: arguments that will be passed in the method invocation.</td><br /><td class="refDescription">集合中的每个元素调用指定的函数(查看源代码可以发现指定函数被调用时,this指针被传成当前元素),并传入给出的参数,返回调用结果组成的Array。 </td></tr><br /><tr><br /><td>map(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription"><span class="code">同collect()</span>. </td></tr><br /><tr><br /><td>max([iterator])</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">返回集合中元素的最大值,或调用Iterator后返回值的最大值(如果给出了Iterator的话)。 </td></tr><br /><tr><br /><td>member(obj)</td><br /><td>instance</td><br /><td>obj: any object</td><br /><td class="refDescription">同 <span class="code">include()</span>. </td></tr><br /><tr><br /><td>min([iterator])</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">返回最小值,参见max()。 </td></tr><br /><tr><br /><td>partition([iterator])</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">返回一个包含两个Array的Array,第一个Array包含所有调用Iterator返回True的元素,第二个Array包含剩下的元素。如果Iterator没有给出,那么就根据元素本身判断。 </td></tr><br /><tr><br /><td>pluck(propertyName)</td><br /><td>instance</td><br /><td>propertyName name of the property that will be read from each element. This can also contain the index of the element</td><br /><td class="refDescription">返回每个元素的指定属性名的属性的值组成的Array。 </td></tr><br /><tr><br /><td>reject(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">和 <span class="code">findAll()相反(返回所有等于false的元素)</span>. </td></tr><br /><tr><br /><td>select(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">同 <span class="code">findAll()</span>. </td></tr><br /><tr><br /><td>sortBy(iterator)</td><br /><td>instance</td><br /><td>iterator: a function object conforming to Function(value, index)</td><br /><td class="refDescription">根据每个元素调用Iterator返回的值进行排序返回一个Array。 </td></tr><br /><tr><br /><td>toArray()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回由集合所有元素组成的一个Array。 </td></tr><br /><tr><br /><td>zip(collection1[, collection2 [, ... collectionN [,transform]]])</td><br /><td>instance</td><br /><td>collection1 .. collectionN: enumerations that will be merged, transform: a function object conforming to Function(value, index)</td><br /><td class="refDescription">合并每个给出的集合到当前集合。合并操作返回一个新的array,这个array的元素个数和原集合的元素个数一样,这个array的每个元素又是一个子array,它合并了所有集合中相同index的元素。如果transform函数被指定,那么array的每个元素还会调用transform函数先做处理。举个例子: [1,2,3].zip([4,5,6], [7,8,9]).inspect() 返回 "[ [1,4,7],[2,5,8],[3,6,9] ]" </td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Hash</span> object</h4><br /><p>Hash对象实现一种Hash结构,也就是一个Key:Value对的集合。 </p><br /><p>Hash中的每个Item是一个有两个元素的array,前一个是Key,后一个是Value,每个Item也有两个不需加以说明的属性,key和value。 </p><br /><p><br /><table class="reference" id="Table13" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>keys()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回所有Item的key的集合的一个array。 </td></tr><br /><tr><br /><td>values()</td><br /><td><nobr>instance</nobr></td><br /><td>(none)</td><br /><td class="refDescription">返回所有Item的value的集合的一个array。 </td></tr><br /><tr><br /><td>merge(otherHash)</td><br /><td>instance</td><br /><td>otherHash: Hash object</td><br /><td class="refDescription">合并给出的Hash,返回一个新Hash。 </td></tr><br /><tr><br /><td>toQueryString()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">以QueryString那样的样式返回hash中所有的item,例如: <span class="code">'key1=value1&amp;key2=value2&amp;key3=value3'</span> </td></tr><br /><tr><br /><td>inspect()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">用一种合适的方法显示hash中的key:value对。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">ObjectRange</span> class</h4><br /><p><em>继承自 Enumerable</em></p><br /><p>用上、下边界描述一个对象区域。 </p><br /><p><br /><table class="reference" id="Table14" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Kind</th><br /><th>Description</th></tr><br /><tr><br /><td>start</td><br /><td>(any)</td><br /><td><nobr>instance</nobr></td><br /><td class="refDescription"><br /><p>range的下边界</p></td></tr><br /><tr><br /><td>end</td><br /><td>(any)</td><br /><td>instance</td><br /><td class="refDescription">range的上边界</td></tr><br /><tr><br /><td>exclusive</td><br /><td>Boolean</td><br /><td>instance</td><br /><td class="refDescription">决定边界自身是不是range的一部分。</td></tr></tbody></table></p><br /><p><br /><table class="reference" id="Table15" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>[ctor](start, end, exclusive)</td><br /><td>constructor</td><br /><td>start: the lower bound, end: the upper bound, exclusive: include the bounds in the range?</td><br /><td class="refDescription">创建一个range对象,从start生成到end,这里要注意的是,start和end必段类型一致,而且该类型要有succ()方法。 </td></tr><br /><tr><br /><td>include(searchedValue)</td><br /><td><nobr>instance</nobr></td><br /><td>searchedValue: value that we are looking for</td><br /><td class="refDescription">检查一个value是不是在range中。 </td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Class</span> object</h4><br /><p>在这个程序包中 <tt class="literal">Class</tt> 对象在声明其他的类时候被用到 。用这个对象声明类使得新类支持 <tt class="literal">initialize()</tt> 方法,他起构造方法的作用。</p><br /><p>看下面的例子</p><br /><p>//declaring the class<br /><span class="highlite">var MySampleClass = Class.create();</span><br /><br />//defining the rest of the class implmentation<br />MySampleClass.prototype = {<br /><br />initialize: function(message) {<br />this.message = message;<br />},<br /><br />showMessage: function(ajaxResponse) {<br />alert(this.message);<br />}<br />};<br /><br />//now, let's instantiate and use one object<br />var myTalker = new MySampleClass('hi there.');<br />myTalker.showMessage(); //displays alert<br /><br /></p><br /><p><br /><table class="reference" id="Table16" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>create(*)</td><br /><td><nobr>instance</nobr></td><br /><td>(any)</td><br /><td class="refDescription">定义新类的构造方法。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Ajax</span> object</h4><br /><p>这个对象被用作其他提供AJAX功能的类的根对象。 </p><br /><p><br /><table class="reference" id="Table17" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Kind</th><br /><th>Description</th></tr><br /><tr><br /><td>activeRequestCount</td><br /><td>Number</td><br /><td>instance</td><br /><td class="refDescription">正在处理中的Ajax请求的个数。</td></tr></tbody></table></p><br /><p><br /><table class="reference" id="Table18" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>getTransport()</td><br /><td><nobr>instance</nobr></td><br /><td>(none)</td><br /><td class="refDescription">返回新的<tt class="literal">XMLHttpRequest</tt> 对象。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Ajax.Responders</span> object</h4><br /><p><em>继承自 Enumerable</em></p><br /><p>这个对象维持一个在Ajax相关事件发生时将被调用的对象的列表。比如,你要设置一个全局钩子来处理Ajax操作异常,那么你就可以使用这个对象。 </p><br /><p><br /><table class="reference" id="Table19" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Kind</th><br /><th>Description</th></tr><br /><tr><br /><td>responders</td><br /><td>Array</td><br /><td><nobr>instance</nobr></td><br /><td class="refDescription">被注册到Ajax事件通知的对象列表。</td></tr></tbody></table></p><br /><p><br /><table class="reference" id="Table20" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>register(responderToAdd)</td><br /><td>instance</td><br /><td>responderToAdd: object with methods that will be called.</td><br /><td class="refDescription">被传入参数的对象应包含名如Ajax事件的系列方法(如onCreate,onComplete,onException)。通讯事件引发所有被注册的对象的合适名称的函数被调用。 </td></tr><br /><tr><br /><td>unregister(responderToRemove)</td><br /><td>instance</td><br /><td>responderToRemove: object to be removed from the list.</td><br /><td class="refDescription">从列表中移除。 </td></tr><br /><tr><br /><td>dispatch(callback, request, transport, json)</td><br /><td>instance</td><br /><td>callback: name of the AJAX event being reported, request: the Ajax.Request object responsible for the event, transport: the XMLHttpRequest object that carried (or is carrying) the AJAX call, json: the X-JSON header of the response (if present) </td><br /><td class="refDescription">遍历被注册的对象列表,找出有由callback参数决定的那个函数的对象。然后向这些函数传递其它的三个参数,如果Ajax响应中包含一个含有JSON内容的X-JSON HTTP头,那么它会被热行并传入json参数。如果事件是onException,那么transport参数会被异常代替,json不会传递。 </td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Ajax.Base</span> class</h4><br /><p>这个类是其他在Ajax对象中定义的类的基类。 </p><br /><p><br /><table class="reference" id="Table21" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>setOptions(options)</td><br /><td><nobr>instance</nobr></td><br /><td>options: AJAX options</td><br /><td class="refDescription">设定AJAX操作想要的选项。</td></tr><br /><tr><br /><td>responseIsSuccess()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">返回 <tt class="literal">true</tt> 如果AJAX操作成功,否则为 <tt class="literal">false</tt> 。</td></tr><br /><tr><br /><td>responseIsFailure()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">与 <tt class="literal">responseIsSuccess()</tt> 相反。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">Ajax.Request</span> class</h4><br /><p><em>继承自 Ajax.Base</em></p><br /><p>封装 AJAX 操作 </p><br /><p><br /><table class="reference" id="Table22" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Kind</th><br /><th>Description</th></tr><br /><tr><br /><td>Events</td><br /><td>Array</td><br /><td>static</td><br /><td class="refDescription">在AJAX操作中所有可能报告的事件/状态的列表。这个列表包括: <tt class="literal">'Uninitialized', 'Loading', 'Loaded', 'Interactive', </tt>和 <tt class="literal">'Complete'</tt>。</td></tr><br /><tr><br /><td>transport</td><br /><td>XMLHttpRequest</td><br /><td>instance</td><br /><td class="refDescription">承载AJAX操作的 <tt class="literal">XMLHttpRequest</tt> 对象。</td></tr><br /><tr><br /><td>url</td><br /><td><nobr>string</nobr></td><br /><td><nobr>instance</nobr></td><br /><td class="refDescription">请求的URL。</td></tr></tbody></table></p><br /><p><br /><table class="reference" id="Table23" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Method</th><br /><th>Kind</th><br /><th>Arguments</th><br /><th>Description</th></tr><br /><tr><br /><td>[ctor](url, options)</td><br /><td>constructor</td><br /><td>url: the url to be fetched, options: AJAX options</td><br /><td class="refDescription">创建这个对象的一个实例,它将在给定的选项下请求url。onCreate事件在调用constructor事被激发。 <span class="bold"><b>重要:</b></span> 如果选择的url受到浏览器的安全设置,他会一点作用也不起。 很多情况下,浏览器不会请求与当前页面不同主机(域名)的url。 你最好只使用本地url来避免限制用户配置他们的浏览器(谢谢Clay)</td></tr><br /><tr class="privateMember"><br /><td>evalJSON()</td><br /><td><nobr>instance</nobr></td><br /><td>(none)</td><br /><td class="refDescription">这个方法显然不会被外部调用。它在Ajax响应中含有X-JSON HTTP头时用于内部调用执行这些内容。</td></tr><br /><tr class="privateMember"><br /><td>evalReponse()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">这也方法显然不会被外部调用,如果Ajax响应含有一个值为text/javascript的Cotent-Type头,那么这个方法就用被调用执行响应体。</td></tr><br /><tr><br /><td>header(name)</td><br /><td>instance</td><br /><td>name: HTTP header name</td><br /><td class="refDescription">引用Ajax响应的头的内容,在Ajax访问结束后再调用这个方法。</td></tr><br /><tr class="privateMember"><br /><td>onStateChange()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">这个方法通常不会被外部调用。 当AJAX请求状态改变的时候被这个对象自己调用。</td></tr><br /><tr class="privateMember"><br /><td>request(url)</td><br /><td><nobr>instance</nobr></td><br /><td>url: url for the AJAX call</td><br /><td class="refDescription">这个方法通常不会被外部调用。已经在构造方法中调用了。</td></tr><br /><tr class="privateMember"><br /><td>respondToReadyState(readyState)</td><br /><td>instance</td><br /><td>readyState: state number (1 to 4)</td><br /><td class="refDescription">这个方法通常不会被外部调用。 当AJAX请求状态改变的时候被这个对象自己调用。</td></tr><br /><tr class="privateMember"><br /><td>setRequestHeaders()</td><br /><td>instance</td><br /><td>(none)</td><br /><td class="refDescription">这个方法通常不会被外部调用。 被这个对象自己调用来配置在HTTP请求要发送的HTTP报头。</td></tr></tbody></table></p><br /><p><!-- ------------------------------------------------------------------------------------------- --></p><br /><h4>The <span class="objectClass">options</span> argument object</h4><br /><p>An important part of the AJAX operations is the <span class="code">options</span> argument. There's no <span class="code">options</span> class per se. Any object can be passed, as long as it has the expected properties. It is common to create anonymous objects just for the AJAX calls. </p><br /><p><br /><table class="reference" id="Table24" cellspacing="0" border="1"><br /><tbody><br /><tr><br /><th>Property</th><br /><th>Type</th><br /><th>Default</th><br /><th>Description</th></tr><br /><tr><br /><td>method</td><br /><td>String</td><br /><td>'post'</td><br /><td class="refDescription">HTTP 请求方式。</td></tr><br /><tr><br /><td>parameters</td><br /><td><nobr>String</nobr></td><br /><td>''</td><br /><td class="refDescription">在HTTP请求中传入的url格式的值列表。</td></tr><br /><tr><br /><td>asynchronous</td><br /><td>Boolean</td><br /><td>true</td><br /><td class="refDescription">指定是否做异步 AJAX 请求。</td></tr><br /><tr><br /><td>postBody</td><br /><td>String</td><br /><td>undefined</td><br /><td class="refDescription">在HTTP POST的情况下,传入请求体中的内容。</td></tr><br /><tr><br /><td>requestHeaders</td><br /><td>Array</td><br /><td>undefined</td><br /><td class="refDescription">和请求一起被传入的HTTP头部列表, 这个列表必须含有偶数个项目, 任何奇数项目是自定义的头部的名称, 接下来的偶数项目使这个头部项目的字符串值。 例子:<tt class="literal">['my-header1', 'this is the value', 'my-other-header', 'another value']</tt> </td></tr><br /><tr><br /><td>onXXXXXXXX</td><br /><td>Function(XMLHttpRequest, Object)</td><br /><td>undefined</td><br /><td class="refDescription">在AJAX请求中,当相应的事件/状态形成的时候调用的自定义方法。 例如 <tt class="literal">var myOpts = {onComplete: showResponse, onLoaded: registerLoaded};</tt>. 这个方法将被传入一个参数, 这个参数是承载AJAX操作的 <tt class="literal">XMLHttpRequest</tt> 对象,另一个是包含被执行X-JSON响应HTTP头。</td></tr><br /><tr><br /><td>onSuccess</td><br /><td>Function(XMLHttpRequest, Object)</td><br /><td>undefined</td><br /><td class="refDescription">当AJAX请求成功完成的时候调用的自定义方法。 这个方法将被传入一个参数, 这个参数是承载AJAX操作的 <tt class="literal">XMLHttpRequest</tt> 对象,另一个是包含被执行X-JSON响应HTTP头。</td></tr><br /><tr><br /><td>onFailure</td><br /><td>Function(XMLHttpRequest, Object)</td><br /><td>undefined</td><br /><td class="refDescription">当AJAX请求完成但出现错误的时候调用的自定义方法。这个方法将被传入一个参数, 这个参数是承载AJAX操作的 &lt;TT class=liter</td></tr></tbody></table></p><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-75976312057083638?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1150384576804978672006-06-15T22:24:00.001+08:002006-06-15T23:16:17.436+08:00使用模板实现ASP代码与页面分离每个进行过较大型的ASP-Web应用程序设计的开发人员大概都有如下的经历:ASP代码与页面HTML混淆难分,业务逻辑与显示方式绞合,使得代码难以理解、难以修改;程序编写必须在美工之后,成为项目瓶颈;整合的程序代码和HTML静态页面时,花费大量的时间才能得到理想的效果,兼作了美工。的确,用脚本语言开发Web应用不容易将数据的处理和数据的显示分开,但在多人合作的情况下,如果无法将数据和显示分开,将大大影响开发的效率,专业分工的发挥。<br />  其它的脚本语言,如JSP、PHP都有自己的解决方案,ASP的后一代产品ASP.NET也实现了代码与页面,似乎直接过渡到ASP是不错的选择。但是总有这样或那样的原因让我们不能或暂时不能放弃ASP直奔.NET大营。从公司角度来看,转换语言是一笔不少的投资,包括雇佣熟手.NET程序员、培训原有程序员、开发工具的转型、开发风格的转型、界面风格转变、接口风格、软件架构、文档、开发流程等等;这还意味着原有的代码必须在新语言环境里重写以实现最佳的效果和稳定性;同时将直接影响这段时间内项目的进度,更有可能导致个别程序员出走。由此看来在您决定转换语言之前,在原基础上寻求一种解决方案,才是最好的选择。<br />  PHP通过模板实现代码与页面,可供选择的有FastTemplate、PHPLIB、Smarty等多种,其中PHPLIB 的影响最大、使用最多。既然如此,我们直接把它搬到ASP来,对于同时使用PHP和ASP的公司还有很有好处:一、美工处理页面时,不管将要套用PHP还是ASP,处理方式是一样,无须经过培训;二、程序员编写代码时,两种语言间的思路接近或一致,相同功能在两种语言实现时,只需拷贝过来略作修改即可,保证了工作效率和项目进度。<br />  1、模板类的设计<br />  实现代码封装成为模板类,即是为了与PHPLIB兼容,也使得代码方便管理与扩展。<br />  模板类要实现的目标为:从模板文件中读入显示的HTML代码,将这些显示代码中需要动态数据的地方替换为ASP程序运算所得出的数据,然后按照一定的顺序输出。其中,替换的部分可以自由的设定。因此它必须完成如下任务:<br />  * 从模板文件中读取显示用的HTML代码。  * 将模板文件和实际生成的数据结合,生成输出的结果。  * 允许同时处理多个模板。  * 允许模板的嵌套。  * 允许对模板中的某个单独的部分进行处理。<br />  实现方法:<br />  * 采用FSO读取模板文件  * 采用正则替换实现模板文件和数据的结合  * 处理多个模板用数组存储来实现。  * 模板的嵌套的实现主要的想法是:将模板和输出(任何中间的分析结果)一视同仁,都可拿来做替换,即可实现。  * 单独部分的处理的通过在模板文件中设定标注,然后在正则替换中结合标注来控制,实现部分替换。<br />  2、模板类的实现<br />  给出具体代码之前,先把主要函数列出,用过PHPLIB的朋友应该对此很熟悉了:    1)Public Sub set_root(ByVal Value) 设定模板默认目录  2)Public Sub set_file(ByVal handle,ByVal filename) 读取文件  3)Public Sub set_var(ByVal Name, ByVal Value, ByVal Append) 设置映射数据-替换变量  4)Public Sub unset_var(ByVal Name) 取消数据映射  5)Public Sub set_block(ByVal Parent, ByVal BlockTag, ByVal Name) 设置数据块  6)Public Sub set_unknowns(ByVal unknowns) 设定未指定映射的标记处理方式  7)Public Sub parse(ByVal Name, ByVal BlockTag, ByVal Append) 执行模板文件与数据的结合  8)Public Sub p(ByVal Name) 输出处理结果<br />  实现代码:<br />Class kktTemplate<br />Private m_FileName, m_Root, m_Unknowns, m_LastError, m_HaltOnErrPrivate m_ValueList, m_BlockListPrivate m_RegExp’ 构造函数Private Sub Class_InitializeSet m_ValueList = CreateObject("Scripting.Dictionary")Set m_BlockList = CreateObject("Scripting.Dictionary")set m_RegExp = New RegExpm_RegExp.IgnoreCase = Truem_RegExp.Global = Truem_FileName = ""m_Root = ""m_Unknowns = "remove"m_LastError = ""m_HaltOnErr = trueEnd Sub<br />’ 析构函数Private Sub Class_TerminateSet m_RegExp = NothingSet m_BlockMatches = NothingSet m_ValueMatches = nothingEnd Sub<br />Public Property Get ClassName()ClassName = "kktTemplate"End Property<br />Public Property Get Version()Version = "1.0"End Property<br />Public Sub About()Response.Write("kktTemplate ASP页面模板类<br>" & vbCrLf &amp;amp;amp;_"程序设计:彭国辉 2004-07-05<br>" & vbCrLf &amp;_"个人网站:<a href=’http://kacarton.yeah.net’><a href="http://kacarton.yeah.net/">http://kacarton.yeah.net/</a><;/a><br>" & vbCrLf &amp;_"电子邮件:<a href=’mailto:kacarton@sohu.com’><a href="mailto:kacarton@sohu.com">kacarton@sohu.com</a></a><br>")End Sub<br />’检查目录是否存在Public Function FolderExist(ByVal path)Dim fsoSet fso = CreateObject("Scripting.FileSystemObject")FolderExist = fso.FolderExists(Server.MapPath(path))Set fso = NothingEnd Function’读取文件内容Private Function LoadFile()Dim Filename, fso, hndFileFilename = m_RootIf Right(Filename, 1)<>"/" And Right(Filename, 1)<>"\" Then Filename = Filename & "/"Filename = Server.MapPath(Filename &amp; m_FileName)Set fso = CreateObject("Scripting.FileSystemObject")If Not fso.FileExists(Filename) Then ShowError("模板文件" & m_FileName &amp; "不存在!")set hndFile = fso.OpenTextFile(Filename)LoadFile = hndFile.ReadAllSet hndFile = NothingSet fso = NothingIf LoadFile = "" Then ShowError("不能读取模板文件" & m_FileName &amp; "或文件为空!")End Function<br />’处理错误信息Private Sub ShowError(ByVal msg)m_LastError = msgResponse.Write "<font color=red style=’font-size;14px’><b>模板错误:" & msg &amp; "</b></font><br>"If m_HaltOnErr Then Response.EndEnd Sub<br />’设置模板文件默认目录’Ex: kktTemplate.set_root("/tmplate")’ kktTemplate.Root = "/tmplate"’ root = kktTemplate.get_root()’ root = kktTemplate.Root’使用类似set_root这样的命名方法是为了兼容phplib,以下将不再重复说明Public Sub set_root(ByVal Value)If Not FolderExist(Value) Then ShowError(Value & "不是有效目录或目录不存在!")m_Root = ValueEnd SubPublic Function get_root()get_root = m_RootEnd FunctionPublic Property Let Root(ByVal Value)set_root(Value)End PropertyPublic Property Get Root()Root = m_RootEnd Property<br />’设置模板文件’Ex: kktTemplate.set_file("hndTpl", "index.htm")’本类不支持多模板文件,handle为兼容phplib而保留Public Sub set_file(ByVal handle,ByVal filename)m_FileName = filenamem_BlockList.Add Handle, LoadFile()End SubPublic Function get_file()get_file = m_FileNameEnd Function’ Public Property Let File(handle, filename)’ set_file handle, filename’ End Property’ Public Property Get File()’ File = m_FileName’ End Property<br />’设置对未指定的标记的处理方式,有keep、remove、comment三种Public Sub set_unknowns(ByVal unknowns)m_Unknowns = unknownsEnd SubPublic Function get_unknowns()get_unknowns = m_UnknownsEnd FunctionPublic Property Let Unknowns(ByVal unknown)m_Unknowns = unknownEnd PropertyPublic Property Get Unknowns()Unknowns = m_UnknownsEnd Property<br />Public Sub set_block(ByVal Parent, ByVal BlockTag, ByVal Name)Dim Matchesm_RegExp.Pattern = "<!--\s+BEGIN " &amp; BlockTag & "\s+-->([\s\S.]*)<!--\s+END " &amp; BlockTag & "\s+-->"If Not m_BlockList.Exists(Parent) Then ShowError("未指定的块标记" &amp; Parent)set Matches = m_RegExp.Execute(m_BlockList.Item(Parent))For Each Match In Matchesm_BlockList.Add BlockTag, Match.SubMatches(0)m_BlockList.Item(Parent) = Replace(m_BlockList.Item(Parent), Match.Value, "{" & Name &amp; "}")Nextset Matches = nothingEnd Sub<br />Public Sub set_var(ByVal Name, ByVal Value, ByVal Append)Dim ValIf IsNull(Value) Then Val = "" Else Val = ValueIf m_ValueList.Exists(Name) ThenIf Append Then m_ValueList.Item(Name) = m_ValueList.Item(Name) & Val _Else m_ValueList.Item(Name) = ValElsem_ValueList.Add Name, ValueEnd IfEnd Sub<br />Public Sub unset_var(ByVal Name)If m_ValueList.Exists(Name) Then m_ValueList.Remove(Name)End Sub<br />Private Function InstanceValue(ByVal BlockTag)Dim keys, iInstanceValue = m_BlockList.Item(BlockTag)keys = m_ValueList.KeysFor i=0 To m_ValueList.Count-1InstanceValue = Replace(InstanceValue, "{" &amp; keys(i) & "}", m_ValueList.Item(keys(i)))NextEnd Function<br />Public Sub parse(ByVal Name, ByVal BlockTag, ByVal Append)If Not m_BlockList.Exists(BlockTag) Then ShowError("未指定的 块标记" &amp; Parent)If m_ValueList.Exists(Name) ThenIf Append Then m_ValueList.Item(Name) = m_ValueList.Item(Name) & InstanceValue(BlockTag) _Else m_ValueList.Item(Name) = InstanceValue(BlockTag)Elsem_ValueList.Add Name, InstanceValue(BlockTag)End IfEnd Sub<br />Private Function finish(ByVal content)Select Case m_UnknownsCase "keep" finish = contentCase "remove"m_RegExp.Pattern = "\{[^ \t\r\n}]+\}"finish = m_RegExp.Replace(content, "")Case "comment"m_RegExp.Pattern = "\{([^ \t\r\n}]+)\}"finish = m_RegExp.Replace(content, "<!-- Template Variable $1 undefined -->")Case Else finish = contentEnd SelectEnd Function<br />Public Sub p(ByVal Name)If Not m_ValueList.Exists(Name) Then ShowError("不存在的标记" &amp; Name)Response.Write(finish(m_ValueList.Item(Name)))End SubEnd Class%><br />  3、使用例子<br />  下面举三个例子进行说明。<br />  1)简单的值替换<br />  模板文件为myTemple.tpl,内容:<br /><html><title>ASP模板简单替换</title><body>祝贺!你赢了一辆{some_color}法拉利!</body><br />  下面是ASP代码(kktTemplate.inc.asp就是上面给出的模板类):<br /><!--#INCLUDE VIRTUAL="kktTemplate.inc.asp"--><%dim my_color, kktmy_color = "红色的"set kkt = new kktTemplate ’创建模板对象kkt.set_file "hndKktTemp", "myTemple.tpl" ’设置并读取模板文件myTemple.tplkkt.set_var "some_color", my_color, false ’设置模板变量 some_color = my_color的值kkt.parse "out", "hndKktTemp", false ’模板变量 out = 处理后的文件kkt.p "out" ’输出out的内容set kkt = nothing ’销毁模板对象%><br />  执行后输出为:<br /><html><title>ASP模板简单替换</title><body>祝贺!你赢了一辆红色的法拉利!</body><br />  2)循环块演示例子<br />  模板文件myTemple2.tpl:<br /><html><title>ASP模板-块的演示</title><body><table cellspacing="2" border="1"><tr><td>下面的动物您喜欢哪一种</td></tr><!-- BEGIN AnimalList --><tr><td><input type="radio" name="chk">{animal}</td></tr><!-- END AnimalList --></table></body><br />  ASP代码:<br /><!--#INCLUDE VIRTUAL="kktTemplate.inc.asp"--><%dim animal, kkt, ianimal = Array("小猪","小狗","小强")set kkt = new kktTemplatekkt.set_file "hndKktTemp", "myTemple2.tpl"kkt.set_block "hndKktTemp", "AnimalList", "list"for i=0 to UBound(animal)kkt.set_var "animal", animal(i), falsekkt.parse "list", "AnimalList", truenextkkt.parse "out", "hndKktTemp", falsekkt.p "out"set kkt = nothing%><br />  执行结果:<br /><html><title>ASP模板-块的演示</title><body><table cellspacing="2" border="1"><tr><td>下面的动物您喜欢哪一种</td></tr><tr><td><input type="radio" name="chk">小猪</td></tr><tr><td><input type="radio" name="chk">小狗</td></tr><tr><td><input type="radio" name="chk">小强</td></tr></table></body><br />  3)嵌套块演示<br />  模板文件myTemple3.tpl:<br /><html><title>ASP模板-嵌套块演示</title><body><table width="400" border="1" bordercolor="#000000"><tr><td><div align="center">{myname}测试</div></td></tr><tr><td>我的动植物园:</td> </tr><!-- BEGIN animalList --><tr><td>{animal}</td></tr><!-- BEGIN plantList --><tr><td> {plant}</td></tr><!-- END plantList --><!-- END animalList --></table></body></html><br />  ASP代码:<br /><!--#INCLUDE VIRTUAL="kktTemplate.inc.asp"--><%dim my_color, kkt, myname, animal, plantset kkt = new kktTemplatemyname = "kktTemplate block test..."animal = array("动物", "植物")plant = array(array("小猪","小白","小强"), array("玫瑰","向日葵"))<br />kkt.set_file "hndKktTemp", "myTemple3.tpl"kkt.set_var "myname", myname, falsekkt.set_block "hndKktTemp", "animalList", "a"kkt.set_block "animalList", "plantList", "p"<br />for i=0 to UBound(animal)kkt.set_var "animal", animal(i), Falsekkt.unset_var "p"’kkt.set_var "p", "", falsefor j=0 to UBound(plant(i))kkt.set_var "plant", plant(i)(j), falsekkt.parse "p", "plantList", truenextkkt.parse "a", "animalList", truenextkkt.parse "out", "hndKktTemp", falsekkt.p "out"%><br />  执行结果:<br /><html><title>ASP模板-嵌套块演示</title><body><table width="400" border="1" bordercolor="#000000"><tr><td><div align="center">kktTemplate block test...测试</div></td></tr><tr><td>我的动植物园:</td> </tr><tr><td>动物</td></tr><tr><td> 小猪</td></tr><tr><td> 小白</td></tr><tr><td> 小强</td></tr><tr><td>植物</td></tr><tr><td> 玫瑰</td></tr><tr><td> 向日葵</td></tr></table></body></html><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-115038457680497867?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1149999134418559642006-06-11T12:06:00.000+08:002006-06-13T11:32:02.220+08:00ASP常见问题及解答1.关于<table>折行: <table style="TABLE-LAYOUT: fixed" width="200" border="0" cellspacing="0" cellpadding="7" bgcolor="#f7f7f7"> <tr> <td style="LEFT: 0px; WIDTH: 100%; WORD-WRAP: break-word"> dffadfdaqqqqqqqqq</font></td> </tr> </table><br />重点是"WORD-WRAP: break-word"把它去掉再看看就知道了.<br /><br />2.批量录入在数据库的应用中比较广泛的,关于批量录入的方法也有好多种。 下面我就结合我实际中的应用,谈一下儿我是怎么实现的。 主要用到的是form的集合的概念,通过循环取的所有的集合内数据。 考虑到大家看着方便,我把它集成到了一个页面。 下面是具体的代码: batchInput.asp <% ''##################################### ''File Function:批量录入数据 ''Author:Myhon ''Date:2003-8-19 ''#####################################<br />''向数据库写入数据 SUB writeData() dim recCnt,i dim fieldName1,fieldName2,fieldName3 dim conn dim sqlStr,connStr connStr="Provider=SQLOLEDB.1;Initial Catalog=myDatabase;Data Source=myhon;User Id=sa;PASSWORD=" set conn=Server.CreateObject("ADODB.Connection") conn.open connStr ''建立数据库连接<br />recCnt=request.form("stu_num").count ''取得共有多少条记录 ''批量录入数据 for i=1 to recCnt fieldName1=trim(request.form("fieldName1")(i)) fieldName2=trim(request.form("fieldName2")(i)) fieldName3=trim(request.form("fieldName3")(i)) sqlStr="insert into myTable(fieldName1,fieldName2,fieldName3) values(''" sqlStr=sqlStr & fieldName1 &amp; "'',''" sqlStr=sqlStr & fieldName2 &amp; "'',''" sqlStr=sqlStr & fieldName3 &amp; "'')" ''response.write sqlStr conn.execute(sqlStr) next END SUB<br />''显示成批录入的界面 SUB InputData() dim recCnt,i %> <form name="bathInputData" action="" method="post"> <% recCnt=cint(request.form("recCnt")) for i=1 to recCnt %> <input type="text" name="fieldName1"> <input type="text" name="fieldName2"> <input type="text" name="fieldName3"> <% next %> <br/> <input type="submit" name="action" value="提交"> </form> <% END SUB<br />''指定要批量录入多少条记录 SUB assignHowMuch() %><br /><!------指定要录入多少条记录--------------> <form name="form1" action="" method="post"> 您要录入的记录的条数:<input type="text" name="recCnt"> <input type="submit" name="action" value="下一步>>"> </form> <% END SUB<br />if request.form("action")="下一步>>" then Call InputData() ''显示成批录入界面 elseif request.form("action")="提交" then Call writeData() ''向数据库批量写入数据 else Call assignHowMuch() ''显示指定录入多少条记录的界面 end if<br />%><br /><br />3.以动感下载系统为例:<br />打开文件 SoftDown.Asp 在: if request.QueryString("ID")="" then response.write "不能连接或者没有指定下载软件" response.end end if 的上面或者是下面加上下列代码<br />dim strReferer,domain,splDomain,isHttp isHttp=false<br />''本站下载系统网址列表,不要带上http:// domain="sron.net,61.156.14.223,61.156.14.227"<br />splDomain=split(domain,",") strReferer=Request.ServerVariables("HTTP_REFERER") for iii = 0 to ubound(splDomain) if instr(strReferer,trim(splDomain(iii)))>0 then isHttp=True next if isnull(strReferer) or isHttp=false then Response.Write "下载链接来自其他网站,这是不允许的,<a href="/sblog/"./"">请进入本站页面后再进行下载。</a>" CloseDatabase response.end end if<br />本站下载系统网址列表 就是访问你下载频道网址里的域名,比如你的下载频道可以用多个网址来访问,所以这里用逗号隔开.<br /><br />4.无法写入cookie的常见问题 1.确定你的response.cookie代码在第一个<html>之前 2.设置cookies的截止日期response.cookie("cookiename").expires = expiresdate;<br />设置cookie的请求指定路径: 就是说你的cookie写入后,指定路径中的页面才有权得到这个cookie 例如:指定路径response.cookie("cookiename").path = "<a href="http://www.domain.com/path">http://www.domain.com/path</a>" 那么只有path目录中的页面才能得到request.cookie("cookiename")<br /><br />5.vbscript的错误捕捉:<br />on error resume next ''打开错误捕捉 ... if err.number<>0 then ''err是vbs内置的对象,类似于try catch的exception err.clear ''错误被处理了就要及时把错误标记清空 ''输出自己的出错信息,或用err.description显示系统出错信息 end if<br />on error goto 0 ''关闭错误捕捉。<br /><br />6.ServerVariables集合用于得到系统的环境变量用以下程序可以讲ServerVariables集合的所有内容名称都显示出来 <html> <head></head> <body> <% for each item in request.servervariables response.write("<p><b>"&item&amp;"</b>:") response.write(request.serverVariables(item)) next %> </body> </html> 具体的系统环境变量如下: Auth_Type 当用户访问一个被保护的脚本时,用于判断是否是一个有效用户 Content_Length 客户端所提交的正文的长度 Content_Type 提交的正文数据类型 Gateway_Interface 服务器所使用的CGI修订版本 Login_User 用户是否以Windows NT帐户登陆 Path_Info 客户端路径信息 Query_String 在一个HTTP请求的查询信息 Remote_Addr 发送请求的远程主机的ip地址,利用此地址可以知道访问这的来源 Remote_Host 发送请求的远程主机名,如果远端服务器不包含该信息,则返回空字符串 Request_Method 数据请求的方法 Script_Map url的基本部分 Script_Name 执行脚本的虚拟路径 Server_Name 该服务器的名称DNS的别名,IP地址及其制定的url路径 Server_Port 数据请求所使用的端口号 Server_Software 服务器端运行的软件名称及版本号 Server_Protocol 要求信息的协议及修订版本 URL 系统的URL路径 HTTP_REFERER 当通过链接到大当前页面时,HTTP_REFERER header 保存这个用户的来源<br /><br />8.HTML文件标记 <html> <head> <!--> <title> <body><br />文字排版标记 <br/> <nobr> <p> <pre> 原始文字样式 <center> <blockquote> 向内缩排 <h> 标题 <strong>,<b> 粗体 <em>,<i>,<cite> 斜体 <U> 底线 <strike> 删除线 <blink> 文字闪烁 <big> 大型字体 <small> 小型字体 <sup> 文字上标 <SUB> 文字下标 <basefont> 默认字体设置 <font> 更改字体设置<br />菜单标记 <menu> 选项菜单 <dir> 目录菜单 <lh> 菜单格式(一) <ul> 菜单格式(二) <dl>,<dt>,<dd> 说明式菜单 <ol>,<li> 标题菜单<br />直线与表格标记 <hr> <table> <tr> <td> <th> <caption> 表格标题<br />超链接标记 <a> 锚<br />图形标记 <IMG> 插入图形<br />框架标记 <FRAME> 定义框架内容 <NOFRAME> 不支持框架声明<br />表单标记 <FORM> <INPUT> <TEXTAREA> <SELECT> <OPTION><br />SCRIPT <script><br />VBSCRIPT标记索引<br />基本运算 + 数字加法及字符串连接 - 数字减法 * 数字乘法 / 数字除法 Mod 求余数 \ 求商数 & 字符串连接 ^ 次方 = 相等 <> 不相等 >= 大于或等于 > 大于 <= 小于或等于 < 小于 Not 非 And 且 Or 或 Xor 异或<br />循环及决策 if ....then 若...则... if ...then...else 若...则...非 else if... 非若 select case... 群组选择条件 end select for ... next 计数循环 while...wend 条件循环(一) do while...loop 条件循环(二) do...loop while 条件循环(三) do until...loop 条件循环(四) do...loop until 条件循环(五)<br />数学函数 Abs 绝对值 Sgn 正负号 Hex 转换成十六进制 Oct 转换成八进制 Sqr 平方根 Int 取整数 Fix 取整数 Round 取整数 Log 以e为底的对数 Sin 正弦函数 Cos 余弦函数 Tan 正切函数<br />字符串处理函数 Len 字符串长度 Mid 取部分字符串 Left 从字符串开头取部分字符串 Right 从字符串结尾取部分字符串 Lcase 转换成小写 Ucase 转换成大写 Trim 清除字符串开头及结尾的空格符 Ltrim 清除字符串开头空格符 Rtrim 清除字符串结尾空格符 Replace 替换字符串部分字符 Instr 判断是否包含于另一个字符串(从起始搜寻) InstrRev 判断是否包含于另一个字符串(从结尾搜寻) Space 任意字符数的空格符 String 任意字符数的任一字符 StrReverse 反转字符串 Split 以某字符分割字符串<br />数据类型转换函数 Cint 转换成整形 Cstr 转换成字符串 Clng 转换成常整数 Cbool 转换成布尔函数 Cdate 转换成日期函数 CSng 转换成单精度 CDbl 转换成双精度<br />日期时间函数 Date 现在日期 Time 现在时间 NOw 现在日期时间 DateAdd 增加日期 DateDiff 两日期差 DateSerial 日期设定 DateValue 日期设定 Year 现在年份 Month 现在月份 Day 现在天 Hour 现在时刻 Minute 现在分钟 Second 现在秒钟 Timer 午夜距现在秒数 TimeSerial 时间设定 TimeValue 时间所属部分 WeekDay 星期名称 MonthName 月份名称<br />其它函数 Array 产生数组 Asc 字符ASCII码 Chr ASCII码字符 Filter 过滤数组 InputBox 输入窗口 Join 合并数组中的元素 MsgBox 信息窗口 Lbound 数组下界 Ubound 数组上界<br />指令 Const 设定常数 Dim 定义变量或者数组 Erase 清除数组 ReDim 重新声明数组 Randomize 起始随机数 Rnd 取得随机数<br />ASP对象<br />Session对象 IsEmpty 测试Session变量是否存在 TimeOut 设定Session变量生存周期 Abandon 强制清除Session变量<br />Application对象 IsEmpty 测试Application变量是否存在 Lock 锁定Application变量 Unlock 解除Lock指令的锁定<br />Cookies对象 Expires 设定Cookies变量的生存周期<br />Connection对象 Open 打开与数据库的连接 Execute 打开Recordset对象 Close 关闭Connection对象<br />Recordset对象 movefirst 将记录指针移至第一条 movelast 将记录指针移至最后一条 movenext 将记录指针移至下一条 moveprevious 将记录指针移至上一条 bof 测试是否为recordset的起始 eof 测试是否为recordset的结束 open 打开Recoreset对象 close 关闭recordset对象 fields 读取数据的子对象 fileds.count 字段个数 pagesize 每页记录条数 absolutepage 设定为某页 pagecount 总页数 Absoluteposition 直接跳至某条记录<br /><br /><br />9.没什么好共享的,但太感动了,把做树型菜单的js函数贴出来, <SCRIPT language="JavaScript"> var lastObj<br />function expandIt(obj) { if(lastObj != null) { if(obj == lastObj) { if(obj.style.display == "none") { obj.style.display = ""; } else { obj.style.display = "none" } } else { lastObj.style.display = "none"; obj.style.display = ""; } } else { obj.style.display = ""; }<br />lastObj = obj } </SCRIPT><br /><table width="100%" border="0" cellspacing="0" cellpadding="0"> <% dim id id = request("id") dim strsql,rs<br />strsql="select * from p_type where slanguage=1 and typelevel=1 order by typename" set rs=fgetrslist(strsql) do while not rs.eof<br />%> <tr> <td height="25" class="LEFTLINKS"><img width="30" height="0" align="absmiddle" /><b><%if rs("isleaf")=0 then%><a href="#" onClick="javascript:expandIt(kb<%=rs("id")%>);return false"><%else%><a href="<%=request.ServerVariables("SCRIPT_NAME")%>?idtree=<%=rs("idtree")%>" ><%end if%><%=server.HTMLEncode(right((rs("typename")&""),len(rs("typename")&amp;"")-2))%></a></b></td> </tr> <% IF clng(id)=clng(rs("id")) then<br />%> <tr id="kb<%=rs("id")%>"> <% else<br />%><br /><tr id="kb<%=rs("id")%>" style="display:none;"> <% end if %> <td> <table> <% dim rs1 strsql="select * from p_type where parentid="&rs("id")&amp;" and slanguage=1 order by typename" set rs1=fgetrslist(strsql) do while not rs1.eof %> <tr><td height="20" class="LEFTLINKS"> <img width="40" height="0" align="absmiddle" /><a href="<%=request.ServerVariables("SCRIPT_NAME")%>?idtree=<%=rs1("idtree")%>&id=<%=rs("id")%>" ><%=server.HTMLEncode(right((rs1("typename")&amp;""),len(rs1("typename")&"")-2))%></a></td></tr> <% rs1.movenext loop rs1.close set rs1=nothing %> </table> </td> </tr> <% rs.movenext<br />loop rs.close set rs=nothing %> </table><br /><br />10.计算网页文本的汉字字数,去掉了表格以外的所有标识。 Function GetLength(strChinese1) Dim strWord, ascWord, lenTotal strChinese1 = Trim(strChinese1)<br />If strChinese1 = "" Or Vartype(strChinese1) = vbNull Then GetLength = 0 Exit Function End If<br />lenTotal = 0 For GetLengthi=1 to Len(strChinese1) strWord = Mid(strChinese1, GetLengthi, 1) ascWord = Asc(strWord) If ascWord < 0 or ascWord > 127 then lenTotal = lenTotal + 1 Elseif ascWord = 63 And strWord <> "?" then lenTotal = lenTotal + 1 Elseif ascWord = 44 And strWord <> "," then lenTotal = lenTotal + 1 Elseif ascWord = 33 And strWord <> "!" then lenTotal = lenTotal + 1 Else lenTotal = lenTotal End If Next<br />GetLength = lenTotal End Function<br /><br />11.<table width="95%" cellspacing="1" cellpadding="5" align=center bgcolor=999999> <tr bgcolor=#ffcc00><td colspan="2" height=25><b>服务器有关的变量</b></td></tr> <tr bgcolor=#efefef><td valign=top>显示客户发出的所有HTTP标题</td><td><%=request.ServerVariables("All_Http")%></td></tr> <tr bgcolor=#efefef><td valign=top>检取ISAPIDLL的metabase路径</td><td><%=request.ServerVariables("APPL_MD_PATH")%></td></tr> <tr bgcolor=#efefef><td valign=top>显示站点物理路径</td><td><%=request.ServerVariables("APPL_PHYSICAL_PATH")%></td></tr> <tr bgcolor=#efefef><td valign=top>路径信息</td><td><%=request.ServerVariables("PATH_INFO")%></td></tr> <tr bgcolor=#efefef><td valign=top>显示请求机器IP地址</td><td><%=request.ServerVariables("REMOTE_ADDR")%></td></tr> <tr bgcolor=#efefef><td valign=top>服务器IP地址</td><td><%=Request.ServerVariables("LOCAL_ADDR")%></td></tr> <tr bgcolor=#efefef><td valign=top>显示执行SCRIPT的虚拟路径</td><td><%=request.ServerVariables("SCRIPT_NAME")%></td></tr> <tr bgcolor=#efefef><td valign=top>返回服务器的主机名,DNS别名,或IP地址</td><td><%=request.ServerVariables("SERVER_NAME")%></td></tr> <tr bgcolor=#efefef><td valign=top>返回服务器处理请求的端口</td><td><%=request.ServerVariables("SERVER_PORT")%></td></tr> <tr bgcolor=#efefef><td valign=top>协议的名称和版本</td><td><%=request.ServerVariables("SERVER_PROTOCOL")%></td></tr> <tr bgcolor=#efefef><td valign=top>服务器的名称和版本</td><td><%=request.ServerVariables("SERVER_SOFTWARE")%></td></tr> <tr bgcolor=#efefef><td valign=top>服务器操作系统</td><td><%=Request.ServerVariables("OS")%></td></tr> <tr bgcolor=#efefef><td valign=top>脚本超时时间</td><td><%=Server.ScriptTimeout%> 秒</td></tr> <tr bgcolor=#efefef><td valign=top>服务器CPU数量</td><td><%=Request.ServerVariables("NUMBER_OF_PROCESSORS")%> 个</td></tr> <tr bgcolor=#efefef><td valign=top width=30%>服务器解译引擎</td><td><%=ScriptEngine &amp; "/"& ScriptEngineMajorVersion &amp;"."&ScriptEngineMinorVersion&amp;"."& ScriptEngineBuildVersion %></td></tr> </table><br /><br />12.10进制表示,希望actor2222 (优悠) 能看到<br />MicrosoftVBscript运行时错误列表(10进制表示)<br />error # 5 无效的过程调用或参数 error # 5 无效的过程调用或参数 error # 6 溢出 error # 7 内存不够 error # 9 下标越界 error # 10 该数组为定长的或临时被锁定 error # 11 被零除 error # 13 类型不匹配 error # 14 字符串空间不够 error # 17 不能执行所需的操作 error # 28 堆栈溢出 error # 35 未定义过程或函数 error # 48 加载 DLL 时出错 error # 51 内部错误 error # 52 错误的文件名或号码 error # 53 文件未找到 error # 54 错误的文件模式 error # 55 文件已经打开 error # 57 设备 I/O 错误 error # 58 文件已存在 error # 61 磁盘已满 error # 62 输入超出了文件尾 error # 67 文件过多 error # 68 设备不可用 error # 70 没有权限 error # 71 磁盘没有准备好 error # 74 重命名时不能带有其他驱动器符号 error # 75 路径/文件访问错误 error # 76 路径未找到 error # 91 对象变量未设置 error # 92 For 循环未初始化 error # 94 无效使用 Null error # 322 不能创建必要的临时文件 error # 424 缺少对象 error # 429 ActiveX 部件不能创建对象 error # 430 类不支持 Automation 操作 error # 432 Automation 操作中文件名或类名未找到 error # 438 对象不支持此属性或方法 error # 440 Automation 操作错误 error # 445 对象不支持此操作 error # 446 对象不支持已命名参数 error # 447 对象不支持当前区域设置选项 error # 448 未找到已命名参数 error # 449 参数是必选项 error # 450 错误的参数个数或无效的参数属性值 error # 451 对象不是一个集合 error # 453 未找到指定的 DLL 函数 error # 455 代码资源锁定错误 error # 457 此键已与该集合的一个元素关联 error # 458 变量使用了一个 VBScript 中不支持的 Automation 类型 error # 462 远程服务器不存在或不可用 error # 481 无效图片 error # 500 变量未定义 error # 501 非法赋值 error # 502 对象不能安全用 Script 编程 error # 503 对象不能安全初始化 error # 504 对象不能安全创建 error # 505 无效的或无资格的引用 error # 506 类没有被定义 error # 507 出现一个意外错误 error # 1001 内存不够 error # 1002 语法错误 error # 1003 缺少 '':'' error # 1005 缺少 ''('' error # 1006 缺少 '')'' error # 1007 缺少 '']'' error # 1010 缺少标识符 error # 1011 缺少 ''='' error # 1012 缺少 ''If'' error # 1013 缺少 ''To'' error # 1014 缺少 ''End'' error # 1015 缺少 ''Function'' error # 1016 缺少 ''Sub'' error # 1017 缺少 ''Then'' error # 1018 缺少 ''Wend'' error # 1019 缺少 ''Loop'' error # 1020 缺少 ''Next'' error # 1021 缺少 ''Case'' error # 1022 缺少 ''Select'' error # 1023 缺少表达式 error # 1024 缺少语句 error # 1025 语句未结束 error # 1026 缺少整型常数 error # 1027 缺少 ''While'' 或 ''Until'' error # 1028 缺少 ''While'' 和 ''Until''或语句未结束 error # 1029 缺少 ''With'' error # 1030 标识符过长 error # 1031 无效数字 error # 1032 无效字符 error # 1033 未结束的字符串常量 error # 1034 注释未结束 error # 1037 无效使用 ''Me'' 关键字 error # 1038 ''loop'' 语句缺少 ''do'' error # 1039 无效的 ''exit'' 语句 error # 1040 循环控制变量 ''for'' 无效 error # 1041 名称重定义 error # 1042 必须是行中的第一个语句 error # 1043 不能为 non-ByVal 参数赋值 error # 1044 调用子程序时不能使用括号 error # 1045 缺少文字常数 error # 1046 缺少 ''In'' error # 1047 缺少 ''Class'' error # 1048 必须在一个类的内部定义 error # 1049 在属性声明中缺少 Let , Set 或 Get error # 1050 缺少 ''Property'' error # 1051 在所有属性的规范中,变量的数目必须一致 error # 1052 在一个类中不允许有多个缺省的属性/方法 error # 1053 类的初始化或终止程序没有变量 error # 1054 属性的 set 或 let 必须至少有一个变量 error # 1055 错误的 ''Next'' error # 1056 ''Default'' 只能在 ''Property'' , ''Function'' 或 ''Sub'' 中指定 error # 1057 指定 ''Default'' 时必须同时指定 ''Public'' error # 1058 只能在 Property Get 中指定 ''Default'' error # 4096 Microsoft VBScript 编译器错误 error # 4097 Microsoft VBScript 运行时错误 error # 5016 缺少正则表达式对象 error # 5017 正则表达式语法错误 error # 5018 错误的数量词 error # 5019 正则表达式中缺少 '']'' error # 5020 正则表达式中缺少 '')'' error # 5021 字符集越界<br /><br />13.利用ASP获得图象的实际尺寸的示例 <!--#i nclude virtual="/learn/test/lib_graphicdetect.asp"--> <html><head> <TITLE>dbtable.asp</TITLE> </head> <body bgcolor="#FFFFFF"> <% graphic="images/learnaspiconmain.gif" HW = ReadImg(graphic) Response.Write graphic &amp; " Dimensions: " &amp; HW(0) & "x" &amp; HW(1) & "<br/>" response.write "<img src="/sblog/"/" &amp; graphic & """" response.write height=""" &amp; HW(0) & """ response.write width=""" &amp; HW(0) & "">" %> </body></html><br />The library that is included is:<br /><% Dim HW<br />Function AscAt(s, n) AscAt = Asc(Mid(s, n, 1)) End Function<br />Function HexAt(s, n) HexAt = Hex(AscAt(s, n)) End Function<br />Function isJPG(fichero) If inStr(uCase(fichero), ".JPG") <> 0 Then isJPG = true Else isJPG = false End If End Function<br />Function isPNG(fichero) If inStr(uCase(fichero), ".PNG") <> 0 Then isPNG = true Else isPNG = false End If End Function<br />Function isGIF(fichero) If inStr(uCase(fichero), ".GIF") <> 0 Then isGIF = true Else isGIF = false End If End Function<br />Function isBMP(fichero) If inStr(uCase(fichero), ".BMP") <> 0 Then isBMP = true Else isBMP = false End If End Function<br />Function isWMF(fichero) If inStr(uCase(fichero), ".WMF") <> 0 Then isWMF = true Else isWMF = false End If End Function<br />Function isWebImg(f) If isGIF(f) Or isJPG(f) Or isPNG(f) Or isBMP(f) Or isWMF(f) Then isWebImg = true Else isWebImg = true End If End Function<br />Function ReadImg(fichero) If isGIF(fichero) Then ReadImg = ReadGIF(fichero) Else If isJPG(fichero) Then ReadImg = ReadJPG(fichero) Else If isPNG(fichero) Then ReadImg = ReadPNG(fichero) Else If isBMP(fichero) Then ReadImg = ReadPNG(fichero) Else If isWMF(fichero) Then ReadImg = ReadWMF(fichero) Else ReadImg = Array(0,0) End If End If End If End If End If End Function<br />Function ReadJPG(fichero) Dim fso, ts, s, HW, nbytes HW = Array("","") Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.OpenTextFile(Server.MapPath("/" &amp; fichero), 1) s = Right(ts.Read(167), 4) HW(0) = HexToDec(HexAt(s,3) & HexAt(s,4)) HW(1) = HexToDec(HexAt(s,1) &amp; HexAt(s,2)) ts.Close ReadJPG = HW End Function<br />Function ReadPNG(fichero) Dim fso, ts, s, HW, nbytes HW = Array("","") Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1) s = Right(ts.Read(24), 8) HW(0) = HexToDec(HexAt(s,3) &amp; HexAt(s,4)) HW(1) = HexToDec(HexAt(s,7) & HexAt(s,8)) ts.Close ReadPNG = HW End Function<br />Function ReadGIF(fichero) Dim fso, ts, s, HW, nbytes HW = Array("","") Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.OpenTextFile(Server.MapPath("/" &amp; fichero), 1) s = Right(ts.Read(10), 4) HW(0) = HexToDec(HexAt(s,2) & HexAt(s,1)) HW(1) = HexToDec(HexAt(s,4) &amp; HexAt(s,3)) ts.Close ReadGIF = HW End Function<br />Function ReadWMF(fichero) Dim fso, ts, s, HW, nbytes HW = Array("","") Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.OpenTextFile(Server.MapPath("/" & fichero), 1) s = Right(ts.Read(14), 4) HW(0) = HexToDec(HexAt(s,2) &amp; HexAt(s,1)) HW(1) = HexToDec(HexAt(s,4) & HexAt(s,3)) ts.Close ReadWMF = HW End Function<br />Function ReadBMP(fichero) Dim fso, ts, s, HW, nbytes HW = Array("","") Set fso = CreateObject("Scripting.FileSystemObject") Set ts = fso.OpenTextFile(Server.MapPath("/" &amp; fichero), 1) s = Right(ts.Read(24), 8) HW(0) = HexToDec(HexAt(s,4) & HexAt(s,3)) HW(1) = HexToDec(HexAt(s,8) &amp; HexAt(s,7)) ts.Close ReadBMP = HW End Function<br />Function isDigit(c) If inStr("0123456789", c) <> 0 Then isDigit = true Else isDigit = false End If End Function<br />Function isHex(c) If inStr("0123456789ABCDEFabcdef", c) <> 0 Then isHex = true Else ishex = false End If End Function<br />Function HexToDec(cadhex) Dim n, i, ch, decimal decimal = 0 n = Len(cadhex) For i=1 To n ch = Mid(cadhex, i, 1) If isHex(ch) Then decimal = decimal * 16 If isDigit(c) Then decimal = decimal + ch Else decimal = decimal + Asc(uCase(ch)) - Asc("A") End If Else HexToDec = -1 End If Next HexToDec = decimal End Function %><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114999913441855964?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1163096054883549542006-06-10T01:47:00.000+08:002006-11-10T02:14:15.043+08:00利用自带biremove.exe完美卸载BlackIce嘿嘿!<br />BlackIce是不是把你惹火了?当你想干掉它时它是不是说:<br />“failed to get product version from c:\windows\biversion.dll. code: -1”<br />哈,你找对地方了<br />你不妨运行一下blackice安装目录下的biremove.exe小程序<br />记住先在windows任务管理器里结束blackice的系统进程哦!<br /><br />这下问题解决了吧?<br />如果它还说:“failed to get product version from c:\windows\biversion.dll. code: -1”<br />那俺就无语咯!<br />睡觉去....zzZZzzZzzZzZ<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-116309605488354954?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1146249847777966872006-04-29T02:42:00.000+08:002006-04-29T02:47:20.440+08:00Ajax 简介Ajax 由 HTML、JavaScript? 技术、DHTML 和 DOM 组成,这一杰出的方法可以将笨拙的 Web 界面转化成交互性的 Ajax 应用程序。本文的作者是一位 Ajax 专家,他演示了这些技术如何协同工作 ?? 从总体概述到细节的讨论 ?? 使高效的 Web 开发成为现实。他还揭开了 Ajax 核心概念的神秘面纱,包括 XMLHttpRequest 对象。<br /><br />五年前,如果不知道 XML,您就是一只无人重视的丑小鸭。十八个月前,Ruby 成了关注的中心,不知道 Ruby 的程序员只能坐冷板凳了。今天,如果想跟上最新的技术时尚,那您的目标就是 Ajax。<br /><br />但是,Ajax 不仅仅 是一种时尚,它是一种构建网站的强大方法,而且不像学习一种全新的语言那样困难。<br /><br />但在详细探讨 Ajax 是什么之前,先让我们花几分钟了解 Ajax 做 什么。目前,编写应用程序时有两种基本的选择:<br /><br />1.桌面应用程序<br /><br />2.Web 应用程序 <br /><br />两者是类似的,桌面应用程序通常以 CD 为介质(有时候可从网站下载)并完全安装到您的计算机上。桌面应用程序可能使用互联网下载更新,但运行这些应用程序的代码在桌面计算机上。Web 应用程序运行在某处的 Web 服务器上 ?? 毫不奇怪,要通过 Web 浏览器访问这种应用程序。<br /><br />不过,比这些应用程序的运行代码放在何处更重要的是,应用程序如何运转以及如何与其进行交互。桌面应用程序一般很快(就在您的计算机上运行,不用等待互联网连接),具有漂亮的用户界面(通常和操作系统有关)和非凡的动态性。可以单击、选择、输入、打开菜单和子菜单、到处巡游,基本上不需要等待。<br /><br />另一方面,Web 应用程序是最新的潮流,它们提供了在桌面上不能实现的服务(比如 Amazon.com 和 eBay)。但是,伴随着 Web 的强大而出现的是等待,等待服务器响应,等待屏幕刷新,等待请求返回和生成新的页面。<br /><br />显然这样说过于简略了,但基本的概念就是如此。您可能已经猜到,Ajax 尝试建立桌面应用程序的功能和交互性,与不断更新的 Web 应用程序之间的桥梁。可以使用像桌面应用程序中常见的动态用户界面和漂亮的控件,不过是在 Web 应用程序中。<br /><br />还等什么呢?我们来看看 Ajax 如何将笨拙的 Web 界面转化成能迅速响应的 Ajax 应用程序吧。<br /><br />老技术,新技巧<br /><br />在谈到 Ajax 时,实际上涉及到多种技术,要灵活地运用它必须深入了解这些不同的技术(本系列的头几篇文章将分别讨论这些技术)。好消息是您可能已经非常熟悉其中的大部分技术,更好的是这些技术都很容易学习,并不像完整的编程语言(如 Java 或 Ruby)那样困难。<br /><br />Ajax 的定义<br /><br />顺便说一下,Ajax 是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写。这个短语是 Adaptive Path 的 Jesse James Garrett 发明的(请参阅 参考资料),按照 Jesse 的解释,这不是 个首字母缩写词。<br /><br /><br />下面是 Ajax 应用程序所用到的基本技术:<br /><br />HTML 用于建立 Web 表单并确定应用程序其他部分使用的字段。 <br />JavaScript 代码是运行 Ajax 应用程序的核心代码,帮助改进与服务器应用程序的通信。 <br />DHTML 或 Dynamic HTML,用于动态更新表单。我们将使用 div、span 和其他动态 HTML 元素来标记 HTML。 <br />文档对象模型 DOM 用于(通过 JavaScript 代码)处理 HTML 结构和(某些情况下)服务器返回的 XML。 <br />我们来进一步分析这些技术的职责。以后的文章中我将深入讨论这些技术,目前只要熟悉这些组件和技术就可以了。对这些代码越熟悉,就越容易从对这些技术的零散了解转变到真正把握这些技术(同时也真正打开了 Web 应用程序开发的大门)。<br /><br />XMLHttpRequest 对象<br /><br />要了解的一个对象可能对您来说也是最陌生的,即 XMLHttpRequest。这是一个 JavaScript 对象,创建该对象很简单,如清单 1 所示。<br /><br /><br />清单 1. 创建新的 XMLHttpRequest 对象<br /><br /><br /><script language="javascript" type="text/javascript"><br />var xmlHttp = new XMLHttpRequest();<br /></script><br /><br /><br /><br />下一期文章中将进一步讨论这个对象,现在要知道这是处理所有服务器通信的对象。继续阅读之前,先停下来想一想:通过 XMLHttpRequest 对象与服务器进行对话的是 JavaScript 技术。这不是一般的应用程序流,这恰恰是 Ajax 的强大功能的来源。<br /><br />在一般的 Web 应用程序中,用户填写表单字段并单击 Submit 按钮。然后整个表单发送到服务器,服务器将它转发给处理表单的脚本(通常是 PHP 或 Java,也可能是 CGI 进程或者类似的东西),脚本执行完成后再发送回全新的页面。该页面可能是带有已经填充某些数据的新表单的 HTML,也可能是确认页面,或者是具有根据原来表单中输入数据选择的某些选项的页面。当然,在服务器上的脚本或程序处理和返回新表单时用户必须等待。屏幕变成一片空白,等到服务器返回数据后再重新绘制。这就是交互性差的原因,用户得不到立即反馈,因此感觉不同于桌面应用程序。<br /><br />Ajax 基本上就是把 JavaScript 技术和 XMLHttpRequest 对象放在 Web 表单和服务器之间。当用户填写表单时,数据发送给一些 JavaScript 代码而不是 直接发送给服务器。相反,JavaScript 代码捕获表单数据并向服务器发送请求。同时用户屏幕上的表单也不会闪烁、消失或延迟。换句话说,JavaScript 代码在幕后发送请求,用户甚至不知道请求的发出。更好的是,请求是异步发送的,就是说 JavaScript 代码(和用户)不用等待服务器的响应。因此用户可以继续输入数据、滚动屏幕和使用应用程序。<br /><br />然后,服务器将数据返回 JavaScript 代码(仍然在 Web 表单中),后者决定如何处理这些数据。它可以迅速更新表单数据,让人感觉应用程序是立即完成的,表单没有提交或刷新而用户得到了新数据。JavaScript 代码甚至可以对收到的数据执行某种计算,再发送另一个请求,完全不需要用户干预!这就是 XMLHttpRequest 的强大之处。它可以根据需要自行与服务器进行交互,用户甚至可以完全不知道幕后发生的一切。结果就是类似于桌面应用程序的动态、快速响应、高交互性的体验,但是背后又拥有互联网的全部强大力量。<br /><br />加入一些 JavaScript<br /><br />得到 XMLHttpRequest 的句柄后,其他的 JavaScript 代码就非常简单了。事实上,我们将使用 JavaScript 代码完成非常基本的任务:<br /><br />获取表单数据:JavaScript 代码很容易从 HTML 表单中抽取数据并发送到服务器。 <br />修改表单上的数据:更新表单也很简单,从设置字段值到迅速替换图像。 <br />解析 HTML 和 XML:使用 JavaScript 代码操纵 DOM(请参阅 下一节),处理 HTML 表单服务器返回的 XML 数据的结构。 <br />对于前两点,需要非常熟悉 getElementById() 方法,如 清单 2 所示。<br /><br /><br />清单 2. 用 JavaScript 代码捕获和设置字段值<br /><br /><br />// Get the value of the "phone" field and stuff it in a variable called phone<br />var phone = document.getElementById("phone").value;<br /><br />// Set some values on a form using an array called response<br />document.getElementById("order").value = response[0];<br />document.getElementById("address").value = response[1];<br /><br /><br /><br />这里没有特别需要注意的地方,真是好极了!您应该认识到这里并没有非常复杂的东西。只要掌握了 XMLHttpRequest,Ajax 应用程序的其他部分就是如 清单 2 所示的简单 JavaScript 代码了,混合有少量的 HTML。同时,还要用一点儿 DOM,我们就来看看吧。<br /><br />以 DOM 结束<br /><br />最后还有 DOM,即文档对象模型。可能对有些读者来说 DOM 有点儿令人生畏,HTML 设计者很少使用它,即使 JavaScript 程序员也不大用到它,除非要完成某项高端编程任务。大量使用 DOM 的是 复杂的 Java 和 C/C++ 程序,这可能就是 DOM 被认为难以学习的原因。<br /><br />幸运的是,在 JavaScript 技术中使用 DOM 很容易,也非常直观。现在,按照常规也许应该说明如何使用 DOM,或者至少要给出一些示例代码,但这样做也可能误导您。即使不理会 DOM,仍然能深入地探讨 Ajax,这也是我准备采用的方法。以后的文章将再次讨论 DOM,现在只要知道可能需要 DOM 就可以了。当需要在 JavaScript 代码和服务器之间传递 XML 和改变 HTML 表单的时候,我们再深入研究 DOM。没有它也能做一些有趣的工作,因此现在就把 DOM 放到一边吧。<br /><br />获取 Request 对象<br /><br />有了上面的基础知识后,我们来看看一些具体的例子。XMLHttpRequest 是 Ajax 应用程序的核心,而且对很多读者来说可能还比较陌生,我们就从这里开始吧。从 清单 1 可以看出,创建和使用这个对象非常简单,不是吗?等一等。<br /><br />还记得几年前的那些讨厌的浏览器战争吗?没有一样东西在不同的浏览器上得到同样的结果。不管您是否相信,这些战争仍然在继续,虽然规模较小。但令人奇怪的是,XMLHttpRequest 成了这场战争的牺牲品之一。因此获得 XMLHttpRequest 对象可能需要采用不同的方法。下面我将详细地进行解释。<br /><br />使用 Microsoft 浏览器<br /><br />Microsoft 浏览器 Internet Explorer 使用 MSXML 解析器处理 XML(可以通过 参考资料 进一步了解 MSXML)。因此如果编写的 Ajax 应用程序要和 Internet Explorer 打交道,那么必须用一种特殊的方式创建对象。<br /><br />但并不是这么简单。根据 Internet Explorer 中安装的 JavaScript 技术版本不同,MSXML 实际上有两种不同的版本,因此必须对这两种情况分别编写代码。请参阅 清单 3,其中的代码在 Microsoft 浏览器上创建了一个 XMLHttpRequest。<br /><br /><br />清单 3. 在 Microsoft 浏览器上创建 XMLHttpRequest 对象<br /><br /><br />var xmlHttp = false;<br />try {<br />xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");<br />} catch (e) {<br />try {<br />xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br />} catch (e2) {<br />xmlHttp = false;<br />}<br />}<br /><br /><br /><br />您对这些代码可能还不完全理解,但没有关系。当本系列文章结束的时候,您将对 JavaScript 编程、错误处理、条件编译等有更深的了解。现在只要牢牢记住其中的两行代码:<br /><br />xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");<br /><br />和<br /><br />xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");。<br /><br />这两行代码基本上就是尝试使用一个版本的 MSXML 创建对象,如果失败则使用另一个版本创建该对象。不错吧?如果都不成功,则将 xmlHttp 变量设为 false,告诉您的代码出现了问题。如果出现这种情况,可能是因为安装了非 Microsoft 浏览器,需要使用不同的代码。<br /><br />处理 Mozilla 和非 Microsoft 浏览器<br /><br />如果选择的浏览器不是 Internet Explorer,或者为非 Microsoft 浏览器编写代码,就需要使用不同的代码。事实上就是 清单 1 所示的一行简单代码:<br /><br />var xmlHttp = new XMLHttpRequest object;。<br /><br />这行简单得多的代码在 Mozilla、Firefox、Safari、Opera 以及基本上所有以任何形式或方式支持 Ajax 的非 Microsoft 浏览器中,创建了 XMLHttpRequest 对象。<br /><br />结合起来<br /><br />关键是要支持所有 浏览器。谁愿意编写一个只能用于 Internet Explorer 或者非 Microsoft 浏览器的应用程序呢?或者更糟,要编写一个应用程序两次?当然不!因此代码要同时支持 Internet Explorer 和非 Microsoft 浏览器。清单 4 显示了这样的代码。<br /><br /><br />清单 4. 以支持多种浏览器的方式创建 XMLHttpRequest 对象<br /><br /><br />/* Create a new XMLHttpRequest object to talk to the Web server */<br />var xmlHttp = false;<br />/*@cc_on @*/<br />/*@if (@_jscript_version >= 5)<br />try {<br />xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");<br />} catch (e) {<br />try {<br />xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");<br />} catch (e2) {<br />xmlHttp = false;<br />}<br />}<br />@end @*/<br /><br />if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {<br />xmlHttp = new XMLHttpRequest();<br />}<br /><br /><br />现在先不管那些注释掉的奇怪符号,如 @cc_on,这是特殊的 JavaScript 编译器命令,将在下一期针对 XMLHttpRequest 的文章中详细讨论。这段代码的核心分为三步:<br /><br />建立一个变量 xmlHttp 来引用即将创建的 XMLHttpRequest 对象。 <br />尝试在 Microsoft 浏览器中创建该对象: <br />尝试使用 Msxml2.XMLHTTP 对象创建它。 <br />如果失败,再尝试 Microsoft.XMLHTTP 对象。 <br />如果仍然没有建立 xmlHttp,则以非 Microsoft 的方式创建该对象。 <br />最后,xmlHttp 应该引用一个有效的 XMLHttpRequest 对象,无论运行什么样的浏览器。<br /><br />关于安全性的一点说明<br /><br />安全性如何呢?现在浏览器允许用户提高他们的安全等级,关闭 JavaScript 技术,禁用浏览器中的任何选项。在这种情况下,代码无论如何都不会工作。此时必须适当地处理问题,这需要单独的一篇文章来讨论,要放到以后了(这个系列够长了吧?不用担心,读完之前也许您就掌握了)。现在要编写一段健壮但不够完美的代码,对于掌握 Ajax 来说就很好了。以后我们还将讨论更多的细节。<br /><br />Ajax 世界中的请求/响应<br /><br />现在我们介绍了 Ajax,对 XMLHttpRequest 对象以及如何创建它也有了基本的了解。如果阅读得很仔细,您可能已经知道与服务器上的 Web 应用程序打交道的是 JavaScript 技术,而不是直接提交给那个应用程序的 HTML 表单。<br /><br />还缺少什么呢?到底如何使用 XMLHttpRequest。因为这段代码非常重要,您编写的每个 Ajax 应用程序都要以某种形式使用它,先看看 Ajax 的基本请求/响应模型是什么样吧。<br /><br />发出请求<br /><br />您已经有了一个崭新的 XMLHttpRequest 对象,现在让它干点活儿吧。首先需要一个 Web 页面能够调用的 JavaScript 方法(比如当用户输入文本或者从菜单中选择一项时)。接下来就是在所有 Ajax 应用程序中基本都雷同的流程:<br /><br />从 Web 表单中获取需要的数据。 <br />建立要连接的 URL。 <br />打开到服务器的连接。 <br />设置服务器在完成后要运行的函数。 <br />发送请求。 <br />清单 5 中的示例 Ajax 方法就是按照这个顺序组织的:<br /><br /><br />清单 5. 发出 Ajax 请求<br /><br /><br />function callServer() {<br />// Get the city and state from the web form<br />var city = document.getElementById("city").value;<br />var state = document.getElementById("state").value;<br />// Only go on if there are values for both fields<br />if ((city == null) || (city == "")) return;<br />if ((state == null) || (state == "")) return;<br /><br />// Build the URL to connect to<br />var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);<br /><br />// Open a connection to the server<br />xmlHttp.open("GET", url, true);<br /><br />// Setup a function for the server to run when it's done<br />xmlHttp.onreadystatechange = updatePage;<br /><br />// Send the request<br />xmlHttp.send(null);<br />}<br /><br /><br />其中大部分代码意义都很明确。开始的代码使用基本 JavaScript 代码获取几个表单字段的值。然后设置一个 PHP 脚本作为链接的目标。要注意脚本 URL 的指定方式,city 和 state(来自表单)使用简单的 GET 参数附加在 URL 之后。<br /><br />然后打开一个连接,这是您第一次看到使用 XMLHttpRequest。其中指定了连接方法(GET)和要连接的 URL。最后一个参数如果设为 true,那么将请求一个异步连接(这就是 Ajax 的由来)。如果使用 false,那么代码发出请求后将等待服务器返回的响应。如果设为 true,当服务器在后台处理请求的时候用户仍然可以使用表单(甚至调用其他 JavaScript 方法)。<br /><br />xmlHttp(要记住,这是 XMLHttpRequest 对象实例)的 onreadystatechange 属性可以告诉服务器在运行完成 后(可能要用五分钟或者五个小时)做什么。因为代码没有等待服务器,必须让服务器知道怎么做以便您能作出响应。在这个示例中,如果服务器处理完了请求,一个特殊的名为 updatePage() 的方法将被触发。<br /><br />最后,使用值 null 调用 send()。因为已经在请求 URL 中添加了要发送给服务器的数据(city 和 state),所以请求中不需要发送任何数据。这样就发出了请求,服务器按照您的要求工作。<br /><br />如果没有发现任何新鲜的东西,您应该体会到这是多么简单明了!除了牢牢记住 Ajax 的异步特性外,这些内容都相当简单。应该感激 Ajax 使您能够专心编写漂亮的应用程序和界面,而不用担心复杂的 HTTP 请求/响应代码。<br /><br />清单 5 中的代码说明了 Ajax 的易用性。数据是简单的文本,可以作为请求 URL 的一部分。用 GET 而不是更复杂的 POST 发送请求。没有 XML 和要添加的内容头部,请求体中没有要发送的数据;换句话说,这就是 Ajax 的乌托邦。<br /><br />不用担心,随着本系列文章的展开,事情会变得越来越复杂。您将看到如何发送 POST 请求、如何设置请求头部和内容类型、如何在消息中编码 XML、如何增加请求的安全性,可以做的工作还有很多!暂时先不用管那些难点,掌握好基本的东西就行了,很快我们就会建立一整套的 Ajax 工具库。<br /><br />处理响应<br /><br />现在要面对服务器的响应了。现在只要知道两点:<br /><br />什么也不要做,直到 xmlHttp.readyState 属性的值等于 4。 <br />服务器将把响应填充到 xmlHttp.responseText 属性中。 <br />其中的第一点,即就绪状态,将在下一篇文章中详细讨论,您将进一步了解 HTTP 请求的阶段,可能比您设想的还多。现在只要检查一个特定的值(4)就可以了(下一期文章中还有更多的值要介绍)。第二点,使用 xmlHttp.responseText 属性获得服务器的响应,这很简单。清单 6 中的示例方法可供服务器根据 清单 5 中发送的数据调用。<br /><br /><br />清单 6. 处理服务器响应<br /><br /><br />function updatePage() {<br />if (xmlHttp.readyState == 4) {<br />var response = xmlHttp.responseText;<br />document.getElementById("zipCode").value = response;<br />}<br />}<br /><br /><br /><br />这些代码同样既不难也不复杂。它等待服务器调用,如果是就绪状态,则使用服务器返回的值(这里是用户输入的城市和州的 ZIP 编码)设置另一个表单字段的值。于是包含 ZIP 编码的 zipCode 字段突然出现了,而用户没有按任何按钮!这就是前面所说的桌面应用程序的感觉。快速响应、动态感受等等,这些都只因为有了小小的一段 Ajax 代码。<br /><br />细心的读者可能注意到 zipCode 是一个普通的文本字段。一旦服务器返回 ZIP 编码,updatePage() 方法就用城市/州的 ZIP 编码设置那个字段的值,用户就可以改写该值。这样做有两个原因:保持例子简单,说明有时候可能希望 用户能够修改服务器返回的数据。要记住这两点,它们对于好的用户界面设计来说很重要。<br /><br /><br />连接 Web 表单<br /><br />还有什么呢?实际上没有多少了。一个 JavaScript 方法捕捉用户输入表单的信息并将其发送到服务器,另一个 JavaScript 方法监听和处理响应,并在响应返回时设置字段的值。所有这些实际上都依赖于调用 第一个 JavaScript 方法,它启动了整个过程。最明显的办法是在 HTML 表单中增加一个按钮,但这是 2001 年的办法,您不这样认为吗?还是像 清单 7 这样利用 JavaScript 技术吧。<br /><br /><br />清单 7. 启动一个 Ajax 过程<br /><br /><br /><form><br /><p>City: <input type="text" name="city" id="city" size="25" <br />onChange="callServer();" /></p><br /><p>State: <input type="text" name="state" id="state" size="25" <br />onChange="callServer();" /></p><br /><p>Zip Code: <input type="text" name="zipCode" id="city" size="5" /></p><br /></form><br /><br /><br /><br />如果感觉这像是一段相当普通的代码,那就对了,正是如此!当用户在 city 或 state 字段中输入新的值时,callServer() 方法就被触发,于是 Ajax 开始运行了。有点儿明白怎么回事了吧?好,就是如此!<br /><br /><br />结束语<br /><br />现在您可能已经准备开始编写第一个 Ajax 应用程序了,至少也希望认真读一下 参考资料 中的那些文章了吧?但可以首先从这些应用程序如何工作的基本概念开始,对 XMLHttpRequest 对象有基本的了解。在下一期文章中,您将掌握这个对象,学会如何处理 JavaScript 和服务器的通信、如何使用 HTML 表单以及如何获得 DOM 句柄。<br /><br />现在先花点儿时间考虑考虑 Ajax 应用程序有多么强大。设想一下,当单击按钮、输入一个字段、从组合框中选择一个选项或者用鼠标在屏幕上拖动时,Web 表单能够立刻作出响应会是什么情形。想一想异步 究竟意味着什么,想一想 JavaScript 代码运行而且不等待 服务器对它的请求作出响应。会遇到什么样的问题?会进入什么样的领域?考虑到这种新的方法,编程的时候应如何改变表单的设计?<br /><br />如果在这些问题上花一点儿时间,与简单地剪切/粘贴某些代码到您根本不理解的应用程序中相比,收益会更多。在下一期文章中,我们将把这些概念付诸实践,详细介绍使应用程序按照这种方式工作所需要的代码。因此,现在先享受一下 Ajax 所带来的可能性吧。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114624984777796687?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1147088099084659812006-04-17T19:33:00.000+08:002006-05-08T19:34:59.106+08:00如何学习C++语言How To Learn C++ Programming Language<br /><br /><br />"关于学C++, 我向你推荐一些书(当然能够结合课内项目实践更好)<br /><br />1。The C++ Programming Language(Bjarne Stroustrup)<br /><br /><br />2。 Inside The C++ Object Model (Stanley B. Lippman)<br />(这本书介绍一些C++的内部实现)<br /><br /><br />3。Advanced C++ Programming Styles And Idioms (James O. Coplien)<br />(这本书介绍一些C++编程的习惯用法)<br /><br /><br />4。 STL Tutorial and Reference Guide (David R. Musser) (Professor Musser<br /><br /><br />是我母校的教授,STL的创始人之一。这本书介绍Generic Programming 的思想和标准)。<br /><br /><br />5。 Design Patterns (Erich Gamma) (很精典的面向对象设计的组件和实例)<br /><br />当然,看任何一本书的时候都要动手(试例程或做习题)。然后尝试着在课堂项目中把书中的方法试验一下,以加深印象。"<br /><br /><br /><br />国外C++几乎所有的教材都被翻译为中文了,如果没有翻译的也已经有影印版出版。<br /><br />TCPL和D&E<br /><br />TCPL和D&amp;E分别是《The C++ Programming Language》和《The Design and Evolution of C++》的简称,均出自Bjarne Stroustrup之手。说它们是C++语言圣经,并不为过。<br /><br />中文名称:<br />《C++程序设计语言(特别版)》,机械工业出版社<br />《C++语言的设计和演化》,机械工业出版社<br /><br />入门教程<br />Stanley B.Lippman, Josee Lajoie, C++ Primer (3rd Edition)<br />《C++ Primer (3RD)中文版》,中国电力出版社<br />Stanley B. Lippman, Essential C++<br />《Essential C++中文版》,华中科技大学出版社<br />《Essential C++(影印版)》,中国电力出版社<br /><br />高效、健壮编程<br />《Effective C++中文版》,华中科技大学出版社<br />《More Effective C++中文版》,中国电力出版社<br />《Exceptional C++中文版》,中国电力出版社<br />《More Exceptional C++中文版》,华中科技大学出版社<br /><br />模板和泛型编程<br />《C++ Templates全览(简体版)》,人民邮电出版社<br />《C++设计新思维:泛型编程与设计模式之应用》,华中科技大学出版社<br /><br />标准库<br />《C++标准程序库:自修教程与参考手册》,华中科技大学出版社<br />《Effective STL(影印版)》,中国电力出版社<br /><br />网络编程<br />《C++网络编程,卷1:运用ACE和模式消除复杂性》,华中科技大学出版社<br />《C++网络编程,卷2:基于 ACE 和框架的系统化复用》,电子工业出版社<br /><br />杂项<br />《C++编程思想(第2版)第1卷:标准C++导引》,机械工业出版社<br />《C++编程思想(英文版 第2版)》,机械工业出版社<br />《C++沉思录》,人民邮电出版社<br />《深度探索C++对象模型》,华中科技大学出版社<br />《深度探索C++对象模型(影印版)》,中国电力出版社<br /><br />C++工程领域的最高境界:<br />《设计模式:可复用面向对象软件的基础》,机械工业出版社<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114708809908465981?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1143214489270201262006-03-24T23:28:00.000+08:002006-03-25T00:00:43.333+08:00用VB将ASP代码封装成DLL摘 要 主要介绍用VB将ASP代码封装成DLL以保护 ASP代码和加快ASP代码的执行速度、节省服务器的资源<br />关键词 ASP,DLL,编程<br />一、 引言<br />Server端的脚本运行环境,它简单易用,不需要编译和连接,脚本可以在 Server端直接运行,并且它支持多用户、多线程,在 Web开发中得到了广泛的应用。服务器端的组件有别于客户端的组件。客户端的组件是通过网络传输,依靠HTML来起作用,而且只能在IE上有用。但是服务器端的组件是运行在服务器端,它在服务器上执行各种操作。因此,所有的浏览器都能享用,它依靠的是服务器而不是浏览器。但是,因为 ASP脚本是纯文本格式,所以恶意者通过源代码可以很容易地看到原本不该看到的页面内容。因此,保护ASP源代码显得非常重要。将ASP代码封装成DLL,不仅加快了ASP代码的执行速度,而且也能保护原代码。当IIS被请求执行一个ASP程序,它首先会在ASP文件中找到标签之间的代码,并且执行它(也可以是<script runat="server"></script><br /><br />之间的代码)。如果这个ASP程序在先前被调用过,那么它就会用内存中的编译过的程序来向用户返回HTML代码,如果没有,那么它就重新编译。这样就大大节省了服务器的资源。<br />二、实现方法<br />启动你的VB,选择ActiveX图标。这个图标可以在新建工程找到!VB会提供一个默认的工程名(project1)和类名(class1)。在动手之前请首先确认我们拥有Microsoft ActiveX Data Object 2.0 Library,它在我们的程序非常有用。从菜单中选择"工程",然后在其中选择"引用",就会出现"引用"窗口从中选择Microsoft ActiveX Data Object 2.0 Library。<br />现在我们有了我们自己的工程(project1)和类名(class1)。以后我们就会在ASP代码中使用它们的名字来引用这个组件。在ASP中我们就这样引用,如下:<br />Set ObjReference = Server.CreateObject("ProjectName.ClassName")<br />为了在类中使用ASP的方法,你必须在此类中写上初始和终止这两个函数。输入如下代码:程序清单中Class1.cls中的Private Sub Class_Initialize()和Private Sub Class_Terminate()。<br />将ASP代码中的关键功能制作成动态链接库(.dll),部分隐藏 ASP源代码。 例如:程序清单中的Global.bas和Class1.cls中输入的代码(代码的主要功能是检索数据库中的记录并显示出来)。<br />在VB的下拉菜单中选择文件→生成article.dll→选择要保存的目录。找到article.dll将其复制到系统盘system32文件夹中,最后一步注册DLL文件。在开始菜单中选择运行输入regsvr32 c:\winnt\system32\article.dll。<br />三、程序清单<br />Global.bas中的代码:<br /><blockquote><br />Public objContext As ObjectContext<br />Public Application As ASPTypeLibrary.Application<br />Public Server As ASPTypeLibrary.Server<br />Public Session As ASPTypeLibrary.Session<br />Public Response As ASPTypeLibrary.Response<br />Public Request As ASPTypeLibrary.Request<br /></blockquote><br />Class1.cls中的代码:<br /><blockquote><br />Private Sub Class_Initialize()<br />On Error Resume Next<br />Set objContext = GetObjectContext<br />Set Application = objContext.Item("Application")<br />Set Server = objContext.Item("Server")<br />Set Session = objContext.Item("Session")<br />Set Request = objContext.Item("Request")<br />Set Response = objContext.Item("Response")<br />End Sub<br />Private Sub Class_Terminate()<br />On Error Resume Next<br />Set Application = Nothing<br />Set Server = Nothing<br />Set Session = Nothing<br />Set Request = Nothing<br />Set Response = Nothing<br />Set objContext = Nothing<br />End Sub<br />Public Sub AspClassInit()<br />On Error GoTo Err<br />Set conn = Server.CreateObject("ADODB.Connection")<br />strcon = "Provider=Microsoft.Jet.OLEDB.4.0;" & _<br />"Data Source=" &amp; Server.MapPath("Article.mdb")<br />conn.Open strcon<br />Set rs = Server.CreateObject("ADODB.Recordset")<br />sql = "select * from Article order by ArticleID desc"<br />rs.Open sql, conn, 1, 1<br />Response.Write "<html>" & vbCrLf<br />Response.Write "<head>" &amp; vbCrLf<br />Response.Write "<meta http-equiv=""Content-Type"" content=""text/html; charset=gb2312"">" & vbCrLf<br />Response.Write "<title>文章管理系统-CSSTUDIO</title>" &amp; vbCrLf<br />Response.Write "</head>" & vbCrLf<br />Response.Write "<body bgcolor=""#FFFFFF"" topmargin=""0"">" &amp; vbCrLf<br />Response.Write "<table width=""100%"" border=""0"" cellpadding=""2"" cellspacing=""0"">" & vbCrLf<br />Response.Write " <tr>" &amp; vbCrLf<br />Response.Write " <td width=""742"" height=""20"">文章标题</td>" & vbCrLf<br />Response.Write " <td width=""90"">点击</td>" &amp; vbCrLf<br />Response.Write " <td width=""145"">添加日期</td>" & vbCrLf<br />Response.Write " </tr>" &amp; vbCrLf<br />Response.Write "</table>" & vbCrLf<br />While Not rs.EOF And Rows < id=" Response.Write rs(" cellspacing="0" cellpadding="0" border="1" href="">" &amp; vbCrLf<br />Response.Write " "<br />Response.Write rs("标题")<br />Response.Write "</a></td>" & vbCrLf<br />Response.Write " <td width=""94"">"<br />Response.Write rs("点击")<br />Response.Write "</td>" &amp; vbCrLf<br />Response.Write " <td width=""148"">"<br />Response.Write rs("添加日期")<br />Response.Write "</td>" & vbCrLf<br />Response.Write " </tr>" &amp; vbCrLf<br />Response.Write "</table>" & vbCrLf<br />rs.MoveNext<br />Wend<br />Response.Write "</body>" &amp; vbCrLf<br />Response.Write "</html>" & vbCrLf<br />rs.Close<br />Set rs = Nothing<br />conn.Close<br />Set conn = Nothing<br />Exit Sub<br />Err:<br />If Err.Number = -13572468 Then Exit Sub<br />Resume Next<br />End Sub<br /><blockquote></blockquote><br />使用article.dll后的index.asp中的代码:<br /><blockquote><br /><%Dim AspTransBuilderObject Set AspTransBuilderObject = Server.CreateObject("article.Class1") AspTransBuilderObject.AspClassInit Set AspTransBuilderObject = Nothing%><br /></blockquote><br />使用article.dll前的index.asp中的代码:<br /><blockquote><br /><% Set conn=Server.CreateObject("ADODB.Connection")<br />strcon = "Provider=Microsoft.Jet.OLEDB.4.0;" & _<br />"Data Source=" &amp; Server.MapPath("Article.mdb")<br />conn.Open strcon %><br /><% Set rs = Server.CreateObject ("ADODB.Recordset")<br />sql="select * from Article order by ArticleID desc"<br />rs.Open sql, Conn,1,1 %><br /><html><br /><head><br /><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><br /><title>文章管理系统-CSSTUDIO</title><br /></head><br /><body bgcolor="#FFFFFF" topmargin="0"><br /><table width="100%" border="0" cellpadding="2" cellspacing="0"><br /><tr><br /><td width="742" height="20">文章标题</td><br /><td width="90">点击</td><br /><td width="145">添加日期</td><br /></tr><br /></table><br /><% While Not Rs.Eof And Rows<Rs.PageSize %><br /><table width="100%" border="0" cellspacing="0" cellpadding="0"><br /><tr><br /><td width="747" height="20">☆<a href="view.asp?id=<% = rs("ArticleID") %>"><br /><% =rs("标题") %></a></td><br /><td width="94"><% = rs("点击") %></td><br /><td width="148"><% = rs("添加日期") %></td><br /></tr><br /></table><br /><% Rs.MoveNext<br />Wend %><br /></body><br /></html><br /><% rs.close<br />set rs=nothing<br />conn.close<br />set conn=nothing %><br /></blockquote><br /><br />四、结论<br />因为这些代码是在服务器端运行的,所以客户端不需要安装任何东西。这仅仅是用ActiveX DLL所能实现的功能的小小的例子。你们可以写好自己的更大的组件,而且还可以用VB中的很多控件。让我们用组件来扩展我们的程序的功能吧!也希望多多的看到我们中国人的组件。但愿本文能起到抛砖引玉的作用。 <div></div><tbody></tbody><blockquote></blockquote><div></div><blockquote></blockquote><div></div><blockquote></blockquote><div></div><blockquote></blockquote><div></div><blockquote></blockquote><div></div><blockquote></blockquote><div></div><blockquote></blockquote><div></div><blockquote></blockquote><br /></blockquote><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114321448927020126?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1143228041972748842006-03-22T06:13:00.000+08:002006-03-25T03:23:53.816+08:00使用Web标准建站第11天:不用表格的菜单布局初步搭建起来,我开始填充里面的内容。首先是定义logo图片:  样式表:#logo {MARGIN: 0px;padding:0px;WIDTH: 200px;HEIGHT:80px;}<br /><br />  页面代码: <div id="logo"><a title="网页设计师" href="http://www.w3cn.org/" ><img height="80" alt="链接到w3cn.org首页" src="images/logo_w3cn_200x80.gif" width="200" /></a></div>以上代码现在应该容易理解。先在CSS定义了一个logo的层,然后在页面中调用它。需要说明的是,为了使网页有更好的易用性,web标准要求大家给所有的、属于正式内容的图片,加一个alt属性。这个alt属性是用来说明图片的作用(当图片不能显示的时候就显示替换文字),所以不要只写成无意义的图片名称。<br />  接下来是定义菜单。<br />1.不用表格的菜单(纵向)<br />  我们先来看菜单的最终效果:<br /><iframe name="menu" align="center" marginwidth="0" marginheight="0" src="http://www.pconline.com.cn/pcedu/sj/wz/other/0409/other/040909sebs_menu.html" frameborder="0" width="200" scrolling="no" height="250"></iframe><br /><br />通常方法我们至少嵌套2层表格来实现这样的菜单,间隔线采用在td中设置背景色并插入1px高的透明GIF图片实现;背景色的交替效果采用td的onmouseover事件实现。但查看本菜单的页面代码,你会看到只有如下几句:<br /><br /><div id="menu"><br /><ul><br /><li><a title="网站标准" href="http://www.w3cn.org/webstandards.html">什么是网站标准</a></li><br /><li><a title="标准的好处" href="http://www.w3cn.org/benefits.html">使用标准的好处</a></li><br /><li><a title="怎样过渡" href="http://www.w3cn.org/howto.html">怎样过渡</a></li><br /><li><a title="相关教程" href="http://www.w3cn.org/tutorial.html">相关教程</a></li><br /><li><a title="工具" href="http://www.w3cn.org/tools.html">工具</a></li><br /><li><a title="资源及链接" href="http://www.w3cn.org/resources.html">资源及链接</a></li><br /></ul><br /></div>  <br />没有用任何table,而用的是无序列 <li>,整个菜单的效果实现的秘密完全在于id="menu",我们再来看CSS中关于menu的定义:<br /><br />  (1)首先定义了menu层的主要样式:#menu {<br />MARGIN: 15px 20px 0px 15px; /*定义层的外边框距离*/<br />PADDING:15px; /*定义层的内边框为15px*/<br />BACKGROUND: #dfdfdf; /*定义背景颜色*/<br />COLOR: #666; /*定义字体颜色*/<br />BORDER:#fff 2px solid; /*定义边框为2px白色线条*/<br />WIDTH:160px; /*定义内容的宽度为160px*/<br />}<br /><br />  (2)其次定义无序列表的样式:<br /><br />#menu ul {<br />MARGIN: 0px;<br />PADDING: 0px;<br />BORDER: medium none; /*不显示边框*/<br />LINE-HEIGHT: normal;<br />LIST-STYLE-TYPE: none;<br /><br />}<br />#menu li {BORDER-TOP: #FFF 1px solid; MARGIN: 0px;}<br /><br />  说明:这里用的是id选择器的派生方法定义(参考第7天:CSS入门的介绍)了在menu层中的子元素 <ul>和 <li>的样式。LIST-STYLE-TYPE: none一句表示不采用无序列表的默认样式,即:不显示小圆点(我们后面用自己的图标来代替小圆点)。BORDER-TOP: #FFF 1px solid;则定义了菜单之间的1px间隔线。<br /><br />  (3)定义onmouseover效果<br /><br />#menu li a {<br />PADDING:5px 0px 5px 15px;<br />DISPLAY: block;<br />FONT-WEIGHT: bold;<br />BACKGROUND: url(images/icon_dot_lmenu.gif) transparent no-repeat 2px 8px;<br />WIDTH: 100%;<br />COLOR: #444;<br />TEXT-DECORATION: none;<br />}<br />#menu li a:hover { BACKGROUND: url(images/icon_dot_lmenu2.gif) #C61C18 no-repeat 2px 8px;<br />COLOR: #fff; }<br /><br />  解释如下:<br /><br />"display:block;"表示将标签a当作块级元素来显示,使得链接变成一个按钮;<br />"BACKGROUND: url(images/icon_dot_lmenu.gif) transparent no-repeat 2px 8px;"这一句定义了替代li的小圆点的图标。"transparent"指背景为透明,"2px 8px"指定图标的位置是距左边2px,距上边8px。这一句也可以拆分写成四句:"BACKGROUND-IMAGE: url(images/icon_dot_lmenu.gif); BACKGROUND-POSITION: 2px 8px; BACKGROUND-REPEAT: no-repeat; BACKGROUND-COLOR: transparent;"<br />"#menu li a:hover"定义了当鼠标移动到链接上以后的颜色变化和小图标变化。<br />  ok,不用表格的菜单就这样实现了。大家可以明显感觉到,原来写在HTML里的表现样式全部剥离放到CSS文件里去了。页面代码节约了大半。通过CSS要修改菜单样式就很简单了。<br /></li></ul></li><div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114322804197274884?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1143227558343471662006-03-21T03:07:00.000+08:002006-03-25T03:25:13.843+08:00使用Web标准建站第10天:自适应高度如果我们想在3列布局的最后加一行页脚,放版权之类的信息。就遇到必须对齐3列底部的问题。在table布局中,我们用大表格嵌套小表格的方法,可以很方便对齐三列;而用div布局,三列独立分散,内容高低不同,就很难对齐。其实我们完全可以嵌套div,把三列放进一个DIV中,就做到了底部对齐。下面是实现例子(白色背景框模拟一个页面):<br /><img style="WIDTH: 337px; HEIGHT: 245px" height="276" src="http://www.naozhoudao.com/blog/040908webs1001.gif" width="484" /><br /><br />例子的页面主要代码如下:<div id="header"></div><div id="mainbox"> <div id="menu"></div> <div id="sidebar"></div> <div id="content"></div></div><div id="footer"></div><br />  具体样式表都写在相应版块里了。重点在于#mainbox层嵌套了#menu,#sidebar和#content三个层。当#content的内容增加,#content的高度就会增高,同时#mainbox的高度也会撑开,#footer层就自动下移。这样就实现了高度的自适应。<br />  另外值得注意的是:#menu和#content都是浮动在页面右面"FLOAT: right;",#sidebar是浮动在#menu层的左面"FLOAT: left;",这是浮动法定位,还可以采用绝对定位来实现这样的效果。<br />  这个方法存在另一个问题,就是侧列#sidebar的背景无法百分之百。一般的解决办法就是用body的背景色来填充满。(不能使用#mainbox的背景色,因为在Mozilla等浏览器中#mainbox的背景色失效。)<br />  好了,主要的框架已经搭建完毕,剩下的工作只是往里面添砖加瓦。如果你希望尝试其他布局,推荐看看以下文章:<br /><a href="http://www.w3cn.org/article/layout/2004/55.html">CSS布局16例 </a><br /><a href="http://www.onestab.net/a/pie/3colcomplex.html">onestab:三栏复合布局演示</a><br /><a href="http://www.onestab.net/a/pie/thr.col.stretch.html">onestab:自由伸展的三栏式版面</a><br />Tips:<a href="http://www.onestab.net/">[onestab 的"P.I.E"专题]</a> 还有更多精彩介绍,推荐去看看。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114322755834347166?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0tag:blogger.com,1999:blog-20264575.post-1143226931013202372006-03-20T00:56:00.000+08:002006-03-25T03:02:11.016+08:00使用Web标准建站第9天:CSS布局入门接下来开始要真正设计布局了。和传统的方法一样,你首先要在脑海里有大致的轮廓构想,然后用photoshop把它画出来。你可能看到有关web标准的站点大都很朴素,因为web标准更关注结构和内容,实际上它与网页的美观没有根本冲突,你想怎么设计就怎么设计,用传统表格方法实现的布局,用DIV也可以实现。技术有一个成熟的过程,把DIV看成和TABLE一样的工具,如何运用就看你的想象力了。注:在实际应用过程中,DIV在有些地方的确不如表格方便,比如背景色的定义。但任何事情都有得有失,取舍在于你的价值判断。好,不罗嗦了,我们开始:<br />1.确定布局<br />  w3cn的最初设计草图如下:<br /><img src="http://www.naozhoudao.com/blog/w3cwebdd.gif" /><br />用表格的设计方法的话,一般都是上中下三行布局<img src="http://www.naozhoudao.com/blog/200634134542615.gif" /> 。用DIV的话,我考虑使用三列来布局,成为这样<img src="http://www.naozhoudao.com/blog/200634134550813.gif" /> 。<br /><br />2.定义body样式<br />  先定义整个页面的body的样式,代码如下:<br /><br />body { MARGIN: 0px;<br />PADDING: 0px;<br />BACKGROUND: url(../images/bg_logo.gif) #FEFEFE no-repeat right bottom;<br />FONT-FAMILY: 'Lucida Grande','Lucida Sans Unicode','宋体','新宋体',arial,verdana,sans-serif;<br />COLOR: #666;<br />FONT-SIZE:12px;<br />LINE-HEIGHT:150%; }<br />  以上代码的作用在上一天的教程有详细说明,大家应该一看就明白。定义了边框边距为0;背景颜色为#FEFEFE,背景图片为bg_logo.gif,图片位于页面右下角,不重复;定义了字体尺寸为12px;字体颜色为#666;行高150%。<br /><br />3.定义主要的div<br />  初次使用CSS布局,我决定采用固定宽度的三列布局(比自适应分辨率的设计简单,hoho,别滴彝道粒?仁迪旨虻サ模?黾拥阈判穆铮?。分别定义左中右的宽度为200:300:280,在CSS中如下定义:<br /><br /><br />/*定义页面左列样式*/<br />#left{ WIDTH:200px;<br />MARGIN: 0px;<br />PADDING: 0px;<br />BACKGROUND: #CDCDCD;<br />}<br />/*定义页面中列样式*/<br />#middle{ POSITION: absolute;<br />LEFT:200px;<br />TOP:0px;<br />WIDTH:300px;<br />MARGIN: 0px;<br />PADDING: 0px;<br />BACKGROUND: #DADADA;<br />}<br />/*定义页面右列样式*/<br />#right{ POSITION: absolute;<br />LEFT:500px;<br />TOP:0px;<br />WIDTH:280px;<br />MARGIN: 0px;<br />PADDING: 0px;<br />BACKGROUND: #FFF; }<br /><br />  注意:定义中列和右列div我都采用了POSITION: absolute;,然后分别定义了LEFT:200px;TOP:0px;和LEFT:500px;TOP:0px;这是这个布局的关键,我采用了层的绝对定位。定义中间列距离页面左边框200px,距离顶部0px;定义右列距离页面左边框500px,距离顶部0px;。<br /><br />  这时候整个页面的代码是:<br /><br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><html xmlns="http://www.w3.org/1999/xhtml" lang="gb2312"><br /><head><br /><title>欢迎进入新《网页设计师》:web标准教程及推广</title><br /><meta http-equiv="Content-Type" content="text/html; charset=gb2312" /><br /><meta http-equiv="Content-Language" content="gb2312" /><br /><meta content="all" name="robots" /><br /><meta name="author" content="ajie(at)netease.com,阿捷" /><br /><meta name="Copyright" content="www.w3cn.org,自由版权,任意转载" /><br /><meta name="description" content="新网页设计师,web标准的教程站点,推动web标准在中国的应用." /><br /><meta content="web标准,教程,web, standards, xhtml, css, usability, accessibility" name="keywords" /><br /><link rel="icon" href="/favicon.ico" type="image/x-icon" /><br /><link rel="shortcut icon" href="http://www.w3cn.org/favicon.ico" type="image/x-icon" /><br /><link rel="stylesheet" rev="stylesheet" href="css/style01.css" type="text/css" media="all" /><br /></head><br /><body><br /><div id="left">页面左列</div><br /><div id="middle">页面中列</div><br /><div id="right">页面右列</div><br /></body><br /></html><br /><br />  这时候页面的效果仅仅可以看到三个并列的灰色矩形,和一个背景图。但是我希望高度是满屏的,怎么办呢?<br /><br />4.100%自适应高度?<br />  为了保持三列有同样的高度,我尝试在#left、#middle和#right中设置"height:100%;",但发现完全没有预想的自适应高度效果。经过一番尝试后,我只好给每个div一个绝对高度:"height:1000px;",并且随着内容的增加,需要不断修正这个值。难道没有办法自适应高度了吗?随着阿捷自己学习的深入,发现一个变通的解决办法,实际上根本不需要设置100%,我们已经被table思维禁锢太深了,这个办法在下一节的学习中详细介绍。<div class="blogger-post-footer"><?xml version="1.0" encoding="GB2312"?> <rss version="2.0"> <channel> <title>Anson_Blog</title> <link>http://www.naozhoudao.com/blog</link> <description /> <generator>www.naozhoudao.com/blog</generator> <item> <title>$BlogItemTitle$</title> <pubDate>$BlogItemDateTime$</pubDate> <description>$BlogItemBody$</description> </item> </channel> </rss><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/20264575-114322693101320237?l=www.naozhoudao.com%2Fblog'/></div>Ansonnoreply@blogger.com0