今日任务:了解学习DOM的基础知识以及学习拆合菜单实例
KISSY的DOM模块的子模块和方法众多,但又很重要,最好的情况是全部熟练掌握,当然一开始学是不可能全部记住DOM的方法。所以这里列举了一些比较常用的重要的方法。
CSS 选择器,关键方法:get、query
class 属性相关操作,关键方法:addClass、removeClass、hasClass
通用属性操作,关键方法:attr、removeAttr、val 、text
样式操作,关键方法:css、width、height、show、hide
(下一节将实例演示以下方法)
遍历操作,关键方法:parent、children、next、prev、siblings
创建操作,关键方法:create、remove、html
这些方法都比较重要,将在下面的实例中运用到,注意体会学习。
一、从get说起
DOM.get极其常用,用于获取符合选择器的第一个元素,如果不存在所选择的元素,返回为空。
若想获取id为“menu”的拆合菜单元素,只需要DOM.get(“#menu”);即可。
KISSY除了get,还有名为one(隶属于node模块)的方法也是用于获取合选择器的元素,也非常常用,关于二者的区别将在讲解node模块时说明。
二、query与get的区别
query用于获取符合选择器的所有元素,不管所选取的元素是几个,返回的都是一个数组, query与get的区别是query用于选取多个元素,而get只能获取符合选择器的第一个元素,即相当于调用query(selector,context)[0]。
看示例中获取class为“menu-item”的li
var menuItem = DOM.query(“#menu .menu-list”);
既然是数组,自然带有length属性,所以可以获取选取的个数,比如:
alert(menuItem.length);
本例中可得其长度是3。
三、addClass和removeClass
这是一组非常常用的方法,顾名思义用于添加样式和删除样式。
还记得上一篇教程中的例子吗?
目标对象同时监听多个事件:
KISSY.use('event',function(S,Event){ S.Event.on('#demo3','mouseover mouseout',function(ev){ if(ev.type=='mouseover'){ S.DOM.addClass('#demo3','demo3-over'); } else if(ev.type=='mouseout'){ S.DOM.removeClass('#demo3','demo3-over'); } }); }); |
可以用一行代码搞定颜色切换,来看代码:
KISSY.use('event',function(S,Event){ Event.on('#demo3','mouseover mouseout',function(ev){ S.DOM[ev.type =='mouseover'&&'addClass'||ev.type =='mouseout'&&'removeClass']('#demo3','demo3-over'); }); }); |
纯属技巧,可读性不高,不推荐使用。不过,在DOM模块里,KISSY提供了能够达到 hover的效果的方法:
KISSY.use('event',function(S,Event){ Event.on('#demo3','mouseover mouseout',function(ev){ S.DOM.toggleClass(this,"demo3-over"); }); }); |
说明:toggleClass ( selector, classNames)操作符合选择器的所有元素, 如果存在值为 classNames 的class, 则移除掉, 反之添加。
很好理解的一组方法:添加属性和删除属性。
要留意的是属性不存在时,返回的是undefined而不是null。
五、val和text
这组方法也非常容易理解:是对元素value属性和text文本值的处理。
无值时,返回“”。
一个是显示符合选择器的所有元素,另外一个是隐藏符合选择器的所有元素,也是非常常用。
var nextMenu = DOM.next(ev.target);
DOM.show(nextMenu);
DOM.hide(nextMenu);
七、css
String css ( selector, name )获取符合选择器的第一个元素的样式值。
void css ( selector, name, value ) 给符合选择器的所有元素设置样式值.
var nextMenu = DOM.next(ev.target);
var display = DOM.css(nextMenu,’display’);
这里补充说明一点val、text、css、width、height等类似的一批获取和设置一起的方法,获取时只获取第一个元素的相应的值,尽管你的选择器是包含多个元素。
width获取/设置元素宽度; height获取/设置元素高度。
至此,DOM基础篇结束,DOM中最常用的几个方法都介绍过了,DOM基础+Event事件基础已经足以完成类似拆合菜单、多级导航等简单的交互任务。
学到了这里,有没有发现DOM的API风格和jquery极其相似?如果你接触过jquery,那么上述方法看到名字其实就会明白其含义。API的语义还是非常清晰的。
由于这部分方法较多,不再一一举例讲解,做了一个demo,咱们一起来看看是什么吧。
页面图略
需要的两个图片:
menu-arrow.jpg
menu-header-bg.jpg
相应的day-5.js文件代码为:
KISSY.use('dom', function(S, DOM) { var menuItem = DOM.query("#menu .menu-list"); alert(menuItem.length); });
KISSY.use('dom,event', function(S, DOM, Event) { var childrenMenus = DOM.query("#menu ul"); var childrenMenus1=DOM.query("#menu div a"); DOM.hide(childrenMenus); Event.on(DOM.get("#btn-1"),'click', function() { DOM.hide(childrenMenus); S.each(childrenMenus1,function(v){ DOM.removeClass(v,'arrow-down'); }); }); Event.on(DOM.get("#btn-2"),'click', function() { DOM.show(childrenMenus); S.each(childrenMenus1,function(v){ DOM.addClass(v,'arrow-down'); }); }); }); KISSY.use('dom,event', function(S, DOM, Event) { var menuItemHeader = DOM.query("#menu div"); Event.on(menuItemHeader, 'click',function(ev) { var nextMenu = DOM.next(ev.target); // 获取子菜单的display样式属性值 var display = DOM.css(nextMenu,'display'); var children = DOM.children(ev.target); // 根据子菜单的显示情况来判断是否显示子菜单 if (display =='none') { DOM.show(nextMenu); DOM.addClass(children, 'arrow-down'); } else { DOM.hide(nextMenu); DOM.removeClass(children, 'arrow-down'); } return false; }); }); |
这里需要提一下的是我们使用的each方法,是kissy种子文件lang里的方法,此方法的功能是:遍历数组中的每一项, 执行指定方法。
那么现在我们想增加一项新功能,即:当展开某项子菜单时,同时隐藏其他子菜单。
根据以上我们所学的知识,可以这样实现:
KISSY.use('dom,event', function(S, DOM, Event) { var menuItemHeader = DOM.query("#menu div"); var childrenMenus = DOM.query("#menu ul"); var childrenMenus1 = DOM.query("#menu div a"); DOM.hide(childrenMenus); Event.on(menuItemHeader, 'click',function(ev) { var nextMenu = DOM.next(ev.target); var disp = DOM.css(nextMenu,'display'); DOM.hide(childrenMenus); if (disp !='none') { DOM.css(nextMenu, 'display','block'); } // 获取子菜单的display样式属性值 var display = DOM.css(nextMenu,'display'); var children = DOM.children(ev.target); // 根据子菜单的显示情况来判断是否显示子菜单 if (display =='none') { DOM.show(nextMenu); S.each(childrenMenus1, function(v) { DOM.removeClass(v, 'arrow-down'); }); DOM.addClass(children, 'arrow-down'); } else { DOM.hide(nextMenu); DOM.removeClass(children, 'arrow-down'); } return false; }); }); |
这样虽然能实现功能,但是在思路上却有欠妥之处。我们先休息下吧,关于为何欠妥,我们将在下一节继续学习。