iQuery实现CSS3 transition动画接口

2010年8月24日 21:48 查看评论(0) 分类:技术文章 Tags:

给iquery加了跟jquery差不多的动画接口animate,不过实现上是通过CSS3的transition。

效果点这里 (桌面浏览器只支持webkit内核,如chrome/safari)

iQuery源码

(全文…)

简化代码学习jquery动画源码

2010年8月18日 22:45 查看评论(3) 分类:技术文章 Tags:

效果见这里:http://bangswork.googlecode.com/svn/trunk/lab/effect/index.html

jquery的动画总体思路是:

有一个fx类专门处理动画,fx的各个实例共享一个timers数组和一个setInterval。对每个传进来的dom的每个属性值都新建一个fx实例去处理,一个fx实例对应一个dom的一个属性的变化。fx里有个step函数,可以计算出当前这个时刻这个属性要达到什么值。

这个step会通过共用的一个setInterval每13毫秒执行一次,这就可以使得它行成动画。另外如果浏览器速度太慢无法达到13毫秒执行一次step,动画也会按时完成,因为是根据当前系统时间计算属性要达到的值的。

每一个fx实例的step都会放进timers数组,实际上setInterval是持续执行timers里的每一个函数,这样只用一个setInterval就让众多属性“一起动”了。step里判断到超过了动画运行的时间,就会返回false让它从timers里移除,timers为空时clearInterval。

下面简单实现这整个过程:
(全文…)

javascript关于数组的几个常用伎俩

2010年8月16日 22:35 查看评论(0) 分类:技术文章 Tags:

1.把对象变成类数组

var a = { name : "jquery" },
b = ["elem1", "elem2", "elem3"];
Array.prototype.push.apply(a, b);
alert(a)	//[Object object]

//可以像遍历数组一样遍历这个对象
for ( var i = 0; i < a.length; i ++ ) {
	alert(a[i])
}

jquery就是用这种方法把jquery对象变成类数组的,效率还很高。

2.去掉一层嵌套数组

var a = [[1,2], 3, [4,5,6]];
var b = Array.prototype.concat.apply([], a);
console.info(b) 	//1,2,3,4,5,6

concat方法:

arrayObject.concat(arrayX,arrayX,……,arrayX)
concat() 方法用于连接两个或多个数组。arrayX为n个数组or元素参数
console.info([1].concat([2,3], 4)) //1,2,3,4

apply方法:

fn.apply(obj, args)
在obj的作用域下调用函数fn,并把数组args里的第i个元素作为第i个参数传给fn
例如
fn.apply(window, [1,2,3]) 等于 fn(1,2,3) (直接调用一个函数作用域就是window)

合起来就有上面那个效果了。

3.复制数组

利用Array.splice(0)可以快速复制一个数组

var a = [1,2,3],
b = a.splice(0);
alert(b)//1,2,3
alert(a==b)//false

4.高效合并字符串

var a = ["<div>","<span>","</span>","</div>"];
alert(a.join(”")) //”<div><span></span></div>”

通过这种方式合并字符串效率比 + 号高了近七八倍,因为js的机制导致每次给字符串追加内容都是抛弃原有字符串新建另一个追加后的字符串,所以效率会低。

在firefox下测试:

var a = []
for (var i = 0; i &lt; 100000; i++) {
	a.push("&lt;div&gt;");
}
console.time("arr");
a.join("");
console.timeEnd("arr");console.time("str");

var b = "";
for (var i = 0; i &lt; 100000; i++) {
	b += "&lt;div&gt;";
}
console.timeEnd("str");
//arr:19ms
//str:141ms

通过PHP curl向腾讯微博发送广播全过程

2010年8月15日 15:04 查看评论(22) 分类:技术文章 Tags:

效果见这里:http://webbang.net/lab/txwb/

由于朋友分布在不同的微博,我希望有个同步到twitter、新浪微博、腾讯微博的工具,但等这么久都没出现这样的工具,微博通似乎停工了,也不支持twitter和腾讯微博,于是想自己做个。

新浪微博和twitter都开放API,要实现同步发送很简单,腾讯微博未开放,就需要hack一下了。这次把研究过程都记录下来了,写得很长~实际上在curl实现那部分我花的时间比较多,走的弯路也多,但由于篇幅原因那部分都简省了~

(全文…)

ThinkPHP数据自动验证中unique的缺陷

2010年6月23日 21:34 查看评论(1) 分类:技术文章 Tags:

ThinkPHP可以为Model添加$_validate属性,使得在使用create方法创建数据对象时能自动对数据进行验证,详细看这里

这其中有个unique的方法,即是验证指定栏的数据在表中是否唯一。向数据表里插入“唯一”字段时可以自动判断并且提示错误,但ThinkPHP这个功能有个缺陷,导致这个unique验证基本上只能在添加数据的时候使用,不能在编辑数据的时候用。

unique验证的源码在ThinkPHP/Lib/Think/Core/model.class.php第944行,对unique验证时就是查找整个数据表这一栏这个值是否存在,这样做在添加数据时没问题,但如果在编辑状态下就有问题了。例如编辑一个用户名和密码,现在不修改用户名只修改密码,因为用户名要进行唯一验证,此时这个用户名没有修改,数据表上是有这个用户名的(就是在编辑的这行数据),于是就提示已存在此数据,无法保存。

我想解决的办法可以是:在验证的时候判断是否传进了此表主键的值,例如判断是否传进了$_POST["admin_id"],如果传进了,对搜索到的数据提取admin_id判断是否相等,相等则不存在unique错误,不相等才出现错误。在这么核心的地方调用$_POST似乎破坏结构,那可以改改$_validate传递的参数。还不熟悉ThinkPHP,就不动手改了。

目前在我的应用中是只在新增数据时检测unique,编辑时不检测,如果编辑时unique的栏有重复了,再在save()时判断是否插入成功和提示,暂时是这样。

JS模仿AS3事件机制

2010年4月18日 15:01 查看评论(3) 分类:技术文章 Tags:

练习下自定义事件的实现,想让JS可以用AS3的语法使用自定义事件,实现很简单,因为没考虑复杂的情况吧。试过后发现有些地方还是模仿不了,最主要不一样的地方是:

1.侦听函数没法自动绑定那个函数所在的object,必须手动把object传进去,像这样:dispatcher.addEventListener(SampleDispatcher.ACTION, e.action, e);
最后还要传“e”这个obj进去,否则函数action里的this不指向e

2.使用的时候继承十分麻烦,还得小心翼翼,看demo就知道了。

(全文…)

YUI3的沙箱机制

2010年4月10日 16:51 查看评论(1) 分类:技术文章 Tags:

YUI2

在YUI2.x里,每一个模块功能的引入都会直接添加在全局的YAHOO里,例如dom.js里:

var Y = YAHOO.util;
Y.Dom = {...}

这样在整个页面范围内,YAHOO.util里就多了一个功能Dom。

YUI3-add()

在YUI3里,每一个模块引入时并没有把功能直接添加到全局的YUI里,看看YUI3里的dom.js:

YUI.add('dom-base', function(Y) {
    //在这里添加dom方法
    Y.DOM = {
        ...
    }
...
}, '3.0.0' );

再看看yui.js里add的源码:

add: function(name, fn, version, details) {

    YUI.Env.mods[name] = {
        name: name,
        fn: fn,
        version: version,
        details: details || {}
    };

    return this; // chain support
}

所以YUI3里引入每个模块时只是把这个模块的内容储存在YUI.Evn.mods里。

YUI3-use()

需要使用某个模块时,在创建YUI实例以后,用use取出来执行模块里的程序,为这个YUI实例添加相应的方法:

YUI().use('dom-base', function(Y) {
    //这里可以用到模块dom-base里对YUI添加的方法Y.DOM
    alert(Y.DOM) //[object object]
})

而在同一个页面里,YUI实例里如果没有指明use(’dom-base’),就没有Y.DOM这个方法

YUI().use('', function(Y) {
    alert(Y.DOM) //undefined
})

沙箱

这里YUI().use(”,function(Y){…})就是一个安全沙箱,可以确保这里面的Y是纯天然无污染的,Y实例里有什么功能完全取决于use里传进的模块名称,function(Y){}里面的程序跟外界是隔离的,在里面创建的变量(除了全局变量)以及对YUI的添加修改都不会影响到同个页面上其他人写的程序。

但是这个纯天然无污染是有点代价的,就是每次都要新建一个YUI实例,消耗内存,但如果不怕Y被污染,可以不每次都创建实例:

var Y = YUI();
Y.use('dom-base', function(Y) {
    //可以同时使用dom-base和oop模块里添加的方法
});
Y.use('oop', function(Y) {
    //可以同时使用dom-base和oop模块里添加的方法
});

add()和use()配合一些参数(例如require)和YUI Loader就成了YUI3模块化编程的基础。

最简化的YUI沙箱

去除了YUI Loader以及require等参数,参考自这里
(全文…)

web workers各浏览器下参数传递的差异

2010年4月5日 23:53 查看评论(0) 分类:技术文章 Tags:

做军旗游戏时想用web workers消除计算时界面的停滞,实现了后发现在firefox下正常,但在chrome/safari下却不能用,网上关于web workers的资料太少了,也可能是因为我没找到,结果就一直debug了半天,才找出原因所在,原因就是:chrome/safari下,web worker传递的参数全都会被转换成字符串。

chrome/safari下,只能用字符串通信,无法传递其他数据,无论是数组,object,布尔值,数值,全都会被转成字符串,而在firefox下则支持所有数据类型的传递。

看这段示例代码,以下测试在firefox3.5 safari4.0.5 chrome4.1下进行:

HTML:

<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML4.0 Transitional//EN">
<html>
<head>
	<title>Test threads fibonacci</title>
</head>
<body>
    <script type="text/javascript">
		var worker = new Worker("testWorker.js");
		worker.onmessage = function (event) {
			alert("type:" + typeof event.data);
			alert(event.data[1]);
		};
		worker.postMessage([2,3]);
    </script>
</body>
</html>

testWorker.js:

onmessage = function (event) {
    postMessage(event.data.name);
};

safari/chrome显示:type:string “,”(字符串”2,3″第二个字符)
firefox显示:type:object 3(数组第二个元素)

可以把worker.postMessage([2,3]);的参数改成其他类型试试,safari/chrome显示出来的type都是string。

写出来好简单,发现这个却花了我挺多时间,firefox对google创造出来的东西的支持比chrome还好,真是奇怪~
(全文…)

搭建maven & cometd过程

2010年3月27日 15:23 查看评论(7) 分类:技术文章 Tags:

近来想做个web game,需要双方持久链接,查了下资料,HTML5的websocket太遥远了得N年后才能流行,用FLASH模拟的socket又限制了没有FLASH插件的浏览器无法玩,最后研究了下comet,发现用这个实现应该靠谱,貌似WEBQQ,gmail里的gtalk,校内的站内提示和聊天都是用comet类似技术。后来找到cometd和pushlet,据说cometd更好,于是就开始捣鼓配置cometd。

配置环境这事儿,要是有有经验的人指点就好了,可以省去90%的时间,可惜没有~只能胡乱摸索。在完全不晓得maven是什么的情况下,配置这个cometd真是折腾死我了,先随便乱整费了很多时间,无果,再在eclipse下载maven插件,捣鼓半天运行不了,最后老老实实地用命令行的方式配置maven,也费了不少时间,但终于运行成功了。记下这个配置的过程,可能以后重装电脑要重新配置时有用。

目前在eclipse还是弄不好maven,运行项目时下载不到所需要的插件无法运行,我纳闷怎么在命令行就可以,在eclipse就不行,maven下载位置都是指向同一个,运行的也是同一个项目,但还是折腾不好。

配置maven

1.到http://maven.apache.org/下载maven,解压到任意一位置,以下假定maven解压地址为C:\Program Files\maven

2.配置环境变量,在变量path的值后面加上C:\Program Files\maven\bin

3.确保jdk环境配置无误:

a.检查变量path的值里有无jdk地址,例如c:\Program Files\Java\jdk1.6.0_10\bin;
b.检查变量有无变量JAVA_HOME,没有则加上,值为JDK地址

4.打开命令提示符(开始-运行-cmd),输入mvn -version检查mvn是否成功配置。

5.打开C:\Program Files\maven\conf\settings.xml,找到<pluginGroups></pluginGroups>,在里面加入<pluginGroup>org.mortbay.jetty</pluginGroup> 如果不加入这句,maven会无法找到和下载jetty,待会运行cometd时会出现这样的错误:

org.apache.maven.plugins:maven-jetty-plugin does not exist or no valid version could be found

6.maven自动下载插件等东西时默认保存在 我的文档/.m2/ 下,如果要改变这个位置,例如保存到maven目录下的down文件夹,可以在setting.xml里面加入<localRepository>/down</localRepository>。注意,目录名字不能有空格,例如c:\program files这个地址是不合法的。
(全文…)

JavaScript里关于this的疑惑

2010年3月12日 10:00 查看评论(0) 分类:技术文章

几天前自己捣鼓东西,碰到一个问题:能不能通过一个函数得到此函数所在的对象?例如:

var obj = function() {
    this.fn = function(){
        alert(this);
    }
}

function get(fn) {
    fn();
}

var myObj = new obj();
get(myObj.fn)

目的是让myObj里的函数fn的this始终指向myObj
上面这样把myObj.fn传入到get并在里面运行,结果myObj.fn的this就改变了指向window
可以通过传入myObj再用call达到目的,想问的是,能否不传myObj就能达到目的

function get(fn, obj) {
    fn.call(obj);
}
get(myObj.fn, myObj)

经过各方指点,知道:
(全文…)