Author Archive for admin

blog迁移成功

由于子域名没备案,原空间被服务商残忍的禁用了……

倒腾了一天,终于在ISS上装了PHP+Mysql+URL Rewriting,并成功导入原有blog数据,真不容易~

期间碰到了很多麻烦的问题:
1.原先把PHP目录放到C盘,死活加载不成功php5isapi.dll,查了N多资料,改了N多次权限,重启了好多次,还是不行……最后尝试了一下把PHP目录移到D盘,就OK了~

2.Mysql的乱码问题,原先的服务商的数据库编码是gb2312的,装完Mysql,改了编码设置,尝试了好几次将原先的sql数据导入到新的数据库中,可能是编码的问题,始终不行……最后想起了Wordpress自带的功能导出的xml备份,成功避开了Mysql编码问题~

3.设置URL Rewriting,这个要容易些,查看了一些资料,将isapi_rwl_x86_0073.msi装到服务器上,添加到ISAPI中,然后将网上找的httpd.ini覆盖上去,最后根据自己的URL Rewriting需求改了一下httpd.ini中的正则匹配规则。

腾讯北京 招Web前端开发

要求:
1.精通HTML、CSS、JS,有用户体验意识,对页面加速技术有了解;
2.懂AS者优先,懂PHP、CGI者优先,懂socket编程者优先,有海量服务开发经验者优先;
3.本科学历;

 有意向的同学请发简历及作品至xhlv#tencent.com (发邮件时请将#换成@)

“千分位”格式化数据的正则

把12345678此类格式的数据换成 12,345,678 格式?

据说是腾讯面试的一道题,还是蛮有意思的。
可以选择用循环来进行处理,但效率显然没有正则来得高。

"12345678".replace(/(?=(?:\w{3})+$)/g,",") //这是网上找的一个正则,有点缺陷,在后面再修正~

这个正则是怎么进行工作的?

研究了一下,它是非常巧妙的利用?=和?:来完成匹配。
?=和?:的功能可以看下面的例子,就应该明白他们的作用了:
"IE 6,IE 7,IE 8".match(/IE (?:7|8)/gi); //["IE 7", "IE 8"]
"IE 6,IE 7,IE 8".match(/IE (?=7|8)/gi); //["IE ", "IE "]
"IE 6,IE 7,IE 8".match(/IE (?!7|8)/gi); //["IE "],这个其实相当于匹配:"IE 6,IE 7,IE 8".match(/IE (?=6)/gi);

这个正则,可以分成两部分:(?=) 和 (?:\w{3})+$
首先,(?:\w{3})+$,从最后开始匹配3的整数倍个数字;
然后,(?=),预搜索符合上述条件的匹配:678、345678所在左侧缝隙的空字符串("12缝隙345缝隙678"),["",""];
最后,将匹配到的空字符串替换成","。

实际上,/(?=(?:\w{3})+$)/g 和 /(?=((?:\w{3})+$))/g 效果是一样的。

这个正则有什么缺陷?
有,比如"123456789"会被替换成",123,456,789",多出来一个逗号。

可以这样来完善这个正则:
"123456789".replace(/(?=(?!\b)(?:\w{3})+$)/g,",")

加一个(?!\b),让(?:\w{3})+$的匹配前面不是边界,就不会包含"123456789"了。

Maxthon,TencentTraveler绑架鼠标右键

正常情况下,当用户右键按下时会触发mousedown事件,然后右键弹起时触发mouseup事件。

而在Maxthon,TencentTraveler中,为了达到鼠标动作的功能,强行把鼠标右键给截获了,也就是说:
当右键按下时并不会立刻触发mousedown事件;
当右键弹起时,先后触发mousedown和mouseup;
在右键弹起之前,如果鼠标移动,那么就会被视为“鼠标动作”的功能,mousedown和mouseup都不会触发。

当然,在这两种浏览器中,右键按下时contextmenu事件也是被截获了。

当无法避开这个问题时,可以通过判别浏览器,然后通过event.button的值来进行区分:
在这两种浏览器中,右键弹起触发mousedown时,event.button为0(其他浏览器都为2)

JS判断是不是Maxthon浏览器

Maxthon 和 IE 的navigator.userAgent居然是一样的….

所以只能另外想办法了,找了一下,原来Maxthon的版本信息是放在window['external']['max_version']中的,那么就可以这样来判断了:
isMaxthon = !!(window['external'] && window['external']['max_version']);

Editplus 调用 TortoiseSVN

不断的在Editplus和文件夹之间切换,挺麻烦的,网上找了个Editplus调用svn的方法,还是挺好用的~

可以把常用的几个命令绑定到Ctrl + 1~4

edtiplus 工具-用户工具-添加工具-程序
菜单文本:SVN Commit
命令: C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe
参数: /command:commit /path:"$(FilePath)" /notempfile /closeonend:0
初始目录: $(FileDir)
Check: "Capture output", "Save open files"

其他方法:只需要把上面的"参数"里的:/command:commit 用下面的替换(例如:/command:about)
:about 显示关于对话框
:log 打开日志对话框
:checkout 打开检出对话框
:import 打开导入对话框
:update 将工作副本的/path更新到HEAD,如果给定参数/rev,就会弹出一个对话框询问用户需要更新到哪个修订版本。为了避免指定修订版本号/rev:1234的对话框,需要加上/nonrecursive和/ignoreexternals参数(这2个参数我没加,还没遇到上述问题)
:commit 打开提交对话框
:add 将/path的文件添加到版本控制
:revert 撤消一个文件自上次更新后的所有的变更
:cleanup 递归清理工作拷贝,删除未完成的工作拷贝锁定
:resolve 将/path指定文件的冲突标示为解决,如果加上/noquestion,将不会提示确认操作。
:repocreate 在/path创建一个版本库
:switch 切换至分枝/标记
:export 将/path的工作副本导出到另一个目录
:merge 打开合并对话框
:mergeall 打开合并所有对话框
:copy 复制工作副本至URL
:settings 打开设置对话框
:remove 从版本控制里移除/path中的文件
:rename 重命名/path的文件
:diff 启动TortoiseSVN设置的外置比较程序
:help 打开帮助文件
:relocate 打开重定位对话框
:help 打开帮助文件
:repobrowser 打开版本库浏览器对话框
:ignore 将/path中的对象加入到忽略列表,仅对文件夹有效。
:blame 打开文件的追溯对话框
:createpatch 创建/path下的补丁文件。
:revisiongraph 显示/path目录下的版本变化图。
:lock 锁定一个文件,可以输入锁定的原因。
:rebuildiconcache 重建windows的图标缓存,当系统图标缓存出了问题才需要这样做(会导致桌面的图标会重新排列)
:properties 显示 /path 给出的路径之属性对话框。

cssText在IE中的小bug

Element.style.cssText

当需要批量赋予Element样式时,cssText是比较好的方式,可以减少reflow,如:

但是,这样会有一个问题,会把原有的cssText清掉,比如原来的style中有’display:none;’,那么执行完上面的JS后,display就被删掉了。
为了解决这个问题,可以采用cssText累加的方法:

但是,cssText(假如不为空)在IE中最后一个分号会被删掉,比较BT….
因此,上面cssText累加的方法在IE中是无效的。

最后,可以在前面添加一个分号来解决这个问题:

evalScripts的实现

在XHR一个页面的时候,有时可能需要执行页面中的脚本,这就是evalScripts了。

在Prototype中,有一个evalScripts的方法来实现这个功能。

这里就借鉴了它的方法,来实现evalScripts功能:

等于比较符“==”解析过程

alert([] == false); //弹出的是true

一个空数组应该是true才对,如:if([]) alert(’[] is true’);
那为什么空数组会等于false呢?

既然空数组等于false,那为什么空对象不等于false呢?如:
var b = {};
alert(b == false); //弹出的是false

非常的好奇,查阅了官方资料,原来“==”的解析过程是这样的:

The Abstract Equality Comparison Algorithm
The comparison x == y,where x and y are values, produces true or false. Such a comparison is
performed as follows:
1. If Type(x) is different from Type(y), go to step 14.
2. If Type(x) is Undefined, return true.
3. If Type(x) is Null, return true.
4. If Type(x) is not Number, go to step 11.
5. If x is NaN,return false.
6. If y is NaN,return false.
7. If x is the same number value as y,return true.
8. If x is +0 and y is −0,return true.
9. If x is −0 and y is +0,return true.
10. Return false.
11.If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same
length and same characters in corresponding positions). Otherwise, return false.
12. If Type(x) is Boolean, return true if x and y are both true or both false.Otherwise,return false.
13.Return true if x and y refer to the same object or if they refer to objects joined to each other (see
13.1.2). Otherwise, return false.
14. If x is null and y is undefined,return true.
15. If x is undefined and y is null,return true.
16.If Type(x) is Number and Type(y) is String,
return the result of the comparison x == ToNumber(y).
17.If Type(x) is String and Type(y) is Number,
return the result of the comparison ToNumber(x)== y.
18. If Type(x) is Boolean, return the result of the comparison ToNumber(x)== y.
19. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
20.If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
21.If Type(x) is Object and Type(y) is either String or Number,
return the result of the comparison ToPrimitive(x)== y.
22. Return false.

那么,对一个空数组和空对象,直接跳到了14步。

然后在19步时,把false转成number,即0。

然后在21步时,将空数组和空对象转换成原始数据类型,与0进行比较;这是最关键的一步,空数组和空对象,转换成数值类型分别是0和NaN,转换成字符串分别是”和’[object Object]‘,官方没说到底转成了哪种原始数据类型,但已经可以看到他们的区别了,0和”等于false,NaN或’[object Object]‘不等于false。

因此空数组等于false,而空对象不等于false。

计算某天是第几周

需求是:选中日历中的某一天,返回该天是在第几周。

原以为,将某天在一年中的总天数除以7,进行上舍入就可以,可惜没这么简单。

假设该年的第一天是周一,那么上面的算法是对的。但每年并不是都从星期一开始的,所以需要计算一下从星期几开始的。

具体算法如下:
1.计算出该天在一年中是第几天,记为Days;
2.计算该年第一天是星期几,记为FirstDay;
3.计算第几周:
如果FirstDay是1,就比较好计算了,将Days/7进行向上舍入即可;
如果FirstDay不是1,那么就需要这样计算,将(Days - (7 -FirstDay + 1))/7进行向上舍入,然后加1;

下面是获取今天是一年中第几周的JS代码: