淘宝Kissy框架分析【七】
2010-06-20 18:39 BlueDream 阅读(1919) 评论(0) 编辑 收藏 举报今天开始就正式进入了DOM文件夹部分. DOMAPI算是比较难搞的部分.KISSY也在不断完善中.所以现在实现的不是很全面.这篇我们主要看下
dom.js和dom-class.js
dom.js只定义了个命名空间.代码还没有具体实现
J.DOM = {
_isElementNode: function(elem) {
return elem && elem.nodeType === 1;
}
};
});
但由于DOM方法都是扩展在J.DOM命名空间下.所以这个文件是必须的.
dom-class.js是对元素的class进行了控制.
【程序源码】
var SPACE = ' ',
DOM = J.DOM,
REG_SPLIT = /[\.\s]\s*\.?/,
REG_CLASS = /[\n\t]/g;
J.mix(DOM, {
// selector是否存在指定的class
hasClass: function(selector, value) {
return batch(selector, value, function(elem, classNames, cl) {
var elemClass = elem.className;
if (elemClass) {
var className = SPACE + elemClass + SPACE, j = 0, ret = true;
for (; j < cl; ++j) {
if (className.indexOf(SPACE + classNames[j] + SPACE) < 0) {
ret = false;
break;
}
}
if (ret) return true;
}
}, true);
},
// 为selector 添加class
addClass: function(selector, value) {
batch(selector, value, function(elem, classNames, cl) {
var elemClass = elem.className;
if (!elemClass) {
elem.className = value;
}
else {
var className = SPACE + elemClass + SPACE, setClass = elemClass, j = 0;
for (; j < cl; ++j) {
if (className.indexOf(SPACE + classNames[j] + SPACE) < 0) {
setClass += SPACE + classNames[j];
}
}
elem.className = J.trim(setClass);
}
});
},
// 为指定的selector删除class
removeClass: function(selector, value) {
batch(selector, value, function(elem, classNames, cl) {
var elemClass = elem.className;
if (elemClass) {
if (!cl) {
elem.className = '';
}
else {
var className = (SPACE + elemClass + SPACE).replace(REG_CLASS, SPACE), j = 0;
for (; j < cl; j++) {
className = className.replace(SPACE + classNames[j] + SPACE, SPACE);
}
elem.className = J.trim(className);
}
}
});
},
// 用新class替换旧的class
replaceClass: function(selector, oldClassName, newClassName) {
DOM.removeClass(selector, oldClassName);
DOM.addClass(selector, newClassName);
},
// 切换指定的class. state是强制删除或者添加
toggleClass: function(selector, value, state) {
var isBool = J.isBoolean(state), has;
batch(selector, value, function(elem, classNames, cl) {
var j = 0, className;
for (; j < cl; ++j) {
className = classNames[j];
has = isBool ? !state : DOM.hasClass(elem, className);
DOM[has ? 'removeClass' : 'addClass'](elem, className);
}
});
}
});
function batch(selector, value, fn, resultIsBool) {
if (!(value = J.trim(value))) return resultIsBool ? false : undefined;
var elems = J.query(selector),
i = 0, len = elems.length,
classNames = value.split(REG_SPLIT),
elem, ret;
for (; i < len; ++i) {
elem = elems[i];
if (elem.nodeType === 1) {
ret = fn(elem, classNames, classNames.length);
if (ret !== undefined) return ret;
}
}
if (resultIsBool) return false;
}
});
1. batch方法
这个方法是批量元素处理的核心方法.总共4个参数:
1) selector[选择器] 这个会通过J.query通过选择器选择出所有符合条件的元素. J.query会在下节讲解.
2) value要进行操作的样式名称.支持(acls bclas) (acls.bcls) (acls .bcls)等宽松模式.
3) fn 回调函数 选择器选出的NodeList value传入的classNames, classNames的长度会循环并作为参数传入回调函数.
4) resultIsBool 如果为true那么返回值为true或false, 否则为undefined.
2.addClass方法.
作用: 为selector筛选出的元素都追加value指定的class
我们下面测试的所有HTML都需要引入这些文件
.red {color:red}
.blue {background-color: blue}
</style>
<script src="../j1616/j1616.js"></script>
<script src="../j1616/j1616-ua.js"></script>
<script src="../j1616/j1616-lang.js"></script>
<script src="dom.js"></script>
<script src="dom-class.js"></script>
<script src="selector.js"></script>
</head>
<body>
<div id="odiv">div</div>
<div id="odiv2">div2</div>
测试用例
这样我们就为id为odiv2, odiv的元素都追加了red和blue的class ==> 字体变红,背景色变蓝.
3.hasClass方法
作用:判断选择器筛选出的元素是否含有value指定的class. 只要有一个元素符合那么就为true. 如果所有的元素都不匹配value那么就为false.
测试用例
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 只有odiv2符合 那么就返回true
4.removeClass方法
作用:为选择器筛选的元素删除value给定的class.
测试用例
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 只有odiv2符合 那么就返回true
J.DOM.removeClass('#odiv2', 'blue'); // 删除了blue样式
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 此时blue样式已被删除 所以返回false
5.replaceClass方法
作用:用一个新的class替换一个class
测试用例
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 只有odiv2符合 那么就返回true
J.DOM.removeClass('#odiv2', 'blue'); // 删除了blue样式
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 此时blue样式已被删除 所以返回false
J.DOM.replaceClass('#odiv2', 'red', 'blue'); // div元素的背景色变蓝 因为用blue替换了red
6.toggleClass方法
作用:切换一个指定的class. 如果第一次样式存在 那么就删除 第二次就又追加上 以此类推.
测试用例:
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 只有odiv2符合 那么就返回true
J.DOM.removeClass('#odiv2', 'blue'); // 删除了blue样式
J.log(J.DOM.hasClass('#odiv, #odiv2', 'red blue')); // 此时blue样式已被删除 所以返回false
J.DOM.replaceClass('#odiv2', 'red', 'blue'); // div元素的背景色变蓝 因为用blue替换了red
J.DOM.toggleClass('#odiv2', 'blue'); // 刚才blue样式存在,那么这次就将其移除
J.DOM.toggleClass('#odiv2', 'blue'); // 刚才blue样式被移除了.那么这次就添加上
这个方法还支持第三个参数state.这个参数可以强制指定是删除还是添加样式.如果true添加,如果false删除
【总结】
整个实现没有什么难度.流程就是. 通过batch去获得selector的所有元素.和所有的样式classNames.然后循环所有元素,依次将元素和所有样式数组传入回调方法中去执行addClass.removeClass等一系列处理后.然后返回. batch再返回这些返回值就可以了.
下节我们将要讲解选择器selector.js