Yahoo! 360° News | Beta Feedback
Start your own Yahoo! 360° page

我感觉我还不太了解电影 - 引自黑泽明(Akira Kurosawa)--> Click here

1 - 5 of 192 First | < Prev | Next > | Last

Kejun's Blog Full Post View | List View

neat ideas!

Blog迁移
由于360要关闭,Blog现已迁到 http://hikejun.com/blog
Monday June 8, 2009 - 08:58am (PDT) Permanent Link | 0 Comments
YUI 3.x 中的Loader组件
在YUI3的种子文件中集成了Loader。YUI3的模块调用都是通过它实现的,如: YUI().use('node', 'base', func)。其实也可以单独使用它。

loader的配置信息:
var loader_config = {
//指定加载完成后执行的回调方法
onSuccess: function(){},

//指定当加载失败时执行的回调方法
onFailure: function(){},

//指定当每个文件加载完时执行的回调方法
onProgress: function(){},

//指定当一个文件加载超时时执行的回调方法
onTimeout: function(){},

//所有回调方法执行的上下文对象。默认为YUI实例对象
context: Y,

//该值将被传到所有回调方法中
data: null,

//元素ID或HTML元素。在指定的HTML元素前插入新的文件
insertBefore: '',

//加载文件指定的编码。默认为UTF-8
charset: 'UTF-8',

//加载组件的基本目录。默认是Y.Env.meta.base(值为http://yui.yahooapis.com/[YUI版本号]/build/)
base: '',

//combo handler的地址。默认是Y.Env.meta.comboBase(值为http://yui.yahooapis.com/combo?)
comboBase: '',

//表示是否使用combo handler加载JS文件
combine: true,

//忽略加载注册在YUI全局上的模块。根据Y.Env.mods判断
ignoreRegistered

//模块路径的根目录。默认为Y.Env.meta.root
root: '',

//超时。默认0。如果指定,该值将用于Get组件,超时后触发超时事件
timeout: 0,

//强制加载的模块列表(array)
force: ['base'],
//忽略加载的模块,指定的模块如果出现在依赖树中将不会被加载
ignore: ['io'],

//默认为true。加载的rollup模块的子模块数量超过3个,则加载rollup模块
allowRollup: true

//过虑所加载模块的路径。调试时用到。
filter: {
searchExp: '-min\.js',
replaceStr: '-debug.js'
},

//要加载的模块
required: {
node: true,
io: true
},

//模块信息。默认在Y.Env.meta.modules下
//可以将自定义的module信息merge在一起,modules = Y.merge(Y.Env.meta.modules, myModuleInfo)
moduleInfo: modules,

//皮肤信息。默认在Y.Env.meta.skin
skin: {},

//rollup模块列表(object)。默认从Y.Env.meta.modules中提取
rollups: {},

//加载依赖的可选模板。默认false
loadOptional: false,


//当insert()或calculate()执行时,产生的加载模板的数组
sorted: [],

//已加载过的模块。
loaded: {},

//指示当insert被调用时,依懒树需要重新计算。默认为true
dirty: ture,

//当前所有插入的模块
inserted: {}

};

var loader = new myLib.Loader(loader_config);

属性很多,其实常用的就是那么几个,对比一下YUI 2的:
YUI 2:
var loader = new YAHOO.util.YUILoader({
base: '/yui/build/',
require: ['tabview', 'colorpicker'],
loadOptional: true,
timeout: 10000,
combine: true,
onSuccess: function(){}
});
loader.insert();

YUI 3:
var loader = new Y.Loader({
base: '/yui/build/',
required: {
node: true,
io: true
},
loadOptional: true,
timeout: 10000,
combine: true,
onSuccess: function(){}
});
loader.insert();

差别不大,主要是指定加载模块列表的方式上(加粗部分)。其它不同之处是上下文对象的属性名,YUI3中叫context,YUI2中叫scope,另外,YUI3中放弃了varName这个属性。

自定义模块的配置属性:
var submod1 = {
//必选项, 模块名
name: 'submod_name',
//类型,默认为‘js’。可以设为'js'或'css'
type: 'js',

//必选项,文件相对路径(相对base定义的根路径)
path: ‘filedir/file.js’,

//可选。依懒的模块列表(array)
requires: ['node', 'animation'],

//可选。相关的模块列表(array)
optional: ['io', 'dd'],
//将替代的模块列表(array)。如果自定义模块是rollup模块,这里指定它将替代的模块
supersedes: [],
//在指定的模块列表后面参加(array)。
after: [],
//可替代的模块数超过设定,则自动用rollup模块替代
rollup: 3,

//文件全路径,定义此项将代替path的设置
fullpath: '',
//可选。是否调入皮肤文件
skinnable: true,
//可选。包含的子模块列表(object)
submodules: {
‘sub-submod1’: {
requires: ['node', 'base']
}
}
};

对比YUI 2自定义模块的配置属性,YUI 3主要增加对rollup模块的定义(即由一组子模块组成的模块)。当allowRollup为true时,同时请求的子模块的数量大于rollup设定的数量,就加载rollup模块。

添加自定义模块:
loader.addModule(submod1);

添加到加载模块列表中:
loader.require(['submod_name']);

执行加载:
loader.insert();

通过这种方式加载外部资源文件,最大好外是性能提高了(相关介绍:http://bit.ly/HDN4u),同时管理起来很方便。

Tags: yui3
Sunday May 31, 2009 - 08:15pm (PDT) Permanent Link | 0 Comments
Google的9条创新原则
(via http://twitter.com/zhaozexin/status/1854808422
  • Innovation, not instant perfection/创新不会马上就完美
    Start rough, learn and iterate./开始粗糙,学习和迭代
  • Ideas come from everywhere/点子来自任何地方
    Ideas can come from the engineers, managers, users even the financial team.
  • Share everything you can/分享一切
    Everything is put on the intranet, so employees know what is happening./任何事情都可以在内网分享
  • You’re brilliant, we’re hiring/你有才,我雇你
    Founders Larry Page and Sergey Brin approve hires. They favor intelligence over experience. /Larry Page和Sergey Brin的雇人之道是,喜欢聪明人胜过有经验的人
  • A license to pursue dreams/允许追求梦想
    Letting employees use 20% of their time on what ever they want./让员工用20%的时间做爱做的事
  • Data is apolitical/数据中没有政治
    There is no “I like”, it is all about the basing decisions on data./不要说“我喜欢”,所有决定都靠数据立足
  • Creativity loves constraints / 创造力爱制约
    Engineers thrive on constraints. /工程师靠限制发展
  • It’s users, not money / 是用户而不是钱
    If you can successfully engage users, you can monetize them/如果你能成功吸引用户,你就能赚钱
  • Don’t kill projects, morph them/不要毙掉项目,改造它
    Products that doesn’t seem to respond well in the market should be morphed into something the market needs, not cancelled /产品市场反响不好应该改造它以适应市场的需求,而不要轻易取消它

的确耐人寻味.


Tags: thought
Tuesday May 19, 2009 - 08:21pm (PDT) Permanent Link | 0 Comments
YUI 3.x的代码重用方法
面向对象的代码设计,本质上是追求代码的重用率。YUI 3中提供了不少令人惊喜的方法,在开发都是非常有用的。

Y.mix方法

Y.merge, Y.aggregate和Y.extend都用到Y.mix方法,所以它是一个基础方法(基础意味着参数较多,用法灵活不好记住)。格式:
Y.mix(r, s, ov, wl, mode, merge);
其中参数mode:
default(0): object to object
1: prototype to prototype (old augment)
2: prototype to prototype and object props (new augment)
3: prototype to object
4: object to prototype
ov - 属性重复是否覆盖。默认不覆盖。
wl - 属性白名单,数组形式。注:mix方法用的形式跟augment方法用的形式不同。

感觉下面这行跟Y.augment(fun1, fun2)的作用相同:
Y.mix(fun1, fun2, 0, null, 1);

将fun1的prototype上的属性添加到obj上:
Y.mix(obj, fun1, 0, null, 3);

将obj的属性添加到fun1的prototype上:
Y.mix(fun1, obj, 0, null, 4);

Y.mix实现了相当灵活的代码重用。一个object或function可以被mix到任意地方。

Y.merge和Y.aggregate的区别

Y.merge将任意个object({...})合并成一个新的object,属性重名后者的覆盖前者的。如:
var newObj = Y.merge(obj1, obj2, obj3, ...objn);
产生的新对象不是reference到旧对象的关系,所以改变obj1属性的值不会影响到newObj。

Y.aggregate实现从一个object({...})向另一个object添加属性。格式:
Y.aggregate(r, s, true, ['prop1', 'prop2']);
将对象s的属性prop1和prop2(白名单方式)添加到对象r上,重名覆盖。

Y.augment和Y.extend的区别

作用都是实现function之间方法的重用。区别是extend是实现继承(类之间有上下级关系),而augment仅仅是从一个function向另一个function添加方法和属性。

Y.extend从fun2的原型链上继承方法和属性,同时扩展新的。扩展时有重名的覆盖。
Y.extend(fun1, fun2, {...扩展fun1原型链上的方法...}, {...扩展fun1的静态方法...});
在fun1的constructor中写入,则可继承fun2自己的属性和方法:
fun1.superclass.constructor.apply(this, arguments);

Y.augment仅仅从fun2的原型链上添加方法和属性。有重名的默认跳过。
Y.augment(fun1, fun2);
重名覆盖需指定第三参数,如:
Y.augment(fun1, fun2, true);
指定白名单,只添加白名单中指定的,如:
Y.augment(fun1, fun2, true, {'prop3': true});

Y.bind绑定新的scope

Y.bind会返回一个新的function。格式:var newfunc = Y.bind(func, scope, arg1, arg2, ..., argn);
var o1 = {
prop: 10
};

var o2 = {
prop: 20
};

var func = function(){
alert(this.prop);
};

var newfunc = Y.bind(func, o1);
newfunc(); //alert 10

var newfunc = Y.bind(func, o2);
newfunc(); //alert 20


Y.clone克隆方法

上面介绍的Y.merge可以实现简单的克隆一个object,Y.bind可以克隆一个function。

Y.clone方法的格式:var newObj = Y.clone(o, safe, f, c, owner);
o - 要克隆的object或function
safe - (通过看源码,没搞明白,留待以后解决了)
f - 会传给回调方法key和value,通过return false;可以阻止copy,从而实现克隆过程中对一些属性的过滤
c - 指定f执行的scope
owner - 克隆function时,指定的上下文对象


Y.Base.build方法

文档中是这样说的:从主方法(类),和一组扩展方法(类)中创建一个新的构造方法(类)。
YUI 3.x的overlay组件就是一个典型的例子,非常精简,只有两行。可见YUI 3的代码重用效率很高。
Y.Overlay = Y.Base.build(Y.Widget, [Y.WidgetPosition, Y.WidgetStack, Y.WidgetPositionExt, Y.WidgetStdMod]);
Y.Overlay.NAME = "overlay";

Tags: yui3
Tuesday May 19, 2009 - 04:44am (PDT) Permanent Link | 0 Comments
YUI 3.x的事件
前不久YUI Team的工程师Satyen Desai深入的分析了YUI3的设计目标和框架。这个链接里是视频和演讲脚本:http://developer.yahoo.com/yui/theater/desai-yui3.html

YUI 3的新特征很令人期待,像我比较欣赏它的分级颗粒化模块设计、插件和内部的扩展机制,这些底层的设计特征非常“潮”。但对我来说,我更关心它的基本开发组件集(Utilities Set)是否够牛B,也就是说开发最基本的Dom, Event, Ajax等等这些。

这次说说YUI 3的Event组件。(组件是我的习惯叫法,在YUI 3中应该叫包,符合Java的叫法)

添加事件监听
向结点(或结点列表)绑定事件:
Y.on('click', handleClick, '#foo', this, arg1, arg2, arg3);
Y.on('click', handleClick, ['#foo1 a', '#foo2 a'], this, arg1, arg2, arg3);
Y.all('#foo1 a').on('click', handleClick);

删除事件
Y.detach('click', handleClick, '#foo');
var fooClickHandle = Y.on('click', handleClick, '#foo', this, arg1, arg2, arg3);
fooClickHandle.detach();
删除结点上所有绑定的事件:
Y.Event.purgeElement('#foo');
删除结点及它的子结点上所有绑定的事件:
Y.Event.purgeElement('#foo', true);
只删除结点上绑定的click事件:
Y.Event.purgeElement('#foo', false, 'click');

模拟事件
YUI 3.x这次提供了模拟事件,很有意思。目前支持模拟下面的事件:
  • click
  • dblclick
  • mousedown
  • mouseup
  • mouseover
  • mouseout
  • mousemove

摸拟点击一个button:
Y.Event.simulate(document.getElementById('bn-submit'), 'click'); //参数1,必须为原生结点
同时按着Ctrl键:
Y.Event.simulate(document.getElementById('bn-submit'), 'click', {ctrlKey: true});

摸拟mouseover一个DIV:
Y.Event.simulate(document.getElementById('map'), 'mouseover');
同时指定相关目标结点:
Y.Event.simulate(document.getElementById('map'), 'mouseover', {relatedTarget: document.body});
同时指定mouseover的坐标:
Y.Event.simulate(document.getElementById('map'), 'mouseover', {clientX: 100, clientY: 100});

模拟键盘事件
目前支持摸拟下面的键盘事件:
  • keyup
  • keydown
  • keypress
Y.Event.simulate(document.getElementById('map'), 'keydown', {keyCode: 97}); //在div#map上摸拟按下'A'键。keyCode的值也支持代码名:ctrlKey, altKey, shiftKey 和 metaKey。

渲染周期事件
available事件
检测一个结点加到DOM树上被执行。如:
Y.on('available', handleOnAvailable, '#foo');
Y.get('body').appendChild(Y.Node.create('<div id="foo">...something...</div>'));

contentready事件
文档上说是结点的内容完全下载完后被执行,依据目标结点的nextSibling结点是否有效。由于过程很快,测试中没看出跟available事件有什么区别。

domready事件
页面在渲染时,一旦DOM树处于可用状态,此事件将被执行。现在通常用domready替代window的load事件。
Y.on('domready', init);

键盘事件
监听在任意元素上的键盘动作:
Y.on('key', handleKeyDown, '#foo', 'down:13');
Y.on('key', handleKeyDown, '#foo', 'down:65,66');
Y.on('key', handleKeyDown, '#foo', 'down:65,66+shift+ctrl', this, arg1, arg2);
第4个参数的格式为“键盘事件:keycode[+shift+ctrl+alt+meta]”。

focus和blur事件
IE和W3C对这两个事件的支持是不同的。近期PPK在yahoo做的一个培训详细介绍过这两件事件,详细请参考这个链接:http://www.quirksmode.org/blog/archives/2009/04/yahoo_presentat.html
用法:
Y.on('focus', handleFocus, '#foo a');
Y.on('blur', handleBlur, '#foo a');

自定义事件
YUI 2.x的自定义事件让开发变得很灵活,而YUI 3.x的自定义事件则更加强大。
官方的介绍“自定义事件具有能冒泡、能取消和内在AOP的特质”。(什么是AOP?参考:http://en.wikipedia.org/wiki/Aspect-oriented_programming)
Satyen Desai在“YUI3的设计目标和框架”中分析过YUI 3自定义事件的机制。

看看如何:
var publisherFactory = function(){
this.publish('event1');
this.publish('event2');
};

Y.augment(publisherFactory, Y.Event.Target);

var publisher = new publisherFactory();

publisher.subscribe('event1', function(){
Y.log('event 1');
});

publisher.fire('event1');

在发布自定义事件同时定义默认处理方法:
var defHandleEvent = function(){
Y.log('default event handler');
};
this.publish('event1', {defaultFn: defHandleEvent});

发布自定义事件的其它配置:
  • 'broadcast': whether or not the YUI instance and YUI global are notified when the event is fired (false)
  • 'bubbles': whether or not this event bubbles (true)
  • 'context': the default execution context for the listeners (this)
  • 'defaultFn': the default function to execute when this event fires if preventDefault was not called
  • 'emitFacade': whether or not this event emits a facade (false)
  • 'fireOnce': if an event is configured to fire once, new subscribers after the fire will be notified immediately.
  • 'preventable': whether or not preventDefault() has an effect (true)
  • 'preventedFn': a function that is executed when preventDefault is called
  • 'queuable': whether or not this event can be queued during bubbling (false)
  • 'silent': if silent is true, debug messages are not provided for this event.
  • 'stoppedFn': a function that is executed when stopPropagation is called
  • 'type': the event type (valid option if not provided as the first parameter to publish)
(出自:http://developer.yahoo.com/yui/3/api/Event.Target.html

AOP的实现
关于AOP的解释: "AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程。可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。"

通过subscribe、before方法可以添加处理方法到默认处理方法之前,通过after方法添加处理到默认处理方法之后。如:
publisher.subscribe('event1', function(){
Y.log('event 1');
});
publisher.before('event1', function(){
Y.log('before: event 1');
});
publisher.after('event1', function(){
Y.log('after: event 1');
});
publisher.fire('event1');

触发event1后,看到的log信息将会是:
event 1
before: event1
default event handler
after: event1
(其中subscribe和before的顺序是看其定义的顺序)
可以在前后任意增加处理方法,确实很cool!

YUI 3的Event确实很好,很强大,唯一缺的可能就是对特殊事件的支持,比如mousewheel, mouseenter, mouseleave
Tags: yui3
Friday May 15, 2009 - 01:00am (PDT) Permanent Link | 0 Comments

Add Kejun's Blog to your personalized My Yahoo! page:

Add to My Yahoo!RSS About My Yahoo! & RSS
1 - 5 of 192 First | < Prev | Next > | Last