'; return ''; } ?> ZEAL Blog·厉
@ZEAL Blog·厉
WWW Zeal Blog
We stand alone,
TOGETHER.
+ 0 - 0 | §又拍云存储的尝试

因为@Fenng的大力推荐,关注又拍其实有段时间了。前阵子在做CDN的选型测试,正好又拍的童鞋要给我开通推荐码机制的权限,所以趁热打铁把这个性价比不错的服务给上了。

作为尝试,我只选择了又拍的图片存储服务。一方面他们提供的自动缩略图生成和优化很方便,另一方面也考虑万一不行的话切换回我们自己的服务也快(毕竟再好的服务也需要有备份方案啊)。

几周的测试下来,API || FTP 的数据接口还是相当方便滴。同名文件覆盖上传之后缓存会自动触发式刷新,基本上能实时看到新图片(测试周期内出现过一次十分钟左右的延迟,可能与他们当时的网络节点状态有关);不像传统CDN那样普遍需要用户主动发起刷新请求。

更为详细的介绍分析@blogkid写得非常具体了(请看: 又拍云实战),比如按需付费、比如简化运维、比如缩略图功能,都是关键的卖点。我就说说一些感觉美中不足的地方:

  1. 管理监控后台比较单薄。管理员帐号只能是一个(只有空间操作员可以随便加,但操作员只能是做文件操作),如果可以像GA那样支持配置多帐号登录管理就好了。
  2. 实时流量监控统计图表存在抖动,并不是非常准确。
  3. 图片空间缩略图的尺寸命名一旦添加了就不能改。虽然说空间可以随便添加、一个空间可以设置10个缩略图版本,但如果由于某些原因当某个空间使用了一段时间之后想修改缩略图的命名规则,还是件麻烦事儿。
  4. 无法进行空间文件的大批量移动复制。通过API||FTP,都是针对文件的增量操作。一旦想调整目录结构,或把数据从一个空间转移到另一个空间,最便捷的方法可能就只有联系又拍的技术支持了(当然又拍的技术响应速度还是一流的,基本上有求必应,产品开道服务为王这两点又拍都做得不错呃)。
  5. 欠缺流量报警机制。比如自定义阀值设置,当某时段流量带宽等数值超过或可用余额不足时,自动邮件/短信提醒等方便运维监控的辅助功能。 

当然这些都是小问题,不会影响主要的服务体验。只是希望又拍的更新升级速度更快些:)

最后,广告时间推荐码购买又拍云存储服务可以得到5%的优惠;当然我也可以得到5%的返利。有需要的童鞋可以微博上找我@ZEAL索取^_-

标签 ( WebDev ) :
+ 0 - 0 | §Zeal.ChinaStock小问题修正版本

曾经捣鼓了个查看股票实时信息的Firefox小扩展放在AMO上,自从改用Chrome后就再没更新了。

最近忽然很多朋友各种方式来问我什么时候出更新包啥的,我一开始还以为是AMO给咱做了什么推广,后来发现是第三方数据源格式变化导致信息获取失败,所以都是这个扩展的老用户发现忽然抓不到数据所以来找我修正呢。

本来自己早已经把Firefox退化到只作为Firebug用,扩展的更新也早就停止了。但被需要的感觉总是很爽,更想不到自己当时为方便自己做的一点小事同时也帮到了别人,至今还有这么多朋友在用它。所以还是决定抽空提交个小修正版本。

此次修正了数据源抓取格式问题(顺便加上显示换手率的设置项)的小更新版本已经提交到AMO,暂时还在等待全面审核状态。如果急着需要用的朋友可以直接到这个完整版本页下载 Zeal.ChinaStock 1.4.0.2 版本

虽然改动很小,但因为很久没启动扩展开发调试环境,感觉略有不适。不少还是Firefox3.6的时候在使用的辅助扩展在Firefox10下面也都没有推出适用版本了。跟Chrome的发展速度和扩展规模相比,Firefox真的是有点弱唉。

标签 ( WebDev ) :
+ 0 - 0 | §小鸟技术团队虚位以待
PHP开发|数据分析|架构|运维|测试,您是来呢来呢还是来呢?  查看全文
+ 0 - 0 | §IE8+Win7下ajaxSubmit异常问题

又是神奇的IE。这次提交过来的Bug是说只有在Win7系统的IE8下打开网站的登录页,填写完登录信息提交之后页面跳转到一个文本页,而这个页面本应该是通过ajaxSubmit进行验证返回验证结果的json数据内容页,不应该显示出来给用户看到。

通常来说出现这个问题都是因为jquery的form扩展失效导致ajax功能没有成功绑定,所以触发了缺省的浏览器表单提交行为造成页面跳转到提交目标页。一路debug下去,发现居然是用来显示提交进度状态窗口的 blockUI 扩展内部出错,抛出了异常。异常指向了 blockUI 用到的针对 IE 浏览器使用的 setExpression 方法。

把这段代码异常捕获住,问题解决。

但为什么同样是 IE8 ,在XP下却不会暴露这个问题,Win7下就出错?

答案在这里这里。XP下的IE8小版本号是8.0.6001,而Win7下是8.0.7600。从 6001 到 7600 ,微软把 setExpression 给干掉了,当然干掉的原因依然是为用户着想。很有爱的微软。

看来以后测试不光是需要考虑 IE8 / IE7 / IE6 / Firefox / Chrome / Safari / Opera 这些大版本号的兼容性了,还需要考虑 .6001 和 .7600 这种IE小版本的差异。如果把所有老版本的jquery和jquery plugins全部升级到最新版应该也可以避免一些类似问题,但替换核心库的升级成本啊。。。或者还是把 <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> 给加在页面头上得了,一了百了。

标签 ( WebDev ) :
+ 0 - 0 | §jQuery的事件绑定命名空间

jQuerybind / unbind 方法应该说使用很简单,而且大多数时候可能并不会用到,取而代之的是直接用 click / keydown 之类的事件名风格的方法来做事件绑定操作。

但假设如下情况:需要在运行时根据用户交互的结果进行不同click事件处理逻辑的绑定,因而理论上会无数次对某一个事件进行 bind / unbind 操作。但又希望 unbind 的时候只把自己绑上去的处理逻辑给释放掉而不是所有其他地方有可能的额外的同一事件绑定逻辑。

这时候如果直接用 .click() / .bind('click') 加上 .unbind('click') 来进行重复绑定的话,被 unbind 掉的将是所有绑定在元素上的 click 处理逻辑,潜在会影响到该元素其他第三方的行为。当然如果在bind的时候是显示定义了function变量的话,可以在unbind的时候提供function作为第二个参数来指定只unbind其中一个处理逻辑,但实际应用中很可能会碰到各种进行匿名函数绑定的情况。

对于这种问题,jQuery的解决方案是使用事件绑定的命名空间。即在事件名称后添加 .something 来区分自己这部分行为逻辑范围。

比如用 .bind('click.myCustomRoutine',function(){...}); 同样是把匿名函数绑定到 click 事件(你可以用自己的命名空间多次绑定不同的行为方法上去),当unbind的时候用 .unbind('click.myCustomRoutine') 即可释放所有绑定到  .myCustomRoutine 命名空间的 click 事件,而不会解除其他通过 .bind('click') 或另外的命名空间所绑定的事件行为。

同时,使用命令空间还可以让你一次性 unbind 所有此命名空间下的自定义事件绑定,通过 .unbind('.myCustomRoutine') 即可。

要注意的是,jQuery的命名空间并不支持多级空间。因为在jQuery里面,如果用 .unbind('click.myCustomRoutine.myCustomSubone') ,解除的是命名空间分别为 myCustomRoutinemyCustomSubone 的两个并列命名空间下的所有 click 事件,而不是 "myCustomRoutine 下的 myCustomSubone 子空间"。

+ 0 - 0 | §新浪微博180尺寸头像显示GM脚本
在小新的围脖官方提供个人头像大图查看功能之前,先整个粗糙的 Greasemonkey 脚本用着。再也不用眯着眼睛看那些超级无敌的50X50压缩小图了。  查看全文
+ 0 - 0 | §淘宝开放平台:好大一朵棉花糖

大淘宝开放平台 ( TOP ) ,给我们描绘出的是一幅十亿人民九亿商的宏伟画面。只要你想,就可以通过给TOP添砖加瓦来赚玛尼。

淘宝开放平台:由淘宝网提供,面向第三方的开放式电子商务服务基础服务框架。其主要内容包括:以OpenAPI形式开放的淘宝网电子商务基础服务、淘宝网自有的开放式应用平台、对第三方应用平台的开放式基础支持。

第一眼看到TOP的API文档,脑海里闪现的是以后做一个垂直B2C网站门槛会更低了:只要进行一个简单的封装,就可以把任何企业现有ERP的产品实时登录到TOP上,支撑电子商务的整套业务逻辑和数据访问压力都由淘宝来承担。公司目前线上营销部门每天花很多时间去做的人工在淘宝登录发布商品的资源浪费也将不复存在。当然,前提是有一批TOP应用开发的先行者做出优秀的插件来促成良性循环。

再看TOP的盈利模式淘宝客佣金 | 插件分成 | 软件销售 | 传统广告。看上去花样繁多,不过相同的本质都是通过增值服务来让卖家付费。在通过免费大旗打倒ebay易趣之后,淘宝看来是打算使用这种相对更自愿的方式来向卖家收费。这种类似跑跑卡丁车的盈利模式在中国应该还是很有市场的。当前,前提依然是有足够多好的插件可以吸引卖家来订购。

很阴暗的猜想一下,淘宝自己现在已经对一些计划中的新功能进行划分了,哪些作为淘宝网的基本功能提供,哪些放到付费插件平台去让卖家掏钱购买(不知道是不是还会包月包年的) -- 然后只要是您想用的功能,统统都是收费滴~~

对于我比较关心的软件销售模式与淘宝的分成关系在于:“当对TOP OpenAPI访问调用超过默认流量限制时,TOP将收取适当费用。在Beta运行期间,只记录流量限制记录,暂不收费。”这个接口使用费用的高低,将直接影响到TOP第三方软件的数量。

不管是 FirefoxTwitter  还是  Google Maps ,它们的第三方扩展/应用如此丰富的原因很大程度上都是因为免费。TOP这朵以盈利为指导思想的雨云诚如八戒眼中的棉花糖,好不好吃且看能不能咬到嘴吧~~

标签 ( WebDev ) :
+ 0 - 0 | §flash反编译杂记

近日有位童鞋让我帮忙把某个在线的flash游戏做成单机硬盘版的好在自己的电脑上玩,恰好又有些其它swf文件的反编译需求,于是很不专业的折腾了一番。思路比较混乱,随手记一下。Flash 达人请直接飘过。

现在的flash不像以前都是单个SWF,直接下载下来就完事儿。在AS3里面可以采用Loader / URLLoader / Sound 等来按需加载不同的外部内容数据,减少单次下载的内容大小。通过 Firebug 的网络面板可以很容易知道在交互过程中产生了哪些二次数据请求,当然也就很容易把这些必需的外部文件也同步保存到本地。

但这样保存下来的内容不见得是整个应用所需的全部素材,因为你不见得会在一次访问过程中触发所有的可能性。所以最彻底的方式是反编译保存下来的SWF文件,然后用全局搜索查找出全部的调用内容。

反编译的工具,对我来说 Sothink SWF Decompiler 不错,基本上能很好的还原出fla文件。但这个工具有一个很严重的问题,在反编译还原 AS 类库文件的时候会出现很多错误,比如把某些变量进行了错误的替换,某些注释被错误的赋值给变量,等等(我用的是 v4.4 ,不知道最新的 v5.0 还有没有这个问题)。如果直接用 Flash CS3 / CS4 去打开生成反编译出来的项目的话,很可能会报出一大堆的编译器错误!所以还需要使用另外一个工具 Action Script Viewer 6 ( ASV6 之前的版本并不支持AS3脚本的反编译),用ASV的 "Export Rebuild Data (JSFL)" 功能导出的 rebuild 脚本虽然有时候并不能完整的重建项目,但导出来的 AS 库文件源代码却很完整。

把 ASV 生成的 AS 库文件复制覆盖到 Sothink 生成的项目文件夹,再打开 Sothink 生成的flp项目文件去编译,应该就不会有一堆莫名其妙的编译器错误了 ---- 一开始我太相信 Sothink 的反编译结果,一度很纠结为什么源代码有这么多编译错误还能生成SWF并正常交互,还以为是跟 Flash CS4 版本兼容性问题又去搞了个 CS3。

ASV 网上能找到的好用版本貌似只有到 asv6 alpha4 ,由于不是 relase 版本,在反编译的时候会提示说反编译出来的东西不一定是完整的 ---- 由于这个提示我一度放弃使用 asv6 ,直到后来拿 asv6 反编出来的源代码去和 Sothink 反编出来的做比较才发现原来声明自己并不一定完整的反而是准确可用的。

这两个工具最好都不要找什么绿色汉化版,有后门。如果常规性会有类似反编译需求的童鞋是值得花钱去买一份正版的来用的。

Sothink 生成的flp项目文件是 for Flash CS3 的, CS4 打开flp文件的方法是:选择“窗口”>“其它面板”>“项目”打开“项目”面板;在“项目”面板中,从“项目”弹出菜单中选择“打开项目”;在“浏览文件夹”对话框中,导航到包含 FLP 文件的文件夹,然后单击“确定”,即可。

为了完成反编译修改大业,终于把机器上尘封了N久的Flash8给卸掉,换成了 Flash CS3 。一开始搞了个精简版,结果对 as 源代码进行语法检查就报“JAVA 运行时环境初始化时出现错误,您可能需要重新安装Flash”。原来精简版把 JVM 都给精简了,需要装一个 jre 环境(或者找找机器上是不是已经有 jre 环境目录了),把jre下的内容复制到 Flash 安装目录下的 JVM 文件夹中(没有的话建一个)。

当然最好还是找个原版镜像出来的比较好,否则总会出现各种古怪问题(比如当Flash项目中用到的字体文件在你本地环境中找不到的话,精简版会直接程序崩溃,就为这个我又一度不得不上网去找来项目中用到的微软雅黑字体给装上)。有时候浓缩不一定是精华。

发布项目时出现“5003: 生成字节代码时发生未知错误”。可以尝试的解决方法: 1、 在“文件->发布设置”的“ActionScript 3.0 设置”中不要勾选“减小文件大小并改善性能”(发布设置这个菜单项平时是没有的,必须打开项目的默认fla文件,一度又很纠结为什么在项目面板鼠标右键点击fla文件的时候不出现这个发布设置...); 2、 “控制->删除 ASO 文件”; 3、 增加一个系统环境变量 JAVA_TOOL_OPTIONS ,变量值设置为 -Xmx512M  (注意 512 这个数字需要根据情况调整,不同的电脑配置可设置的数值不一样,可以从 1024 开始往小里改。我的本本要改到 400 才行,大于 400 的数字会又一次导致'JAVA 运行时环境初始化出现错误';修改了环境变量之后可以开一个命令行窗口输入命令 SET JAVA_TOOL_OPTIONS=ANYTHING 让新的环境变量立即生效,重新打开 Flash CS 程序即可)。

当去掉了发布设置选项中的"省略 trace 动作"勾选框之后,测试项目时会输出"VerifyError: Error #1030: 堆栈深度不对称"的错误,没搞清为什么,只好把这个选项再勾上。

URLLoader 加载本地文件,相对路径如果写成 "./data/......" 的话,测试项目没问题,生成项目之后用某些支持SWF的播放器也没问题,但用 Flash Player 运行生成出来的SWF时会抛出类似"Error #2044: 未处理的 ioError:。 text=Error #2032: 流错误" 的 ioError ,需要把 "./" 去掉,直接写 "data/......" 这样的相对路径才能正常读取到相对目录下的内容。 

折腾完毕,一个字:累。或许是早期版本Flash IDE对as脚本编写支持的超级弱让我对 Flash 一直很排斥,即便到现在还是如此。也许 HTML 5 真的可以让人抱有期待。本来嘛,都是基于浏览器的东西为什么不做成内置标准以最简单的方式来提供给开发者?

标签 ( WebDev ) :
+ 0 - 0 | §ChinaStock终于通过AMO审核

为研究 Firefox 扩展开发整的 Zeal.ChinaStock 从去年5月份开始提请审查,到今天将近一年的时间,终于得见天日不用再待在沙盒里面接收测试了。自贺一下。

历次被打回的理由如下:

1. Your add-on must have some reviews either on AMO or elsewhere on the web. See http://shawnwilsher.com/archives/108 for some ideas on how to do that.

第一次的提请审核时间最久,在我都已经快忘了这回事的时候 AMO 回了这么一封信。看来必须是在沙盒里面待到有一定的回复评论数量才行。

2. In order to prevent conflicts with other addons that may be installed by users, you need to wrap your 'loose' variables and functions within a JavaScript object. You can see an example of how to do this @ http://blogger.ziesemer.com/2007/10/respecting-javascript-global-namespace.html.

第二次告诉我代码里面有用到全局变量,容易跟其他扩展的代码发生冲突。看了看其它公布在AMO网站上的附件组件,有不少也是存在大量全局变量的,估计要么是提交的早审核没这么严格,要么是影响力大AMO给开后门了。只好用Firebug查看所有的全局变量,把它们都封装到自己的命名空间对象下面。 AMO 提供的 how-to 链接是被墙的,需要翻墙阅读。

3. You're evaluating remote code, which may be a serious security risk. Please use https://developer.mozilla.org/En/Components.utils.evalInSandbox and resubmit.

原来代码里面使用了 eval 来执行远程抓取到的内容。去掉了对 eval 的使用之后再提交,没过多久就收到 Congratulations 邮件了。

Updated 2009-04-02 11:50 -- 更新了一次版本,差不多等了一个多星期之后 Mozilla 完成版本review予以发布。有意思的是他们居然同时还在 Minefield 上进行了测试,并建议我 increase max compatible version from the developer control pane (no need to resubmit with an altered install.rdf) 。这直接促使我下载了还在开发中的  latest nightly build 进行测试。Mozilla 的测试人员确实是认真负责加勤奋,赞一个。

标签 ( WebDev ) :
+ 0 - 0 | §设置Firefox statusbarpanel背景

在 Firefox 自定义附加组件中扩展状态栏 statusbar 的内容一般通过在附件组件的 XUL 定义文件中添加 statusbarpanel 元素来实现。

每个 statusbarpanel 都可以定义不同的 CSS 样式。比如对于 <statusbarpanel id="zealiTestExt-panel" label="test label"/> ,可以用常规的方式来修改样式:

var pTargetEle = document.getElementById('zealiTestExt-panel');
with(pTargetEle.style){
    fontWeight = 'bold';
    color = '#f00';
}

但如果想修改 statusbarpanel 的背景,直接这样写你会发现没有起任何效果:

... backgroundColor = '#0f0';

原因是 Firefox 对状态栏的元素应用了基于操作系统的样式,或者当前使用的主题样式定义覆盖了用户自定义组件的样式。解决方法是加入 mozilla 的扩展CSS样式 -moz-appearance 以及 !important 声明:

...
pTargetEle.setAttribute('style','-moz-appearance: none !important; background-image: none !important;background-color: #0f0 !important;');

-moz-appearance 设置为 none 并加上 !important 强制 Firefox 不对该状态栏区域应用缺省系统样式;同时强制清除当前背景图片的样式并设定新的背景颜色。

标签 ( WebDev ) :
+ 0 - 0 | §Google Ajax APIs Playground

Google 的工程师 Ben Lisbakken 利用他的 20% 时间捣鼓出一个展示 Google 所提供的各种 JavaScript API 功能的界面。开发人员通过这个界面可以迅速检索这些 API 的常用功能,然后对这些示例代码进行在线修改即时查看执行结果。

Playing around with Googles AJAX APIs
这个东西比直接去阅读那些枯燥的 API 文档然后在本地自己写测试代码要好用多了,强烈推荐。目前里面包含的API有:

  • Visualization
  • Search
  • Language
  • Blogger Data
  • Libraries
  • Maps
  • Google Earth
  • Feeds
  • Calendar Data

其中 Libraries API 就是常用 JavaScript 库的 CDN 。对于安全性没有特别要求的中小型网站来说,使用 Google 集中提供的js库(比如jquery)可以减少一次自己服务器的http连接,同时使用 Google CDN 的人越多,这些库文件在浏览器缓存里面存在的可能性就越大,访问速度也就越快。如果 Google 能够永远“不作恶”,永远不倒闭,那么使用他的 Libraries API 绝对比在自己的服务器上放一份拷贝要好。

有趣的是虽然 Google 官方建议通过引用 <script src="http://www.google.com/jsapi"></script> 之后调用 google.load("jquery", "1"); 的方法来最高效的使用这些 Libraries API ,但就连这个 Googles AJAX APIs Playground 也是直接用 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script> 这样的方式来调用 CDN 中的 js 代码库的。

两种方法要我选肯定也是选直接引用的,反正官方文档里面明确说明两种方法都可以,并且有给出每个库对应的引用URL,没必要多那么一举嘛。

标签 ( WebDev ) :
+ 0 - 0 | §Google Maps的反向地理编码来了
半年前在说 Google Maps API 的反向地理编码(Reverse Geocoding)很遗憾的不提供中国地区的查询,现在终于等到70多个国家都开放的一天了。虽然目前中国地图地址解析器还只支持市/县/区级别的地址,但跟之前只能定位到国家级别比起来已经是能够做一些比较实际的应用了。  查看全文
标签 ( WebDev ) :
+ 0 - 0 | §Google PR查询接口checksum新算法

前些日子一篇N久之前的老文忽然成了被阅读的热点,检查之后才发现自己使用那段代码来做pr查询的页面已经不能正常得到URL的Page Rank值了,取而代之的是一大段“In your email, please send us the entire code displayed below”之类的Google terms_of_service错误提示信息。看来是原先的接口已经失效了。

但我装在Firefox工具栏的扩展插件SearchStatus仍然能够正常解析出每个受访页的PR值,找到 SearchStatus 的插件包解开来看源码,果然是使用了不一样的验证码生成算法,在原先的 checksum 生成之后,还需要再进行一次计算,两次演算之后得到的才是正确的ch参数。

于是拿现成的js代码改造一番之后,新的PHP版本的 Google PageRank 查询接口方法就出来了。经过本地测试之后,谁想传到服务器之后又出现了该死的 terms_of_service 错误提示。把checksum的计算过程一步步打出来,发现经过了几次右位移之后本地和服务器上的数字就不一样了。这才想到服务器是64位机,32位系统下位移之后应该被cut掉的bit在那里就活得好好的。加了个 trunkbitForce32bit 方法,对所有算术运算之后的数值进行高位屏蔽,算是搞定了64位系统下的多余位问题。结果拿到32位Linux环境下跑又不兼容了,原因是PHP在进行算术处理出现溢出时,会自动尝试将int转为float。当发生的是负数溢出时,这一操作在Windows下能正确保留精度,但在Linux下就有问题了。

下面这段代码:

$a = -4294967295;
echo dechex($a)."<br />\n";
if ( $a < 0 ) $a += 4294967296;
echo dechex($a)."<br />\n";

第一个echo在Windows下能够正确输出该负数低32位的补码,而在32位Linux机上输出的则是int类型所能表示的最大负数0x80000000了。只有通过取巧的方式给这个溢出的大负数加上一个超出整数范围的大整数来抵消掉溢出的部分,才能复原低32位应该有的样子。

使用这些非常规手段,终于炮制出这个更新版的兼容Linux32/Linux64/Windows的Google PR值查询接口的PHP脚本实现(含完整代码)

参考:
php异或运算的不可靠性
PHP vs. BIGINT vs. float conversion caveat
http://www.teamworksusa.com/RDS275/HydroWorks275/keygen.php

标签 ( WebDev ) :
+ 0 - 0 | §Reverse Geocoding for Google Maps API

Reverse Geocoding ,也就是反向地理编码(逆地理编码),可以根据地图上某一点的经纬度值来查询该点附近的地理信息。比如要实现捕获用户鼠标事件判断用户点的是哪国哪省哪市哪条街道,就需要有相应的 reverse geocoding 服务支撑。

在当前版本的 Google Maps API 中对这项功能提供了有限支持。对于开放了 Geocoding (GClientGeocoder)Driving Directions (GDirections) 接口的国家和地区,Nico Goeminne 写了个 GReverseGeocoder 类来完成反向地理编码解析(Google Pages 貌似这几天被 GFW 掉了,访问不到 Nico Goeminne 站点的朋友可以看我本地的镜像链接)。可惜的是目前谷歌中国的ditu.google.com还没有提供GDirections接口,不知道后续的版本会不会放出。下面是 Nico Goeminne 列出的 GReverseGeocoder 当前的国家支持情况(x=支持, n=不支持, p=理论上支持但未经过测试):

Country GClientGeocoder GDirections GReverseGeocoder
Austria x x p
Australia x x p
Belgium x x x
Brazil x x x
Canada x x p
The Czech Republic x x p
Denmark x x p
Finland x x p
France x x x
Germany x x x
Hong Kong x n n
Hungary x x p
India x n n
Ireland x x p
Italy x x x
Japan x n n
Luxembourg x x x
The Netherlands x x x
New Zealand x x x
Norway x x p
Poland x x p
Portugal x x p
Singapore x x p
Spain x x p
Sweden x x p
Switzerland x x x
Taiwan x n n
Thailand x x p
the United Kingdom x x x
the United States x x x

实际上,在 Google Maps API 官方文档里面 GClientGeocoder 接口的 getLocations(address, callback) 方法里面虽然没有明确说明,却可以传递用逗号或空格分隔的经纬度值进去作为address参数,也能达到反向地理编码解析的目地。只是目前这样调用返回的Placemark对象精度只能到国家级别,并没有更进一步的所在地信息,还没有太多的实际价值。

一些非 Google Maps 提供的 geocoding / reverse geocoding 服务链接: http://groups.google.com/group/Google-Maps-API/web/resources-non-google-geocoders ,基本上可查询范围都是欧美国家,有偿服务居多。

中国区域的 reverse geocoding 服务方面, MapABC搜索API中倒是有 reverseGeoCoding(msearchpointpara) 接口方法,美中不足的是其flash版本的地图跨浏览器兼容性又不是太好还有滚动广告条,文档的组织也够凌乱,所使用的经纬度坐标又不是标准的数字形式,极大的影响了使用体验;51ditu 的位置描述接口则直接作为收费接口有偿提供。看来想使用免费又称心的 reverse geocoding 还得耐心等谷歌地图开放相应的功能了。

附:ChinaGeocodeMaps.csv 中国地区大中城市经纬度参照表

标签 ( WebDev ) :
+ 0 - 0 | §据说的最出色浏览器

看到有人说用了Safari之后"已经开始不愿意去用firefox了",忍不住也试用了一把,顺便看看最近几个应用在Safari下的兼容性。一打开浏览界面,果然很有苹果的酷炫风格,相当养眼。

然后就发现Safari的XMLHTTPRequest并没有如其他主流浏览器一样缺省使用utf-8编码来处理内容,必须在服务器端强制设定页面编码才不至于在Ajax处理中文时出现乱码(比如在脚本里面 header("Content-Type:text/html;charset=utf-8"); 或者在Apache的conf里面加上 AddDefaultCharset UTF-8  ,如果不幸服务器端的php.ini里面设置了不恰当的default_charset的话还必须在所有相关的php文件开头加上ini_set('default_charset','UTF-8'); 才行),也算相当有性格。

至于号称的 fastest browser in the world,没怎么感觉出来。IE6当然是没啥好比的;相较Firefox而言,去使用 Gmail 和自己的几个应用项目,速度上最多也就半斤八两各有快慢。或许因为是Mac移植版的缘故?没用过Mac版的,不得而知。

标签 ( WebDev ) :
+ 1 - 0 | §IE下Flash内容刷新后消失问题

很常见的一个图片轮播Flash,使用之后发现在IE下按F5刷新之后Flash区域就变成一大块背景色,内容轮播出不来了。有趣的是右键点击Flash选择"关于Adobe Flash Player 9 ..."打开 Adobe 的官网之后再按F5刷新,内容又可以正常显示了。

一点点去掉代码发现是 <param name="scale" value="exactfit"> 这个参数作怪。在 Flash 的脚本里面强制指定了 Stage.scaleMode = "noScale"; 而我的 Flash 代码生成 js 里面缺省把 scale 设成了exactfit 。 似乎这两者之间发生了某些冲突,导致IE下出现这种奇怪的刷新之后就白屏的现象。Firefox下倒是没问题。把参数改成 <param name="scale" value="noScale"> 之后恢复正常。

标签 ( WebDev ) :
+ 0 - 0 | §Zeal OpenID Server打包下载

本来PHP Standalone OpenID Server 的代码改装出来的 Zeal OpenID Server 纯属好玩,最近发现对 OpenID 感兴趣的朋友日渐增多,发信留言询问相关的东西。所以干脆把整个汉化修改之后的 Zeal OpenID Server 整站源码打了个包,喜欢研究的朋友自己 down 一个下来瞧瞧吧。

如果使用过程中有什么问题,最好自己去搞定,俺不负责技术解答,嘿嘿 :)

gz 压缩包: 446,651 字节 openid.zeali.net.tar.gz     zip 压缩包: 505,148 字节 openid.zeali.net.zip

Just Copy the whole folder to your server .

create a database ,
import tables information of file zeal_openid_server.sql

change config.php to fit your requirements.

default settings in config.php:

administrator user : admin
administrator pass : 123456

db host : localhost
db name : zeal_openid_server
db user : openuser
db pass : 123456

标签 ( WebDev ) :
+ 0 - 0 | §jquery更新到1.1.4

照例,每次的版本更新都会大幅提升 selector 的速度。不过这次的版本更新作为 1.1.x 的最后一个版本,为了给九月份的 1.2 版做铺垫,去掉了一些老版本中的方法。因此在使用之前最好确认一下原有代码的兼容性。

比如在 Validation 插件的 showLabel 方法中,作者采用 label = jQuery("<" + this.settings.errorElement + ">") 的方式来新建一个 dom 对象,在 1.1.4 中必须改为 label = jQuery("<" + this.settings.errorElement + "></" + this.settings.errorElement + ">") 才能被正常创建。否则在进行form输入字段验证的时候在IE下永远不会看到任何的提示信息显示出来。

具体 1.1.4 中 Deprecated 掉的内容包括:

  • $("div//p") , $("div/p") , $("p/../div") , $("div[p]") , $("a[@href]") 这几种 selector 写法
  • 带参数的 $("div").clone(false) 方法 ( 改而使用 .clone().empty() )
  • $("div").eq() , $("div").lt() , $("div").gt() 均由新增加的 slice 方法来实现等价功能
  • $("#elem").loadIfModified("some.php") , $.getIfModified("some.php") 均由调用底层的 $.ajax 方法来实现等价功能
  • $.ajaxTimeout(3000) 需要改而使用 $.ajaxSetup({timeout: 3000}) 来实现
  • $(…).evalScripts()
标签 ( WebDev ) :
+ 0 - 0 | §Ajax应用导致IE崩溃的因素
  • 内存泄漏。像 Circular References / Closures / Cross-Page Leaks / Pseudo-Leaks 这些引起 IE 内存泄漏的因素已经被无数人分析讨论过(1 , 2)。据说 IE7 以及 IE6 的某个更新补丁能够解决 memory leak 的问题,但事实上即便在 IE7 下面还是一不小心就让你的脚本吃光内存。比如创建 DOM 对象的时候在加入节点之前就把事件处理函数绑定到该 DOM 对象,或者把 DOM 对象从节点中移除之后再进行事件的解绑。
  • 以 DOM 方式频繁对 table 的整行(TR)进行 remove 和 append 。尤其是如果在 table 中使用了多个 tbody 并对这些 tbody 进行 remove / append 操作的话, IE 会直接出现非法操作框而退出。这个问题 IE7 倒表现良好,算是有点进步。
  • 不同的事件/函数同时操作DOM的对象。由于 javascript 本身不提供同步机制(当然也不是完全没有办法),所以在 Ajax 这样的异步模式下容易产生对象操作冲突。
标签 ( WebDev ) :
+ 0 - 0 | §resize事件造成的IE假死

当在 window 的 resize 事件中包含某些页面内容处理或计算导致 resize 事件再次被触发的时候, IE 会随机陷入假死状态,而 Firefox 则能够很好的处理。要防止这样的假死,比较简单的处理方法是通过 setTimeout 延迟处理。以 jQuery 的时间绑定语法为例:

function dealWithSth() {
    alert("resize event trigger");
};

var pResizeTimer = null;
$(window).bind(
 'resize',
 function() {
    if(pResizeTimer) clearTimeout(pResizeTimer);
    pResizeTimer= setTimeout(dealWithSth, 50);
 }
);

标签 ( WebDev ) :
+ 0 - 0 | §jQuery使用杂记

ajaxError( callback ) 中关于 callback 函数的传入参数,并不像官方文档说明的那样依次是XMLHttpRequest / settings / exception object 。实际上在这三个参数之前的第一个参数是指向 callback 本身的一个引用对象,从第二个参数开始才是文档中所描述的参数。其它几个 ajaxComplete / ajaxSend / ajaxSuccess 估计也类似。

使用了 ifModified 参数之后(也就是在发送 http request 的时候添加 If-Modified-Since HEADER),在 IE6 下刷新页面经常出现 IE 崩溃退出, IE7 / Firefox 下则正常。怀疑是跟浏览器的一些外部加载项有关

对于 flash 内容,如果设定宽度/高度为0, Firefox 不会真正载入这个 flash , IE 则似乎照常处理。

Firebug 确实很牛,彻底给了我一个使用 Firefox 的理由。想提高 js 代码调试的效率,这玩意少不了。

标签 ( WebDev ) :
+ 0 - 0 | §[存] AllowOverride 指令

通常利用 对 URL 进行重写的时候, rewrite 规则会写在 .htaccess 文件里。但要使 apache 能够正常的读取 .htaccess 文件的内容,需要对 .htaccess 所在目录进行配置。从安全性考虑,根目录一般都配置成不允许任何 Override ,即

<Directory />
    AllowOverride None
</Directory>

在 AllowOverride 设置为 None 时, .htaccess 文件将被完全忽略。当此指令设置为 All 时,所有具有 ".htaccess" 作用域的指令都允许出现在 .htaccess 文件中。

AllowOverride 可用的指令如下:

AuthConfig
允许使用与认证授权相关的指令(AuthDBMGroupFile, AuthDBMUserFile, AuthGroupFile, AuthName, AuthType, AuthUserFile, Require, 等)。
FileInfo
允许使用控制文档类型的指令(DefaultType, ErrorDocument, ForceType, LanguagePriority, SetHandler, SetInputFilter, SetOutputFilter, mod_mime中的 Add* 和 Remove* 指令等等)、控制文档元数据的指令(Header, RequestHeader, SetEnvIf, SetEnvIfNoCase, BrowserMatch, CookieExpires, CookieDomain, CookieStyle, CookieTracking, CookieName)、mod_rewrite中的指令(RewriteEngine, RewriteOptions, RewriteBase, RewriteCond, RewriteRule)和mod_actions中的Action指令。
Indexes
允许使用控制目录索引的指令(AddDescription, AddIcon, AddIconByEncoding, AddIconByType, DefaultIcon, DirectoryIndex, FancyIndexing, HeaderName, IndexIgnore, IndexOptions, ReadmeName, 等)。
Limit
允许使用控制主机访问的指令(Allow, Deny, Order)。
Options[=Option,...]
允许使用控制指定目录功能的指令(OptionsXBitHack)。可以在等号后面附加一个逗号分隔的(无空格的)Options选项列表,用来控制允许Options指令使用哪些选项。

所以对于 URL rewrite 来说,至少需要把目录设置为

<Directory /myblogroot/>
    AllowOverride FileInfo
</Directory>

标签 ( WebDev ) :
+ 0 - 0 | §XSLT中的按日期排序
XSLT 1.0 的 <xsl:sort> 元素提供了对 xml 数据进行排序的功能,但支持的数据类型只有 "text" | "number" | qname-but-not-ncname 。如果想对数据按照日期进行排序,就需要采用变通的方式。  查看全文
标签 ( WebDev ) :
+ 1 - 0 | §[存] IE6下DIV高度显示的Bug

IE6下默认的字体尺寸大致在 12 - 14px 之间,当你试图定义一个高度小于这个默认值的 div 的时候, IE 会固执的认为这个层的高度不应该小于字体的行高。所以即使你用 height: 6px; 来定义了一个 div 的高度,实际在 IE 下显示的仍然是一个 12 px 左右高度的层。

要解决这个问题,可以强制定义该 div 的字体尺寸,或者定义 overflow 属性来限制 div 高度的自动调整。比如 <div style="height: 6px; font: 0px Arial;"></div> 或者 <div style="height: 6px; overflow: hidden;"></div> 都可以阻止 IE 的自作聪明。

该问题在 IE7 / Firefox /Opera 下均不存在。

标签 ( WebDev ) :
+ 0 - 0 | §IE7下的href处理问题

不知道什么时候开始每次进入 Google ReaderManage subscriptions 界面之后,无论点选哪一个 Tab 链接页面都会一闪之后自动跳回 Reader 的主页去。但我明明那时候是通过这里的 Import/Export 把 feeds 导进去的,结果现在想在到这里把 feeds 导出来做备份就死活进不去了。

原先我以为是 Google 的开发人员在对这些功能进行修改,暂时作了跳转屏蔽。反正 feeds 放在这里应该也不会出什么大问题,便没太在意。

但今天看到说SPA开始提供多国语言界面就想去试下。结果到了 snap 的定制页面 想选择 Bubble Language 为简体中文的时候,发现一点国旗页面就自动跳转掉了;状况跟 GReader 如出一辙。

查看了两者的源代码,都是使用了类似 <a href="" onclick="{return confirm('Clicked');}">Click Test</a> 的写法。正常来说当点击这样的 URL 链接后, onclick 先被触发,如果触发的处理脚本最终返回 true 的话, href 中的内容会被浏览器打开;如果返回 false 的话,不进行后续处理。

这才想起我前阵子做测试已经把浏览器升级到 IE7 了;赶紧跑到 IE6 和 Firefox 下试了一把,果然 GReader 和 Snap 都恢复了正常反应。

看来 IE7 不论 onclick 的返回是 true 还是 false ,对于 href 的内容是照处理不误( 1 , 2 )。如果不希望 href 坏了 onclick 的好事的话,最保险还是在 href 里面加上 javascript:void(0) 为好。

标签 ( WebDev ) :
+ 0 - 0 | §SPA开始提供多国语言界面

Snap Preview Anywhere™ 预览服务和最初相比,已经相继增加了不少个性化的界面定制功能。今天又从 dimlau 的日志上看到 SPA 已经推出了包括中文简体在内的9种语言界面。试用了一下,感觉中文界面看上去总是没有英文那样舒服。另外现在还提供了两个尺寸的预览窗口选择,觉得原来的预览图太小的话可以选择 large 模式。 进行这两项设置,只需要在原来的代码参数后面增加 &size=large&lang=zh-cn 这两个参数即可。

标签 ( WebDev ) :
+ 0 - 0 | §block-level elements的宽度计算

对于 block-level 的页面元素(比如 DIV )来说,要让他相对于父级元素居中显示的话,标准的做法是为该元素定义的样式中包含 margin: auto; 属性。虽然在 IE 下我们使用 text-align: center; 就可得到居中的效果,但如果要考虑到不同浏览器之间的兼容,还是使用标准的方式比较好( text-align 理论上应该只是用来指定 block-level 元素里面所包含的每一行 inline-level 元素 -- 比如 SPAN -- 的对齐方式)。

来自 CSS3 的相关定义

For block-level elements with horizontal flow in a containing block also with horizontal flow, the computed values of the 'width' and margins must satisfy this constraint:

(width of containing block) =
margin-left + border-left + padding-left + width + padding-right + border-right + margin-right

The following cases can occur:

  1. None of width, margin-left and margin-right are specified as 'auto' and the values satisfy the constraint.
  2. None of width, margin-left or margin-right was specified as 'auto' and the equation is not satisfied. There are two sub-cases: (1) if the 'direction' of the element is 'ltr', the specified value of 'margin-right' is ignored and 'margin-right' is set to the value that makes the equation true; (2) if 'direction' is 'rtl', it is 'margin-left' that is ignored and computed from the equation.
  3. If exactly one of width, margin-left or margin-right is 'auto', its value is computed from the equation.
  4. If width and one or both margins are 'auto', the margins that are 'auto' are set to 0 and the equation is solved for width.
  5. If both margin-left and margin-right are 'auto', the equation is solved under the extra constraint that margin-left = margin-right.

If, after solving the equation, width has a value that is smaller than 'min-width', the computed value of 'width' is set to the computed value of 'min-width' and the constraint is evaluated again as if width had been specified with this value.

If, after solving the equation, width has a value that is larger than both 'max-width' and 'min-width', the computed value of 'width' is set to the larger of 'max-width' and 'min-width' and the constraint is evaluated again as if 'width' had been specified with this value.

Note: case 5 can be used to center block-level elements:

BLOCKQUOTE {
    width: 30em;
    margin-left: auto;
    margin-right: auto }

This is different from 'text-align: center', which centers each line inside the block, but not the block inside its parent.

Block-level elements with a vertical flow inside a containing block with a vertical flow are analogous, but with a constraint on height and margin-top/margin-bottom:

(height of containing block) =
margin-top + border-top + padding-top + height + padding-bottom + border-bottom + margin-bottom

标签 ( WebDev ) :
+ 0 - 0 | §[存]关于innerText等
innerText 属性在 IE 浏览器中可以得到当前元素过滤掉 HTML Tags 之后的文本内容,在某些时候还是比较有用。但类似的非标准属性/方法在其他浏览器中并不一定都得到支持。  查看全文
标签 ( WebDev ) :
+ 0 - 0 | §web页面中的键盘事件捕获
基本上所有的HTML元素都可以触发 onkeypress 和 onkeydown 事件,通过对这个事件的处理就可以达到页面键盘快捷键的设置。  查看全文
+ 1 - 0 | §Links 2006-10-31: Censored Data API
标签 ( WebDev ) :
+ 1 - 0 | §Apache安装后自启动配置

下载源码包 make && make install 之后, apache 并不会自动往 init.d 里面添加自己的 httpd service。需要手工把 apache 安装目录的 bin/apachectl 拷贝一份到 /etc/init.d/httpd 。如果想让 httpd service 能够在不同的运行级别下都能自动启动,还需要 vi /etc/init.d/httpd ,在 #!/bin/sh 下面增加几行 chkconfig 需要的内容:

# chkconfig: 2345 70 30
# description: Apache is a World Wide Web server.  It is used to serve \
#              HTML files and CGI.
# processname: httpd

关键是 chkconfig: 2345 70 30 这一行,第一个数字 2345 表示让 apache 在 2345 这四个级别都自动运行;第二个数字 70 表示进程启动的优先级;第三个数字 30 表示进程停止的优先级。修改保存之后执行 /sbin/chkconfig httpd reset ,chkconfig 就自动在各个级别的 rc*.d 中增加 httpd 的 link 。要查看 chkconfig 是否 reset 正确,通过命令 /sbin/chkconfig --list httpd 就可以查看当前 httpd service 被配置在哪几个运行级别自启动。

标签 ( WebDev ) :
+ 2 - 0 | §当td为空时怎样显示其边框

  之前总结了下如何用 css 来实现 table 的 border + bordercolordark + bordercolorlight 的边框明暗效果,然后有网友问我为什么他写了一个类似的 css 样式,但只能在 Opera 下正常看到表格的边框效果, IE 下则什么也没有。

  于是我跑去下了个 Opera9 一看,确实如此。原因倒也不复杂:因为在 IE 下( Firefox 似乎和 IE 一致)如果某个 td 的内容为空的话,即便你设置了高度和宽度,这个 cell 的边框样式也是不会被显示出来的; Opera 则不管是否有内容与否,一概应用样式来渲染。这个问题刚毕业那会就碰到了,当时部门的科长来问我,后来我跟他说:给每个空的 td 加上   就行了。以后每次碰到这个问题,我就统统采用这个简单粗暴有效的方式来解决了。

  但今天卯足了劲研究了几下,从 Jiarry 那知道原来 css 语法是允许我们对这些缺省行为进行改变的:使用 border-collapse:collapse;empty-cells:show; 就可以让消失的边框显现出来。

class="test1": 加 border-collapse:collapse;

.test1{
    border:1px solid #999999;
    border-collapse:collapse;
    width:60%
}
.test1 td{
    border-bottom:1px solid #999999; 
    height:28px; 
    padding-left:6px;
}

class1  这儿有内容
这儿有内容  


class="test2": 加 border-collapse:collapse; 和 empty-cells:show;

.test2{
    border:1px solid black;
    border-collapse:collapse;
    width:60%
}
.test2 td{
    border-bottom:1px solid black; 
    height:28px; 
    padding-left:6px;
    empty-cells:show;
}

class2  这儿有内容
这儿有内容  


class="test3": 不加 border-collapse:collapse; 和 empty-cells:show; 的情况下

.test3{
    border:1px solid #999999;
    width:60%
}
.test3 td{
    border-bottom:1px solid #999999; 
    height:28px; 
    padding-left:6px;
}

class3  这儿有内容
这儿有内容  

标签 ( WebDev ) :
+ 2 - 0 | §关于Blog顶部的滚动导航条代码
不少朋友通过各种方式问我要 Blog 顶部的滚动导航菜单的代码。其实也没什么特别的,但既然有需求,我就还是把这部分代码整理出来,供大家参考。附加冰男所要求的浮动在窗口底部的代码。  查看全文
+ 0 - 1 | §[存] Scripting.Decoder 代码
Windows Script Encoder 对 asp / vbscript / jscript 等脚本进行编码混淆。收集些解码相关的资料。  查看全文
+ 0 - 1 | §[转]JavaScript中的集合及效率
由于 JavaScript 的语言特性,我们可以向通用对象动态添加和删除属性。所以 Object 也可以看成是 JS 的一种特殊的集合。虽然这个集合的 key 只能是 String 类型,不像 Java 里面的各种集合类能够使用各种对象作为 Key ,但对于实现一般的客户端 JS 功能来说,已经是足够用了。同样,因为所有的 JS 内部对象都继承自 Object 对象,所以实际上 JS 的 Array 对象也可以使用字符串来做为数组的下标,就像 PHP 中的数组变量一样。来自鸟食轩。  查看全文
+ 0 - 0 | §bordercolorlight的CSS实现
在 IE 中可以对 table 使用 border + bordercolordark + bordercolorlight 来实现表格边框的明暗效果。但要通过对应的 css 样式定义来实现这种效果,并没有直接的相应属性可用(何况这是IE独有属性)。  查看全文
标签 ( WebDev ) :
+ 0 - 0 | §url rewrite 的善后工作

RewriteEngine On
RewriteRule ^entry/([0-9]+)$ blog/entry.php?id=$1&avoidrepeat=1 [L]
RewriteCond %{QUERY_STRING} ^id=([^&]+)$
RewriteRule ^blog/entry\.php$ /entry/%1? [R=301,N]

  由于一开始的时候主机并不支持 mod_rewrite ,所以日志的 url 都是带 ? 参数的动态 url 。这次决定把该 SEO 的都给 SEO 起来,于是在根目录下加了这个 .htaccess 文件。

  但想要让原来已经被 Search Engine 收录的动态 url 自动转到新的静态化的 url 上来却颇费功夫。本来以为直接加一条 R=301 的 RewriteRule 就行了,可实际上 RewriteEngine 对于 rewrite 之后的最终url与初始url完全一样的逻辑会直接给 Ignore 掉,所以必须加上一个无意义的 &avoidrepeat=1 参数来让 RewriteEngine 认为这是两个不同的请求。另外对于 ? 后面的参数字符串必须在 RewriteCond 里面来匹配而不是直接在 RewriteRule 匹配。

  经过这样的处理之后,无论是通过老式的 entry.php?id=XXX 方式还是经过静态化的 /entry/XXX 方式来访问,最终都会定位到 /entry/XXX 这个静态化的 url 上,对于 Search Engine 来说应该可以更快的根据 R=301 的状态码来更新它的索引库。

标签 ( WebDev ) :
+ 0 - 1 | §Apache mod_rewrite 之目录冲突

  现象:在 VirtualHost 配置块中启用 RewriteEngine ,进行 url rewrite ,结果发现重写到某一个目录下的url总是报错,说是 url 不存在。但通过实际的动态url去访问一切正常。

  httpd-vhost.cnf相关配置如下:

<VirtualHost *:80>
    ServerAdmin noname@gmail.com
    DocumentRoot /www/html/scripts
    ServerName scripts.zeali.net
    ErrorLog /logs/scripts.zeali.net-error_log
    CustomLog /logs/scripts.zeali.net-access_log common
<IfModule rewrite_module>
RewriteEngine On
RewriteRule /entry/([0-9]+)\.html /live/entry.php?id=$1
</IfModule>
</VirtualHost>

  反复测试,发现如果把 /www/html/scripts 下的 live 目录重命名成其他的名字, url rewrite 就完全正常。难道说 live 是 mod_rewrite 的关键字?不太可能。继续检查,发现在操作系统的根目录下存在一个同名的 live 目录。把这个目录删除之后, rewrite 恢复正常。

  结论: mod_rewrite 在执行 RewriteRule 的时候首先寻找的是操作系统的目录层次,而不是 DocumentRoot 下的相对目录层次;因此如果不幸在 DocumentRoot 目录下存在与操作系统根目录下一样的目录, mod_rewrite 将不会正确的找到 rewrite 的目标 url 。Updated 2006-07-18 14:40 -- 如果使用 .htaccess 文件设置 RewriteRule 的话,因为使用的是相对目录形式,就不会存在这个问题。

  目前暂时找不到明确的文档来印证这个问题,或者说我对 mod_rewrite 的理解太浅。希望能看到更准确的说法来诠释这个现象。在此之前,只能认为这是 mod_rewrite 设计上的问题,注意不要让需要加入 RewriteRule 的文档地址与操作系统的目录结构发生冲突。

标签 ( WebDev ) :
+ 0 - 0 | §Links 2006-07-03: EasyEclipse
  • EasyEclipse
    Eclipse之所以势头如此强劲,甚至于搞到 Borland 都心灰意冷宣布出售整个 IDE 产品线 (虽然没有明显证据可以表明两者之间的因果关系),其开放性大概占了主导因素。
    抛开开源免费的特性不谈,作为一个 SDK 而不是单纯的 IDE 面目出现,使得 Eclipse 具有了强大的生命力。只要是跟开发相关的功能需求,都可以作为扩展插件集成到这个统一的平台中去,最大限度的吸引了使用各种不同语言开发者的注意力( Firefox 打的也正是这一手牌)。
    但在带来无比自由的同时,往往也会让初用者感到迷茫。如果你不知道该为你的 Eclipse 配些什么兵器的话,不妨到 EasyEclipse 逛逛。
  • Google Answers: Understanding ulimit output
标签 ( WebDev ) :
+ 0 - 0 | §attribute.specified属性

  Pivot 自带的 wysiwyg 编辑器功能比较少,扩展起来也不方便,虽然 1.3 版本引入TinyMCE ,但都不合自己的习惯。好在可供选择的 wysiwyg 在线编辑器多得数不过来, Genii Software 甚至专门对这些编辑器做了详细对比。最终 我选择了 "excellent and easy to use" 的 Xinha 。不过再好的东西也会有 bug (尽管有时候 javascript 的脚本所谓 bug 往往是拜浏览标准的混乱所赐)。

  最近发现用 Xinha 切换到 HTML Source 模式添加了图片 Map 区域之后( <AREA title="点击查看大图" shape="RECT" target="_blank" coords="0,0,81,150" href="http://www.zeali.net/images/lina/lina1.jpg"> ),切换回 wysiwyg 模式再切回来,AREA Tag 的 shapecoords 属性就消失了。一路跟踪下来,发现 Xinha 在 Toggle HTML Source 的过程中,使用了 HTMLArea.getHTMLWrapper 方法对整个内容进行了格式化处理,这其中用到了 attribute.specified 属性进行判断:

    if (!a.specified && !(root.tagName.toLowerCase().match(/input|option/) && a.nodeName == 'value')) {
        continue;
    }

  而让人想不通的是,对于 shapecoords 这两个属性来说,无论是否在 HTML 里面进行了设置, specified 的值都是 false ,而不是像 msdn 文档里面所描述的那样 “An attribute is specified if it is set through HTML or script”,只有像 title , target, href 这种比较常规的属性才能通过 specified 的值来判断是否已经做了设置。也正因为如此, Xinha 在对 HTML 代码进行重新格式化的时候, shapecoords 这两个属性的相关内容就被直接 continue 给忽略掉了。

  有意思的是从 Xinha 上面的那段代码来看,已经对 inputoption 这两个 Tag 的 value 属性进行了排除,可见 value 属性遭受的“不公平”待遇类似于 shapecoords 。可惜 Xinha 好事没做到底,msdn 貌似也没有明确的指出哪些 Tag 的哪些属性无法通过 specified 的值来判断存在与否,所以也只能是发现一例例外就在原来的语句基础上增加一个过滤语句了:

    ... &&
    !(root.tagName.toLowerCase() == 'area' && a.nodeName.toLowerCase().match(/shape|coords/))

  搞定,收工。

标签 ( WebDev ) :
+ 0 - 0 | §两个与Firefox相关的问题

  今天偶然发现在 Firefox 下点击我 Blog 页面头部的 RSS feed 图标并不像在 IE 下那样可以正常的跳转到 RSS feed XML 页面。难怪之前好像有朋友问我说我的 Blog 上的 RSS 订阅哪里去了?

  原因:因为我用的是 window.navigate("URL") 而不是 location.href='URL' 来做跳转;不幸的是 Firefox 并不支持 navigate 方法。所以以后任何地方要做跳转,忘了 navigate 吧!

  RSS feed 图标可以正常点进去了,又发现 RSS feed XML 的内容显示似乎有点异样。仔细一看原来是正文的内容没有被正确的转化回 html 格式化内容。

  原因:因为我为这个 xml 文件加了 xsl 定义文件,并对于每篇日志的正文部分使用了 disable-output-escaping='yes' 属性来通知浏览器的 xml parser 不要把这部分 html 代码转义。同样的,这个属性为 MSXML 所支持,但 Transformiix 引擎就不支持了。 Firefox 等浏览器使用的 XSLT Processor 恰恰是 Transformiix 。所以,对于 Transformiix 系的浏览器,只能采用“曲线救国”的方法了,利用 javascript 代码找到所有没有被浏览器自动转义回来的内容并进行正确的转义, BunnyQ 在日志中详细描述了解决方案(包括其他几个需要注意的 XSL 兼容性问题)。我最终使用了比较简便的方式:

  在原先的代码
 <div class="list_introduce" id="content">                          

 <xsl:value-of select='description' disable-output-escaping='yes' />
 </div>                                                             

  后面增加一段专门针对Transformiix的处理代码
 <xsl:if test="system-property('xsl:vendor')='Transformiix'">       
 <script language="javascript">                                     
 var el = document.getElementById("content");                       
 el.innerHTML = el.textContent;                                      
 </script>                                                          
 </xsl:if>                                                          

标签 ( WebDev ) :
+ 0 - 0 | §CSS, array_shift怪事两片

css里面漏写一个分号,在本地浏览居然还能显示正常的效果,通过域名访问css的效果就不见了;

while($val=array_shift($arr))死活shift不出东西来,改成foreach($arr as $val)才正常;

但想通过测试代码来重现这两个现象,居然重现不了,css漏写分号就是显示错误,array_shift也能正常shift。郁闷ing。

刘润说:“不要搞封建活动。”再离奇的表象都可以找到合理的技术性解释。只不过在我们发现真相之前,往往被表象指引到一个错误的方向去思考问题了。

标签 ( WebDev ) :
+ 1 - 0 | §奇怪的insertCell

同一段代码在不同的机器上执行结果却莫名其妙的不同,这是最让人郁闷的事情。这两天用 DHTML 的 insertCell 方法来通过 javascript 脚本动态增加表格内容。在自己的本本上一切正常,等到让别人用的时候发现 insert 进去的 td 顺序正好倒了过来,本来应该是第一列的变成了最后一列。折腾半天,发现调用 inertCell 方法的时候可以不填写 index 的值,默认情况下自动添加td到当前行的末尾 oTD = TR.insertCell( [iIndex]) 。于是把所有的 index 参数去掉,问题消失。

等到后来想写段测试代码来重现这个问题,居然死活重现不了。

猜测:只有当 insertCell 遇上 XXX 之后才会出现插入顺序错误的问题,并且只有在WinXP sp2的 IE 上才会出现(我的本本是sp1,甚至我在 Firefox下看到的都是正常的)。

+ 1 - 0 | §Links 2006-04-20: 表格文字自适应
标签 ( WebDev ) :
+ 0 - 1 | §Links 2006-04-05: CSS Caching Hack
  • CSS Caching Hack
    为了防止页面被浏览器给Cache住而导致用户看不到更新了的内容,我们通常会在URL后面添加一个随机变化的参数,比如 http://.../myarticle/10022.xml?e234kk23s8234 。不过我们往往会忽视 CSS 样式文件被Cache的后果。事实上现在的页面内容和表现日渐分离,整体观感完全依赖于 CSS 文件,一旦你对服务器上的 CSS 文件做了些关键性的修改(比如增加了样式定义)并且在你的 html 文件里面使用了这些新的样式定义,用户再来浏览你的页面可能会发现页面忽然变得极其丑陋,必须按Ctrl-F5强制刷新所有内容才能看到正常的页面表现。这是因为在你的html页面得到更新的时候,css样式文件并没有被浏览器同步更新。因此,我们应该为引用的css样式文件也添加这样一个可以变化的参数来根据实际情况要求浏览器真正重新抓取一遍,比如:<link rel="stylesheet" xhref="http://www.zeali.net/css/zeal.css?version=1" type="text/css" />
  • Google Related Links
    类似 Google AdSense ,在你的页面上放置一段代码,Google自动把相关的新闻、链接显示出来。当然理论上来说这些相关内容是真正与你的页面相关,而非别人通过付费购买的 AdWords ,你也并非通过放置这段代码来赚取广告费,纯粹为了提高页面内容的丰富性。这样一个缺少明显驱动力的东西愿意去使用的人大概也就不多,何况据说目前这个服务对中文的支持度还有待提高。。
  • How to quit your software job and become a millionaire instead
标签 ( WebDev ) :
+ 2 - 1 | §Comet: keep-alive Ajax

  我在之前的日志里面提到:“当这种冗余的数据传输变得相当频繁的时候(比如我之前所做的即时比分系统为了让浏览器第一时间得到最新的比分变化XML数据必须以2、3秒一次的频率不停的刷新这个XML地址,或者类似的一些即时证券股票交易系统),由此所造成的网络带宽的无畏消耗会变得相当惊人。”

  对于这个问题,临时性的解决方法是采取各种手段(压缩XML数据、采用YAML格式、优化 Http Header)减少数据传输量。但从根本上来说,只有让数据按需传输,才会使流量最小化。本来计划设计实现基于 server-push + Ajax 版本的即时数据分发系统,因为种种原因完全搁置了起来。现在 Alex 给它取了个名字叫 Comet ,并详细的描述了这个名词所代表的内容。

  意料之中的,不少人对这个新名词嗤之以鼻。但在我看来,即便这个 Comet 是一个卫浴清洁剂品牌,至少是对现有技术的归纳总结,跟别人介绍的时候也免得大费口舌。就像 Ajax 一样,虽然只是几样老技术的综合体,之前也有不少人已经在用着这些技术;但只有在 Ajax 这个名词流行起来之后,才真正得到了大规模的应用,各种基于 Ajax 的 frameworks 才争相出炉。对于后进的开发者来说,有了 Ajax 这么一面大旗指路,就意味着少走一大段别人走过的路。

  所以,不管这个架构最终会以什么外貌风行,姑且就叫做 Comet 。 Comet 实际上就是在传统的(这个词对于 Ajax 不知道是否合适) timely client-side pulling Ajax 基础上引入 server-side push 机制,在客户端(通常是 Browser )与服务器之间建立 long-lived 连接, server根据需要把数据主动的 push 到客户端。要做到这一点最简单的可以利用 HTTP 协议的 Keep-Alive 头,但如果要能很好的支持大并发量、方便的实现业务逻辑扩展,就不太可能基于传统的 Web server 来实现服务端的程序,只有重新设计 server 。

  正如 Ajax 风行之前已经有许多开发者在利用 XMLHttpRequest 来实现着自己的应用一样,有着 Comet 概念的产品目前也并不算少:LightstreamICEfaces这样的商业化产品;Pushlets这样的开源项目。相信在一段时间的技术沉淀之后, push style Ajax 会像当初的 Ajax 一样得到个响当当的头衔。

标签 ( WebDev ) :
+ 1 - 0 | §Links 2006-03-01: ActionScript3.0
标签 ( WebDev ) :
+ 0 - 0 | §Links 2006-02-22: Prototype
标签 ( WebDev ) :
+ 1 - 1 | §Maxthon下浮动层的莫名消失
好多天没博了,这里杂草渐多。贴一段测试代码上来,演示浮动层在Maxthon下面会莫名其妙找不到的效果。之前写了一篇“Maxthon对IE的劫持”,HunterXP说那是因为我对Maxthon不了解,只要设置好了Maxthon和IE是完全一样的。今天记录下这个小问题,也是顺便可以佐证一下我的观点:即便使用的是IE的内核,也不可能有哪个浏览器是和IE“完全一样的”。任何程序在实现的时候总会有bug的存在;同样的接口提供给不同的人来调用,所实现出来的东西也会天差地别:)  查看全文
标签 ( WebDev ) :
+ 1 - 0 | §辞旧迎新,上UTF-8

  一直以来想把这个从GB2312改到编码,但因为pivot采用的文本数据库使用PHP的serialize存档方式,数据结构依赖于字符串长度,一旦从GB2312改到UTF-8,非英文字符串的长度就发生了变化,原有的日志读取将发生错误。日志一天天增多,编码切换可能的潜在危险就让我越来越不敢去做这件事情了。

  昨天终于咬咬牙,决心彻底搞定这个问题,算是给自己新年带来的第一个新气象吧。写GB2UTF8的批量日志文件编码转换脚本、更新语言文件/模板文件、增加新的UTF-8相关字符串处理函数,一切在本地机器上测试相当顺利。没想到覆盖到服务器上的时候居然出现莫名其妙的问题,页面没法正常重新生成。用ftp维护上传文件是件痛苦的事情,经过几个小时的折腾,终于是“暮然回首”,在pivot站点上发现了db repair的工具可以轻松的解决问题,修复升级之后被局部破坏的数据文件。

  总算大功告成,两点教训:

  • 覆盖之前一定要在服务器上备份目录,而不是只在本地备份!不同环境下的备份即便只是简单的copy,也可能存在差异性。没有服务器Shell登录的权限,也可以想办法用PHP的passthru之类的系统命令调用来曲线执行Shell命令。
  • 碰到问题最好先到官方站点找找答案。看似简单的问题可能会越变越复杂,不如在自己给自己设套之前看看是不是有更简单现成的解决方法。
标签 ( WebDev ) :
+ 1 - 0 | §[转]prototype 源码解读
Prototype is a JavaScript framework that aims to ease development of dynamic web applications. Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for Web 2.0 developers everywhere.Ruby On Rails 中文社区的醒来贴了自己对于prototype的源码解读心得,颇有借鉴意义。  查看全文
标签 ( WebDev ) :
+ 1 - 0 | §eval() may be evil
Simon Willison 认为:虽然提供了把动态字符串作为脚本代码来执行的 eval() 函数,为代码的编写提供了很多的便利,但同时也导致了代码执行效率的低下以及难以维护。通常来说,只有设计存在缺陷才会不得不用 eval() 来弥补这些缺陷。  查看全文
+ 1 - 0 | §用YAML节约网络传输带宽

  XML无疑在如今的各种网络/传统应用中扮演着重要的角色,不同服务之间通过统一的结构化标记语言来交换数据、发送请求,同时能进行文档的结构合法性检查。尤其时下大热的Ajax框架中,XML更是不可或缺的角色。

  但同时,提供这些便利和健壮性的代价是数据传输量的倍增。有时候用以完整表述文档所使用的Tags和Attributes甚至比实际内容本身还要多。

  当这种冗余的数据传输变得相当频繁的时候(比如我之前所做的即时比分系统为了让浏览器第一时间得到最新的比分变化XML数据必须以2、3秒一次的频率不停的刷新这个XML地址,或者类似的一些即时证券股票交易系统),由此所造成的网络带宽的无畏消耗会变得相当惊人。当然,我们可以通过调整Web Server的HTTP Header做些有益的工作(gzip, Http 1.1 Etag 与 Last-Modified等),但何不同时也考虑一下在优雅的XML之外使用其他的数据组织方式来传输那些“带宽至上”的数据?

  YAML作为一种更为紧凑的数据序列化格式,在保证数据结构可读性的同时大大减少了结构化所需要的额外数据量。Laurence Moroney比较清晰的描述了XML和YAML之间的异同以及YAML的基本语法以及基本的YAML数据生成和解析的方法。

  对于YAML来说最大的问题是其流行程度。目前的.NET和Java平台对YAML语法的解析支持都比较欠缺(不像XML你可以轻而易举从各种途径找到最好的解析器)。但 RubyPython 等已经提供了对YAML的很好支持 -- 包括PHPPerl。流行度引发的另一个问题是YAML的数据结构目前无法通过DOM接口来解析,也就是说你如果在使用Ajax或者其他涉及到客户端DOM接口的应用,要么就放弃使用YAML的念头,要么就把YAML的内容包装在一个最简单的XML Tag之内,通过DOM来获取文档,然后再使用自己的YAML解析器来解析封装在里面的实际的YAML数据内容。

  如果你的系统符合这些条件,不妨试试YAML:

  • 用XML来交换数据使你的网络带宽支出费用剧增(随着用户数的增加)
  • 数据的生成和接收方都在你的可控范围
  • 你没有太多的时间去从头设计定义一个完全个性化的数据交换结构
  • (或者)你正在使用Ruby :)

see also:
XML 问题: YAML 对 XML 的改进
Slaven Rezic's Javascript binding
Using YAML to Decrease Data Transfer Bandwidth Requirements
YAML 和 Ruby

标签 ( WebDev ) :
+ 0 - 0 | §dp.SyntaxHighlighter
dp.SyntaxHighlighter是一个不错的源代码语法高亮插件,用于你的页面中通过js来动态实现语法高亮显示你的源代码。  查看全文
+ 2 - 0 | §getElementsByClass

获取XHTML页面上所有具有相同className的Element对象的javascript函数:

/**
* rootNode          the root node to be checked on,
*                   for example 'document'
* classToSearch     className to be matched
* tagName           elements name to be searched between,
*                   '*' for all elements in 'rootNode'
* returns           an array contains all elements matched

*/
function getElementsByClass(rootNode,classToSearch,tagName) {
    var elementsToReturn = new Array();

    var elementList = rootNode.getElementsByTagName(tagName);
    var nLen = elementList.length;

    var pattern = new RegExp("\\b"+classToSearch+"\\b");

    for(var i = 0; i < nLen; i++){
        if( pattern.test(elementList[i].className) ){
            elementsToReturn[elementsToReturn.length]
= elementList[i];
        }
    }

    return elementsToReturn;
}

标签 ( WebDev ) :
+ 1 - 0 | §Ajax without XmlHttpRequest?

  Ajax & PHP without using the XmlHttpRequest Object,这样的一个标题足够吸引我去看个究竟。然而文章本身其实倒没有太多特别的东西,简而言之是介绍了如何利用动态加载js来实现页面的无刷新数据提交。不过随后的四十几条回复评论内容却很丰富,讨论也颇激烈,让我一口气把它们给看了下来。

  这其中议论的一大焦点在于作者采用的标题把Ajax给扯了进来,热门名词自然引发热门讨论。在不少人为这篇文章叫好的同时,大量Ajax'ers则认为文章所涉及的技术不值一晒。

  • 从纯粹的字面来理解,既然没有XmlHttpRequest的使用,Ajax中的'x'基本上来说也就无从谈起,自然算不上Ajax了。作者多少有些文不对题自相矛盾。
  • 从功能性上来说,通过 document.createElement('SCRIPT') 来动态创建js的引用,继而完成客户端数据的异步提交,只能算是类Ajax风格。如果考虑到客户端与服务器之间的交互性和数据提交状态的可跟踪性,js无疑是没法和XmlHttpRequest Object相提并论的。

  Ajax是个好东西;Ajax之流行带来大量Ajax Framework的涌现对于开发人员来说更是好事(想当初为了实现这些功能所有代码都是自己从头一点点写出来的,早流行几年的话能给我省多少力气啊)。问题在于现在的Ajax就像web2.0一样,被说滥、用滥了。针对Ajax & PHP without ...一文的各种反对声音的批判逻辑往往是:“你这不是Ajax style的,所以你这东西就是trash。”

  但其实很多时候,我们的需求只是像Ajax & PHP without ...文中的示例那样让表单提交过程更酷一点、避免整个页面的刷新而已。对于这些简单的需求,通过各种其他的"伪"Ajax技术来实现,足矣。其中一个回复评论提到的这篇文章很能说明问题。Remote Scripting的实现方式向来就有多种,针对不同的应用需求完全可以选择不同的解决方案。Ajax这个名词之所以流行,只是因为目前有像Gmail这样重量级的优秀应用实例出现吸引了足够的眼球而已。即使不用XmlHttpRequest对象,我们也可以使用Java Applet来实现类似的数据交互,甚至可以在Flash8里面用XMLSocket来做这件事情。

  也许作者给自己的文章换个标题效果会更好 -- 就像 Javascript includes - yet another way of RPC-ing 和 Remote scripting with javascript 这两篇讲述类似内容的日志那样。

标签 ( WebDev ) :
+ 1 - 0 | §从和讯网摘到美味书签

厌倦了和讯网摘的不道德(网摘显示的地址都是和讯的跳转页面而非最终url)和功能的不完整(至今也没有提供API和导出功能),而365key上面充斥着太多的垃圾条目,兜来兜去,我决定还是用回到美味书签。

好在我放在和讯上的网摘数量不多,总共一百多条,分页显示也就两页内容,可以很容易的把所有网摘的html代码拷贝下来。就算数量多,用程序去循环抓取也还简单。

原始信息有了,需要把它们解析出来导入到del.icio.us中。我选择用来对原始html进行整理生成一个PHP数组变量,然后通过REST API把所有的网摘一次性导入(del.icio.us目前似乎屏蔽了导入功能,否则直接生成标准格式的bookmark文件就可以导入了,可以省去调用它的API接口的麻烦)。当然要注意执行导入的PHP脚本文件应该是UTF-8格式。

导入过程还算顺利,只是有几点小问题:

  1. 和讯网摘列表对于单个网摘只显示最多两个tag,所以对于两个以上的tags就只好让它丢失了
  2. 和讯网摘的网摘描述可以放很长一段文字,以至于我以前收录的时候有时候把文章正文全部作为描述放进去了,而del.icio.us支持的描述文字长度有限(中文字大概100个左右),所以只能把超长的文字截去
  3. 中文tags有些字造成乱码,好在数量不多(两三个),导入以后需要手工修改一下这几个网摘的tags

不管怎么说,所造成的问题在我能接受范围之内。

标签 ( WebDev ) :
+ 0 - 1 | §FireFox的iframe显示问题

  笔记本和家里的PC全部都重装了,顺便也就装上了Firefox 1.5 RC版。结果发现自己之前费了老大劲在Firefox1.0.x下面修改的Blog显示代码到了这个1.5RC又出现了问题。

  最大的问题是iframe的显示又不对了,大部分的iframe内容统统变成白板,而且iframe页面的高度也完全和原来不一样。

  经过无数次的测试+Google之后,终于把问题最终定位:原来我把iframe作为一部分内容放在了DIV里面,为了页面美观,我用js首先把这个DIV设成了display = 'none';然后在iframe的onload里面在把这个层设置为可见,同时根据实际的iframe.document的高度来动态调整iframe的高度。

  这些操作在IE和Firefox之前版本里面能够正确的表现出来,但在1.5RC里面,Firefox似乎发生了一些错乱,当iframe载入文档的同时进行了DIV的display='none'操作(或者是Firefox本身对这两种操作进行了同步化?),这之后再去通过设置display='';来显示DIV的内容的话,IFRAME就会出现空白一片,除了iframe之外的页面元素却能全部正常的显示。

  虽然知道了问题所在,但看来目前我没有更好的解决方法,只能是调整自己js的处理,暂时去掉了把DIV隐掉的操作。同时把这个现象作为bug提交给了bugzilla,希望在1.5的正式版本不会有这个问题存在。

----

P.S. 这个1.5版本有一个好的改进,那就是对于iframe高度的计算,之前的版本计算出来的高度不准确,以至于我必须在js里面单独针对Firefox进行判断:

//extra height in px to add to iframe in FireFox 1.0+ browsers
var FFextraHeight=getFFVersion>=1.0? 16 : 0 ;

来把这个缺掉的16px的高度给加回去。现在1.5版本就完全不需要进行这个修补了:)

标签 ( WebDev ) :
+ 0 - 0 | §自定义MSN的日志显示风格
本文对于习惯使用MSN Shell之类的插件来记录个性化聊天记录或者根本就没有打开“自动保留对话的历史记录”的MSN Messenger用户来说帮助不大。但如果你是在使用MSN Messenger自带的聊天记录保存功能的话,或许可以通过以下的介绍对其进行一些个性化修改。  查看全文
标签 ( WebDev ) :
+ 1 - 0 | §Macromedia三剑客v8中文版

Macromedia Studio 8 简体中文版已经开始公开发售 >>

Flash 8 : http://www.codepub.com/Software/View-Software-3903.html

Dreamweaver 8 : http://www.codepub.com/Software/View-Software-1185.html

Fireworks v8.0 : http://www.codepub.com/Software/View-Software-3801.html

其他两个也就算了,这Flash 8可是很可能和接下来的工作息息相关,不得不去关注的了。

标签 ( WebDev ) :
+ 0 - 0 | §用Javascript检测Flash功能是否可用
  通常我们在网页上使用Flash的时候都不会去考虑用户使用的是哪个版本的Macromedia Flash Player。而实际上尽管90%以上的用户都已经安装了Flash播放插件,却并不是每个人安装的插件都是比较新的Flash 5或6的版本。当你在Flash里面使用了一些新版本独有的特性的时候,那些仅仅安装了旧的兼容版本的Flash播放器的用户很可能将无法正常观看你费尽心力制作的内容。同时对于那些不使用IE浏览器的用户来说,他们的浏览器可能压根就不支持插件自动提示安装的功能,那将是更糟糕的事情。
  对于开发人员来说,任何时候都不应该把自身产品的可用性依赖于用户的高智商上面。如果你指望用户自己通过阅读你的帮助页面来自己发现并解决这些播放器兼容性和下载安装的问题,那么你的产品离被用户抛弃也就不远了。  查看全文
标签 ( WebDev ) :
+ 0 - 0 | §万恶的源泉是什么
今天在薄荷的Blog上看到了对于Javascript的批判,基本上来说对于现象的描述很到位。然而Javascript脚本被滥用,能说是Javascript自己的错么?  查看全文
标签 ( WebDev ) :
+ 0 - 0 | §你可能不知道的CSS语法技巧
Webcredible上列出了不少关于CSS使用语法上的小技巧,还是比较实用的。以前很多东西只知道要这么写,可很少去考虑为什么。看来用CSS能做的事情远远比自己所了解的要多。  查看全文
标签 ( WebDev ) :
+ 1 - 0 | §URL编码方法的比较

javascript中存在几种对URL字符串进行编码的方法:escape(),encodeURI(),以及encodeURIComponent()。这几种编码所起的作用各不相同。 

escape() 方法:

采用ISO Latin字符集对指定的字符串进行编码。所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。

不会被此方法编码的字符: @ * / +

encodeURI() 方法:

把URI字符串采用UTF-8编码格式转化成escape格式的字符串。

不会被此方法编码的字符:! @ # $& * ( ) = : / ; ? + '

encodeURIComponent() 方法:

把URI字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,比如 / 等字符。所以如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。

不会被此方法编码的字符:! * ( ) '

因此,对于中文字符串来说,如果不希望把字符串编码格式转化成UTF-8格式的(比如原页面和目标页面的charset是一致的时候),只需要使用escape。如果你的页面是GB2312或者其他的编码,而接受参数的页面是UTF-8编码的,就要采用encodeURI或者encodeURIComponent。

另外,encodeURI/encodeURIComponent是在javascript1.5之后引进的,escape则在javascript1.0版本就有。

参考文章: Comparing escape(), encodeURI(), and encodeURIComponent()

标签 ( WebDev ) :
+ 1 - 0 | §浏览器兼容的在线播放器语法

昨天贴了一篇关于beyond的歌曲,采用的是最常见的 <object id="mplayer" type="application/x-oleobject" classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" ... 写法,结果发现在上根本播放不出任何内容。到紫竹梦轩的首页去听她置顶的歌曲,同样也是连播放器都看不到。看来这个又是IE Only的语法了。怎么改?

要显示兼容与IE/Firefox/Opera等浏览器的在线播放器,测试下来比较鲁棒的应该是如下的xhtml代码写法:

<object type="application/x-mplayer2" width="610" height="48" align="" data="/images/beyond_WhoWillGoWithMe.mp3">
<param name="src" value="/images/beyond_WhoWillGoWithMe.mp3" />
<param name="filename" value="/images/beyond_WhoWillGoWithMe.mp3" />
<param name="type" value="application/x-mplayer2" />
Sorry, Your Browser Does not support this player. Please Try IE or Fx to play this media.

</object>

感谢雨吁的Blog所介绍的xhml页面插入mp3的四法之比较

标签 ( WebDev ) :
+ 1 - 1 | §用javascript动态调整iframe高度
当你在页面上使用了iframe之后,一般来说会不希望iframe显示难看的滚动条,以使iframe里面的内容和主页面的内容浑然一体。这时候你会设置 scrolling="no" 属性。但是这样一来如果iframe里面的内容是变化的,高度会随之内容的变化而变化的时候,你的iframe就会显得太长导致底下一大片空白,或者正好相反,由于iframe的高度太小导致一部分内容会被挡住。这里我提供一个兼容IE/NS/Firefox的javascript脚本实现动态调整iframe的高度。如果需要调整宽度的话,原理是一样的,本文不加详述。  查看全文
+ 0 - 1 | §Links(HREF元素)的click方法
对于HTML页面上的超链接(HREF),并不是所有的浏览器都支持其click方法。  查看全文
标签 ( WebDev ) :
+ 0 - 2 | §为你的Blog增加网摘功能
通过一段javascript代码,让用户浏览你的weblog日志的时候可以方便的把喜欢的文章快速收藏到自己的网摘里面。  查看全文
+ 0 - 1 | §兼容标准XHTML的浮动层特效实现
近日对自己的blog进行代码兼容性的改进,发现了原来的很多问题。之前修改了一些基本的CSS语法错误,基本实现了在IE和Firefox下页面观感上的一致。但对于一些js特效,尤其是浮动层的显示上面的问题,一直留着,今天才花功夫进行了修改,使得浮动层的滚动,鼠标拖放都得到了兼容处理。  查看全文
标签 ( WebDev ) :
+ 0 - 1 | §可移动层的实现示例
本文提供了一个通过javascript+dhtml脚本实现在IE浏览器里面显示的可以被鼠标拖动的层。这个层能够自动滚动或者被关闭,就像我的Z-Tips一样:)  查看全文
Since 2005.04.27  梦想 就像鸡蛋 要么孵化 要么臭掉RSS Feed (Entries) | About me | Back To Home | @ZEAL | zbird.com | 沪ICP备05024379号
-->