今天开始就正式进入了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