iColin 

Do what you want
 

Macbook Air使用小记

2012年01月21日

入手MBA也有一段时间了,从一个初级小白进阶成为一个中级小白,下面就分享了使用MAC的一些经验(老手可以直接飘过了)。

GUI介绍

顶部的是任务栏和菜单栏,底部(默认在底部)的是Dock栏,可以理解为快捷方式栏。

设置

一个东西拿到手,总是忍不住研究下里面的设置项。点击任务栏左侧的apple图标,选择-系统偏好设置,弹出的界面中有各种设置项。换下桌面,更改下Dock栏的位置,hover态图标大小。设置输入法什么的。

手势(默认)

一个手指轻敲触摸板/单击触摸板 单击
二个手指上下滑动 滚动
三个手指滑动 在页面中可以选中内容,当焦点在文件上时,可以拖动文件
四个手指
左右滑动 切换屏幕
上下滑动 将当前运行的应用程序全部显式在桌面上,也是快速切换其他应用程序的一种方式
四个手指合起来,显式应用程序列表;四个手指分开,回到之前的应用程序
可以去系统偏好设置-触摸板里面自定义手势

快捷键

command + m :最小化 (右手按)
Command + q :关闭当其应用程式(退出进程)
Command + w :关闭窗口,不会退出进程(比如关闭当其聊天窗口)
Command + o : 打开选中的文件/文件夹
command + , :进入当其应用程序的设置界面 (右手按右边的command的,很方便)
command + h :隐藏当其应用程序 (点击Dock栏的图标即可显式程序)
command + tab :在多个打开的应用程序中切换
command + delete : 删除一个项目到回收站
command + shift + delete:清空回收站
enter : 重命名选中的文件/文件夹

ctrl + a : 回到行首
ctrl + e :回到行尾
fn + delete :删除光标后的一个字符
command + l :定位到地址栏
command + r :刷新

应用程序

  • finder:文件管理器,在finder中,可以按command + 1~4 的组合键来指定项目按照图标、列表、分栏等方式来显式
  • spotlight:号称超强的搜索工具(个人用得比较少,coding直接从vim开始,找文件要进入加密镜像照,spotlight也找不到)
  • iCal:日历软件,可以和google日历同步,很爽哇

安装程序

我了解的有两种方式,一种是DMG格式的文件,打开dmg之后,直接运行里面的install文件,一路Next。另一个中是app格式的,直接把这个app拖动到applications里面即可。

安装的程序去哪里找?可以使用前面说到的手势——四个手指合起来,就能显示应用列表,或者去finder里面的应用程序文件夹下找。注意,系统设置、插件等程序安装后不一定出现。

应用列表

日常类:

  • chrome
  • qq
  • fit输入法
  • 迅雷
  • MplayerX (SPlayerX有个自动搜索字幕的优势)
  • iWork
  • DropBox
  • CleanApp (有洁癖的同学可以用这个更彻底的删除应用)
  • betterZip
  • Evernote
  • Omni Graffle (思维导图工具)
  • 豆瓣FM

开发类:

  • vim
  • xampp
  • Fireworks
  • VMWare fusion

双系统

准备好一个U盘,一个windows操作系统的镜像文件,使用bootCamp很Easy的完成安装。需要注意的是,如果你安装的是win7系统,请使用windows loader激活。如果你使用其他工具激活,启动系统时黑屏等待时间变为30~40s。对这种情况也可以windows loader再次激活即可解决。当然如果你时正版用户,就无需担忧。

另一点,按照双系统后,默认启动的是后面按照的那个系统,可以进入系统偏好设置-启动磁盘,来选择默认启动的系统。

规划个人文件存储

和win不同的是,mac下默认没有各种盘符,所有文件都在Macintosh HD这个磁盘里面,你可以直接在Macintosh HD磁盘下按喜好建立各文件夹存储资料。我个人是这样做的:在磁盘根目录新建code、design、fun三个目录分别存储个人代码、设计和好玩的东西。图片、视频、音乐等都放在mac默认的那些分类里面。对了,隐私文件放哪里好,spotlight太强,我可不想随便让人搜索到。

Mac提供了方便的数据加密功能。即建立一个加密镜像,把隐私数据都扔到这个镜像中。每次访问镜像的数据时需要提供密码。一起来试试吧:

进入应用程序-实用工具-磁盘工具,新建映像,依次填写镜像名称、存储位置、镜像文件夹名称、镜像大小,然后选择128位AES加密,点击创建就OK了。再运行镜像文件,输入密码,你可以放肆向镜像里面放隐私数据了。可是,可是一定要记得密码哦。

更改文件默认打开程序

两手指轻按一个文件,选择-显式简介,然后选择要使用的应用程序,点击全部更改即可。

Android开发环境搭建

2011年08月21日

零基础开始搭建Android开发环境,我们开始吧:

先理解这些名词

  • JDK:Java Development Kit(Java开发工具包)
  • SDK:Software Development Kit(软件开发工具包)

下载必备软件

安装并配置JDK

双击Java安装文件,可以安装到默认路径,亦可自己选择路径,我这里安装到C:/Java/jdk/目录下。然后配置环境变量:

1. 设置JAVA路径

打开“控制面板”-“系统”-“高级”-“环境变量”,在打开的对话框中的”系统变量”下方点”新建”,在对话框
中的“变量名”中填写“JAVA_HOME”,值为”C:\Java\jkd\”,点“确定”。

2. 设置CLASS路径

再新建一个系统变量,变量名为CLASSPATH,值为.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\toojs.jar;。

3. 设置PATH路径

PATH变量一般系统中已存在,所以选择PATH变量,点击“编辑”,在变量值的最后面加上;%JAVA_HOME%\bin;%JAVA_HOME\jre\bin;。

JDK配置完毕,测试下,在命令行中输入“java -verison”,即可看到当前Java的版本信息。

安装并配置SDK 1.6

先解释下这里为什么要安装SDK1.6,而不是SDK2.2或者更高。据测试官方提供的SDK2.2的安装包缺少adb.exe文件,因此在eclipse中无法指定SDK的位置。所以只能先安装SDK 1.6,然后再升级到所需要的版本(后面步骤会有提到)。

解压SDK到D:\SDK\(任意目录皆可),配置环境变量:

1. 设置Android路径

如配置JAVA环境变量的步骤一样,新建一个系统变量,变量名为Android_home,变量值为SDK的路径,D:\SDK\

2. 设置PATH路径

编辑PATH变量,在值后面加上;%Android_home%\tools。

SDK配置完毕,在命令行中输入“Android -help”就能看到相关帮助信息。

解压Eclipse,安装ADT,关联SDK

解压Eclipse,双击eclipse.exe

安装ADT:在菜单栏,选择”help”-”install new software”,在打开的对话框中点击Add按钮,在名称处输入ADT,在地址中输入http://dl-ssl.google.com/android/eclipse/ ,执行install操作安装ADT插件

关联SDK:重启Eclipse,在菜单栏选择”Window”-”Preferences”,在对话框中点击Android,点击右侧的Browse按钮选择SDK的目录(D:\SDK\),点击”确定”。

通过SDK Setup更新SDK

把SDK Setup解压到SDK的根目录下(D:\SDK\),双击SDK setup.exe,启动Andriod SDK and AVD Manager,选中左侧setting,在右侧选择”Force https://xxx to be fetched using http://”,选择”save & apply”,选择所需要的更新内容,比如我这里选了3项:

  • Android SDK Tools, revision 5
  • SDK Platform Android 2.1, API 7 revision 1
  • Sapmles for SDK API 7, revision 1

若更新中有提示目录被占用,请尝试关闭杀毒软件再进行更新。更新完毕之后,Android开发环境就搭建好了。

字符集和编码方式

2011年03月30日

什么是字符集和字符编码

根据wiki对现代字符集的定义,字符集是一个字符序列,将一个字符集对应到一指定集合中某一东西(比如自然数序列)的过程称之为字符集编码(比如将拉丁字母编码成ASCII字符集),这样的一个字符集和对应的自然数序列叫做编码字符集。比如字母“A”对应的整数是65,“B”对应的整数为66。通常将字符集通俗的理解为字符和数字的对应表。

字符集的历史

为了更形象描述字符集,这里引用一部分资料上的历史:

起源及ASCII的诞生

很久以前,一群人用八个可以开合的晶体管来组成不同状态来表示万物,这样的一个字节(byte)就可以表示256种字符(2^8),他们把前32种状态叫做控制码,控制码有特殊的用途,比如打印机遇到0×10就输出换行等。这样,他们继续把大小写字母、数字和标点符号都用字节的各种状态来表示,一直排到了127位,这样计算机就可以用存储英文数据。当时计算机普及率很低,这样的方案看起来很不错,于是大家把这种方案叫做ANSI的ASCII(Aemerican Standard Code for Information Interchange)编码。

随后,世界上其他国家的人也开始使用计算机,他们发现ASCII里面没有想要的字符,于是把127位之后的空位来表示他们所需的新字符和符号,这样一直排到了255号,128-255之间的字符称为扩展字符集。

GB2312字符集

到中国人开始使用计算机时,已经没有位置来表示中文字符,于是亲们把127位以后的字符废除掉,并规定:127位之前和ASCII字符集一样,127位后,每两个字节表示一个汉字(前后两字节叫做
高字节和低字节),这样大部分简体汉字都可以表示了,另外还把字母、数字和标点符号都重新收编了一次,这就是所谓的“全角字符”。这种字符集叫做GB2312,它是对ASCII的中文扩展。(以
前常听程序员默念:一个汉字的长度等于2个英文字符的长度)

GBK和GB18030字符集的由来

随着计算机的普及,中国人发现还有好多繁体字没法表示呢!于是再次取消低字节大于127位的限制,只要是第一个字节大于127位就表示这是一个汉字的开始,这种方案叫做GBK字符集,它完整包含了GB2312字符集,还增加了很多繁体字和特殊符号。
再后来,少数民族也用电脑了,还得给照顾他们,于是在GBK的基础上又增加了很多少数民族的文字,这样GB18030字符集便诞生了。GB2312,GBK,GB18030通称DBCS(Double Byte Character Set双字节字符集)

想一统宇宙的Unicode

当时,很多国家都搞出一套自己的字符集方案,这就给信息交换带来了不少麻烦。于是ISO决定解决这个问题:废除所有地区性字符集,制定了一套囊括所有字符的字符集。即Universal Multiple-Octet Coded Character Set,简称UCS,俗称Unicode。

关于Unicode字符集

Unicode规定:统一使用双字节(16位)来表示一个字符,对于ASCII的字符,编码序号保持不变,只是由原来的8位扩展到16位(在存储海量数据时有浪费空间的诟病),其他的文字和符号全部重新编码。Unicode用UTF(Unicode Transformation Format)来实现,UTF-8即每次编码8个字节。

关于UTF-8

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,关于UTF-8编码方式,可以通过下面的表描述:

1
2
3
4
5
6
7
8
U+00000000 – U+0000007F:    0xxxxxxx
U+00000080 – U+000007FF:    110xxxxx 10xxxxxx
U+00000800 – U+0000FFFF:    1110xxxx 10xxxxxx 10xxxxxx
U+00010000 – U+001FFFFF:    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U+00200000 – U+03FFFFFF:    111110xx 10xxxxxx 10xxxxxx 10xxxxxx  10xxxxxx
U+04000000 – U+7FFFFFFF:    1111110x 10xxxxxx 10xxxxxx 10xxxxxx  10xxxxxx 10xxxxxx
 
//ps: Unicode在范围D800-DFFF中不存在任何字符

第一行的意思是:如果遇到0xxxxxxx(以0开头)的UTF8编码,则说明这是单字节表示的ASCII字符(0×00-0×7F)。

在一长串二进制中,有可能2-6个字节来表示一个字符,这样的话就需要额外的信息来描述多字节字符
的起始位置(starter),以及字节的长度(length)

接下来的几行表明:如果遇到10xxxxxx(以10开头)的字节,说明这是一个非ASCII字符中的一个字节,并且不是该字符的第一个字节编码。那么,除去以0和10开头的字节都是字符的首字节了。如果字节是110开头就
表示这是一个两字节字符,如果是1110,就表示这是一个三字节字符…以此类推,可以看出首字节的1的个数就表示这个字符占有的字节个数
(length)。

UTF-8编码示例

看明白这个表以后,举例说明下字符的UTF-8编码。以“零”这个汉字为例:

“零”的unicode码是38646,对应十六进制码是ox96f6。转换成二进制为1001011011110110。根据上面的理论,“零”(0×96f6)在U+0800-U+FFFF区间内,需要用三个字节编码,把这些二进制码拆
分放到“1110xxxx 10xxxxxx 10xxxxxx”各个x处(从低位往高位放,高位不足补0),组合得11101001 10011011 10110110,“零”就是以这样的二进制字节流存储和传输的。

把上面得到的三个二进制数转换成十六进制,可得:0xE9,0×9B,0xB6,然后我们在javascript中用encodeURI方法对“零”编码,得到%E9%9B%B6,很眼熟吧,就是前面的3个二进制数的十六进制表示。(encodeURI是一种percent encoding,ECMA262上有记载,但据说该编码没有通过w3标准)

1
2
3
4
5
6
7
    // 说明:零的unicode为38646, 38646 == ox96F6 == 1001011011110110
    var z = '零' ;
    console.log(parseInt('11101001', 2).toString(16)); //输出 e9
    console.log(parseInt('10011011', 2).toString(16)); //输出 9b
    console.log(parseInt('10110110', 2).toString(16)); //输出 b6
 
    console.log(encodeURI(z).replace(/%/gi, '  ')); //输出 e9 9b b6

HTML和Javascript中使用Unicode

HTML和Javascript都是支持Unicode字符集的,所以你可以在HTML中直接使用Unicode码来表示字符,符号实体就是这样的应用。比如我们用">"或者">"来表示">",前一种方式叫做符号实体,后一种方式叫做实体编号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    // 说明:零的unicode为38646, 38646 == ox96F6 == 1001011011110110
 
    // 以下HTML语言在浏览器中会输出两个“零”
    <strong>&#38646;</strong>
    <strong>&#x96f6;</strong>
 
    var z = '零' ;
    // 在javascript也可以直接是用unicode码来表示字符
    console.log('\u96f6') ;  //输出 零
    console.log(String.fromCharCode('38646')); //输出 零
 
    // 查看“零”的Unicode码和十六进制码
    console.log(z.charCodeAt(0)); //输出 38646
    console.log(z.charCodeAt(0).toString(16)); //输出 96f6
 
    // escape编码——percent encoding,返回百分比格式的十六进制
    console.log(escape(z)); //输出 %u96f6

PS: 感谢stauren

参考:
http://en.wikipedia.org/wiki/Charset
http://en.wikipedia.org/wiki/Character
http://en.wikipedia.org/wiki/Unicode
http://en.wikipedia.org/wiki/Utf-8
http://stauren.net/log/fpev3c89q.html

关于reflow和repaint

2011年03月19日

最近又重新查阅了一些关于reflow(回流)、repaint(重绘)的资料,整理成笔记:

1. 什么是reflow和repaint

“Repaint is what happens whenever something is made visible when it was not previously visible, or vice versa, without altering the layout of the document. ”
“Reflow is a more significant change. It is the name of the web browser process for re-calculating the positions and geometries of elements in the document”

Repaint发生在当某些元素由不可见变为可见,或由可见变为可见的情况下,前提是不改变文档的layout模型。
Reflow是一个更加明显的改变,它是浏览器重新计算文档元素的尺寸和位置的一个过程。

2. 什么情况下会发生reflow和repaint

a) Repaint

  • Adding an outline to a element //增加outline属性
  • Changing the background color //改变背景色
  • Changing the visibility style //改变visibility属性

b) Reflow

  • Resize the window //调整浏览器窗口大小
  • A script manipulating DOM tree //脚本操作DOM
  • Manipulating the className property of an element //操纵className属性
  • Style changed that affect the layout //修改影响layout的样式
  • Adding or removing a stylesheet //添加一处样式表
  • Calculating offsetWidth and offsetHeight //计算offsetWidth和offsetHeight
  • Contents changed,such as typing text in an input box //内容改变,比如在文本框内输入文本
  • Activation of CSS pseudo classes  //激活伪类

3. reflow和repaint带来什么影响

过多Reflow和Repaint会导致DOM渲染变慢,甚至破坏layout模型

Repaint requires the engine to search through all elements to determine what is visible, and what should be displayed.
The engine must reflow the relevant element to work out where the various parts of it should now be displayed. Its children will also be reflowed to take the new layout of their parent into account. Elements that appear after the element in the DOM will also be reflowed to calculate their new layout, as they may have been moved by the initial reflows. Ancestor elements will also reflow, to account for the changes in size of their children. Finally, everything is repainted.

对于Repaint,需要浏览器引擎搜索整个DOM节点,然后决定各部分该如何呈现。
对于Reflow,引擎需要reflow相关的元素来计算各部分的现实方式,该元素的子节点也要根据新的layout模型reflow,出现在该元素之后的元素也需要reflow来计算新的layout模型,因为他们可能被初始化reflow移除掉,并且该元素的祖先元素也要reflow来计算这些子级元素的改变,总之,所有的都被repaint了。

下图列举了各浏览器对于各种样式修改引发的reflow次数:
reflow time by various browser

4. 如何避免reflow

  • Reduce unnecessary DOM depth //减少不必要的DOM层级
  • Making several style changes at once //一次修改多个样式
  • Avoid tables for layout //避免使用table布局
  • Avoid css expression //避免使用cssExpression
  • Apply animations to elements that are position fixed or absolute //让动画元素绝对或者固定定位
  • Trading smoothness for speed //牺牲流畅度来换取速度
  • Avoid inspecting large numbers of nodes //避免大规模操作节点
  • Avoid modifications while traversing the DOM //避免边渲染DOM边改变DOM
  • Cache DOM values in script variables //缓存DOM信息

5. 实例

Bug描述:winxp的IE7/8浏览器中,搜索页面会在页面加载后异步载入部分DOM结构,此时后面的DOM内容位置偏离了原始位置(见红框部分DOM内容)。
bug-caused-by-reflow

分析:javascript脚本操作DOM时引起的reflow导致祖先节点reflow和同一个祖先节点下的临近节点的reflow。在reflow时,layout模型发生了变化,部分浏览器引擎重新计算DOM的位置发生了一些错误。

6. 参考文献

区分IE和非IE的最短判断

2011年02月27日

由于会议邀请者的系统时间出错,我被早到了一个小时到达会议室,闲着无聊,就顺便看看新闻,在JE里面看到一个“区分IE和非IE的最短判断”,帖子中的解释是:根据IE在对数组使用toString方法时报错来判断,代码大致如下:

1
2
3
4
5
if (+[1,]){
    alert('您正在使用非IE浏览器');
}else {
    alert('您正在使用IE浏览器');
}

Well,这里使用了一元加法运算符,对这个不了解到可以看看下面的代码(关于对数组使用一元加法运算符,我暂时没找到正规文档,只好以实例来说明来推测):

1
2
3
4
// 当数组只有1个元素时,返回这个数组元素
alert(+[1]);
// 当数组长度大于1时,返回NaN
alert(+[1,2]);

好吧,其实我想说“区分IE和非IE的最短判断”的是根据IE和标准浏览器对数组容错处理不一致的特性来实现的。

标准浏览器会忽悠数组中最后一个”,” (当作这是开发者不小心写上去的), 而IE则不会忽略它,而且用undefined来填充最后一个数组元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = [1,] ;
// 查看数组a的length属性 枚举数组
// 通过这两步可以测试出非IE是忽略掉数组中最后一个空元素的
// 而IE却用undefined来填充最后一个元素
alert([1,].length);
for (var i = 0, le = a.length ; i < le; i++ ) {
    alert(a[i]);
}
 
// 由上述得知 +[1,] 相当于 +[1, undefined] 
// 根据上面一元运算符的实例,你不难想到在IE下+[1,]会返回NaN了
alert(+[1,]);
alert(+[1,undefined]);

—– split —–

BTW:最近时间排得紧,走路都在想些事情,以至于生活方面的事情都有点昏昏的,买东西忘了拿找零,取钱忘记了拿。一心无二用,以后做什么事情都要专注,哪怕是取钱,也要盯着带着印钞机余温的RMB从ATM中徐徐吐出,然后收回卡,放好钱包再走人。

2010年的流水账

2011年02月11日

第一季度

  • 遭遇两次重感冒,两次都去医院输液才恢复,真郁闷啊!看来久宅必病啊,我得动起来,
  • 于是我便去同事组的足球队凑热闹了。快乐并痛着,短短几个月,摔伤两次,撞伤两次。
  • 两个项目都上线了,关注数据反馈,及时优化。

第二季度

  • 夏天临近,心情也逐渐躁动起来,在这个躁动的季节,躁动的我遭遇了很多事情.好的,不好的,扑面而来,我尽力冷静地分析思考再选择,然而在某些环节上,我依然离谱的错了。错的不能以常理推断我为何会做出那样的举动,仔细回想下,其实这种类似的举动,我高一就有过。冷汗!下不为例。
  • 团队小outting,我居然忘了地名,只记得那里的瀑布和那片适合踢球的草坪了
  • 在这个季度末,我辞职了

阅读这个条目剩下部分 »

jQuery源码阅读笔记(1)

2011年01月16日

“阅读jQuery源码”,在2010年尾时,我写下了这个plan。该是执行的时候了。

我选择的jQuery版本是1.4.4,在逐行阅读分析jQuery代码前,我首先快速阅读了jQuery的全部代码,大致了解了jQuery源码的结构:整个jQuery源码是一个自执行的匿名函数。给匿名函数有个传递一个window参数,这样做便于压缩源码内的window字符串。在源码中,通过自执行函数来将jQuery和$变量保留给全局作用域供用户使用(#898)。

在接下来的时间,我将jQuery源码分成几大块进行逐行阅读分析。本文记录了第一部分的一些笔记。

构造jQuery对象(#20-#898)

jQuery对象并不是new jQuery()生成的,而是实例化构造函数jQuery.fn.init()生成的,看看源码中这几个关系:

1
2
3
4
5
6
7
8
jQuery.prototype = jQuery.fn #99
//  jQuery的fn属性和其原型是指向同一个对象
 
jQuery.fn.init.prototype = jQuery.fn  #327
// 把jQuery的原型挂在jQuery.fn.init的原型链上,以便于外部的jQuery对象能访问jQuery原型链上的所有方法
 
jQuery.extend = jQuery.fn.extend #329
// 他们指向同一个扩展方法

这个部分伊始定义了很多正则,比如判断查询器字符类型的,判断JSON数据相关的,判断浏览器userAgent等待。还有定义一些Object方法的别名。

jQuery的原型函数

在#99开始定义jQuery的原型,jQuery大部分功能都是通过其的静态方法来实现的,原型中的方法只是暴露给外部的API接口,其中:

  • init方法根据传递的selector参数查询出对应的对象并返回;
  • get方法会根据传递参数返回指定的对象元素;
  • pushStack方法将传递的对象压入jQuery对象中;
  • each 你懂的;
  • ready 判断DOM是否加载完毕;
  • eq 根据参数获取指定位置的数组元素;

阅读这个条目剩下部分 »

jQuery 动画组件(Animate)浅析

2010年12月26日

之前自己在做js动画组件时遇到了JS时钟精度问题,遂去参考下jQuery的处理方式,顺便把jQuery的动画组件部分简要分析了一遍。

jQuery组件都是由一个API接口函数暴露给用户的,组件的核心功能由有底层函数去完成。JQuery动画组件的接口函数就是animate。在了解animate之前,先了解到jQuery中动画相关的几个属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 用来设置定时器的变量
var timerId ;
 
jQuery.extend({
    // 修正一些参数,比如在回调函数中加入队列控制,并把这些修正后的参数放置一个对象里面返回
    speed: function( speed, easing, fn ) {},
 
    // 缓冲函数,决定动画运行方式
    easing: {},
 
    // 用来存储 执行动画实例单步的方法 的数组(有点拗口)
    timers: [],
 
    // 动画构造函数
    fx: function( elem, options, prop ) {}
 
});

结合我在源码中加的一些注释,简要描述jQuery的动画过程:
animate方法,首先调用speed方法去修正参数,然后用枚举或者队列的方式去执行多个动画。接下来,遍历动画中要修改的属性,修正属性值,并将每个属性生成一个动画实例。调用实例custom方法将属性从开始值过渡到结束值。

custom方法,把动画的单步操作(step方法)压入到前面提到的timers数组中,并调用tick遍历执行所有动画。

step方法——动画的单步操作,计算动画的逝去时间,并将逝去时间与预定动画时长的比值作为动画的变化比值,将比比值结合动画缓冲函数,计算出动画变化值。如果动画逝去时间超过预定动画时长,则将属性更新到最后一帧,并调用预定的回调函数。返回false,表示该动画实例已完成。

tick方法——定时遍历执行所有动画实例的step方法。如果step方法返回为false(该动画实例已完成),则将包含执行step方法的函数从timers数组中移除,如果timers数组为空(全部动画实例都运行完毕),执行stop方法。

stop方法——终止动画,停止定时器,并清空定时器变量timerId

看完jQuery源码,自己也改造了一个。满足最基本的功能呢 查看Demo

下面是JQuery动画组件的大部分源码(我加了一些注释):
阅读这个条目剩下部分 »

Editplus一键同步到FTP

2010年12月11日

在Dreamweaver中,可以将正在编辑的文件一键同步到FTP服务器中,很是便利。如果Editplus也能快捷同步就好了,想到在Editplus可以调用外部程序或者命令,于是用php写了个同步到FTP的脚本文件,并作为工具添加到Editplus中。

原理很简单:首先定义FTP的相关参数,比如主机名,用户名,密码等;再指定FTP的路径和本地环境的路径,以便于将本地环境中的文件上传到FTP上对应路径,然后通过php的相关函数连接FTP服务器,并上传文件。

脚本配置很简单(脚本地址在文章底部,当然你可以去googleCode上获取):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< ?php
// 定义FTP参数
$ftp_host = '192.168.0.1';
$ftp_user = 'username';
$ftp_pass = 'password';
$ftp_port = 21;
$pasv_mode = true;
 
// 定义开发环境路径
$remote_root_dir = '/domains/xxx.com/public_html/blog' ;
 
// 定义本地上传路径(此路径等价于开发环境路径)
$local_root_path = 'D:/www/blog' ;
 
...

阅读这个条目剩下部分 »

IE下setTimeout 的bug

2010年11月6日

用Js封装了一个常用的动画组件 (googleCode) ,发现动画完成所需的时间在IE和在其他浏览器下有很大的差别。

开始以为是组件中调用的函数过于复杂,导致IE计算太耗时,拖延了整个动画的完成时间。于是选择了最简单的函数来实现动画,但问题依旧存在。排除了函数的复杂性,那就只可能是setTimeout的问题了。

setTimeout(code, millisec); 在指定的毫秒数后调用函数或者表达式。(我在后面将称“指定的毫秒数”为调用间隔)

疑问:IE是否在我指定的毫秒数之后执行了函数呢?

把代码精简到最少,继续测试,下面的的一段代码用来连续10次调用run函数(调用间隔是10ms),执行完后弹出的结果是调用10次函数耗费的总毫秒数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">
//< ![CDATA[
var animAlex = function (d) {
    var t = 0 ;
    var run = function () {
        if (t < d){
            t++;
            //尝试修改这里的参数 从0到15 都会按15计算
            setTimeout(run, 10);
        }else {
            alert(+ new Date() - s );
        }
    } ;
    run();
} ;
var s = + new Date() ;
animAlex(10);
//]]>
</script>

点击查看demo

忽略函数执行时间(这里,函数的执行时间确实可忽略),调用10次函数所需时间的理论值等于调用间隔和执行次数的乘积,这里调用间隔是10ms , 执行了10次,则总需时间 10×10 = 100ms ,当然浏览器不可能完全精准。但误差也应该保证在正负10ms以内。

面对现实,执行结果是:
阅读这个条目剩下部分 »