YUI2.8相关核心源码浅解及学习笔记(一)

文章写的太长了,分几部分好了,接着上面刚讲的,接下去是DOM模块

[b]一、DOM模块:[/b]

一般的js框架肯定少不了的几大模块之一,YUI的dom模块的确是没有像jQ做的那么神奇的感觉,但它却是众多dom框架的鼻祖之一。那就来看看:

首先是$()的YUI版本:get()

[b]1、get(ele)[/b]

这边源码不贴了,与jQ强大的$来说get只能取到ID值,其实就是对getElementById的封装(对于本身就是DOM元素的直接返回),不过看过源码后指出一点
              if ('length' in el) { // array-like 
c = [];
for (i = 0, len = el.length; i < len; ++i) {
c[c.length] = Y.Dom.get(el[i]);
}

return c;
}

这边可以传一个数组类似于一个装着id值的数组,就能直接返回DOM元素的数组了。

再看其他的函数前我们先看看这个batch的函数

[b]2、batch()[/b]

这个函数主要管的就是对于可能元素数组的传入值进行method的分配

batch: function(el, method, o, overrides) {
var collection = [],
scope = (overrides) ? o : window;//作用范围,如果为true则是用o对象

el = (el && (el[TAG_NAME] || el.item)) ? el : Y.Dom.get(el); // 如果el存在并且有DOM则直接用,否则要用get,就是说可以传id值的数组哦~~
if (el && method) {
if (el[TAG_NAME] || el.length === undefined) { //如果ele是单个元素则直接用call返回
return method.call(scope, el, o);//实际传入两个参数el,o
}

for (var i = 0; i < el.length; ++i) {
collection[collection.length] = method.call(scope, el[i], o);//对于数组的每个元素都进行一次method调用
}
} else {
return false;//这边的el和方法属性是必须的
}
return collection;
},

代码解释看上面我的注释,这边的collection[collection.length]是亮点!相当于是进行一次对索引值++一次,因为length总比最后的索引值大一~~

这个方法基本上都是执行私有方法,不过YUI中的私有方法非真正的闭包私有,只是在公共方法名前加上下划线
这边来看一个hasClass方法:

hasClass: function(el, className) {
return Y.Dom.batch(el, Y.Dom._hasClass, className);
},

这边因为el可能是个数组所以调用了batch方法,把私有方法_hasClass传入,该方法的形参传入为ele,className。

接下来是getElementsBy这个方法,为什么要先讲这个方法呢,这个是好多getEleBy...的都是这种形式的。

[b]3、getElementsBy(method, tag, root, apply, o, overrides, firstOnly)[/b]

这个方法主要是根据测试函数method进行筛选DOM元素,当然原始的数组是从ByTagName中取得的,直接看源码:

getElementsBy: function(method, tag, root, apply, o, overrides, firstOnly) {
tag = tag || '*';//建议使用该方法时最好加上tag值。。。不然效率会降低很多
root = (root) ? Y.Dom.get(root) : null || document; //开始的树

if (!root) {//检测
return [];
}

var nodes = [],
elements = root.getElementsByTagName(tag);//取得原始数组
//下面开始筛选元素
for (var i = 0, len = elements.length; i < len; ++i) {
if ( method(elements[i]) ) {//逐个迭代入测试函数,测试函数为一个只能传入DOM元素返回boolean值的函数
if (firstOnly) {//取得第一个元素,类似于tp框架的find函数
nodes = elements[i];
break;//跳出外层循环
} else {
nodes[nodes.length] = elements[i];//又是这种形式的自加
}
}
}

if (apply) {//这边的apply是一个函数
Y.Dom.batch(nodes, apply, o, overrides);//调用batch迭代apply
}


return nodes;
},

老样子具体看我上面的注释,这边getElementBy函数最后一个firstOnly直接设为true调用;

下面再来看看byClassName在YUI是怎么实现的
直接上源码:

getElementsByClassName: function(className, tag, root, apply, o, overrides) {
tag = tag || '*';
root = (root) ? Y.Dom.get(root) : null || document;
if (!root) {
return [];
}

var nodes = [],
elements = root.getElementsByTagName(tag),//都用到的方法
hasClass = Y.Dom.hasClass;//引用别名

for (var i = 0, len = elements.length; i < len; ++i) {
if ( hasClass(elements[i], className) ) {//这边相当于getElementsBy的测试函数
nodes[nodes.length] = elements[i];//又是那种++法,我很喜欢
}
}

if (apply) {
Y.Dom.batch(nodes, apply, o, overrides);
}

return nodes;
},

是不是感觉很上面的getElementsBy方法很相近啊,具体看我注释。

基本所有的取得节点的方法都是类似的形式
接下来是关于属性的方法,和上面的hasClass方法一样调用私有方法:
 
_getAttribute: function(el, attr) {
var val;
attr = Y.Dom.CUSTOM_ATTRIBUTES[attr] || attr;

if (el && el.getAttribute) {
val = el.getAttribute(attr, 2);//这边是用到了element接口的getAttribute方法,2为node_type
} else {
}

return val;
},

这边的Y.Dom.CUSTOM_ATTRIBUTES[attr]是YUI对IE和w3c下的别名进行封装;

CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
'for': 'htmlFor',
'class': CLASS_NAME // CLASS_NAME = 'className'
} : { // w3c
'htmlFor': 'for',
'className': _CLASS // _CLASS = 'class'
},

相当于你这里传入for或htmlFor都是被允许的,它们可以按浏览器版本进行匹配。

[b]继续~~下面的一些方法略写下[/b]

getStyle()
这个解释也不用多,按照getComputedStyle和currentStyle的差别区分浏览器,期间也是用到了batch方法+私有方法迭代~

setStyle(el, property, val)
这个方法比较坑爹感觉,明显比不支持json格式的css传入,opacity解决了浏览器差异,还有float属性不用分IE的styleFloat还是w3c的cssFloat,直接传float就行了

getX和getY还有getXY都是用_getXY私有方法实现的,解决了浏览器一些兼容问题

还有要提一下isAncestor这个方法:(看API文档实在感觉好笑)

isAncestor: function(haystack, needle) {
haystack = Y.Dom.get(haystack);
needle = Y.Dom.get(needle);

var ret = false;

if ( (haystack && needle) && (haystack[NODE_TYPE] && needle[NODE_TYPE]) ) {
if (haystack.contains && haystack !== needle) { // contains returns true when equal
ret = haystack.contains(needle);
}
else if (haystack.compareDocumentPosition) { // gecko
ret = !!(haystack.compareDocumentPosition(needle) & 16);
}
} else {
}
return ret;
},

[b]
这边的haystack是干草堆的意思(相当于是祖先元素 ),而needle是缝衣针的意思(相当于是子元素 ),这边特别形象,yahoo的工程师个个都是宝啊,噶幽默~~
就感觉是android系统开发中有一个方法叫toast(弹出提示的一个widget),为什么叫toast呢??因为西方的toast面包都是从面包机里弹出来的!!太形象了!!所以编程的时候也可以有些小幽默的命名,能够印象深刻。[/b]

[b] 小结下:YUI的DOM处理方法的共同点就是传形参的第一个参数基本都是ele元素,这在jQ中通过链式方式实现,其后的参数的本质其实是相同的,总的来说从DOM的使用方法来说jQ和YUI有些不同,YUI稍显麻烦,但究其本质的Dom元素处理方式其实是相似的~
[/b]
下一篇准备讲一下事件模块~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值