今日任务:深入学习DOM知识及进一步完善拆合菜单实例
在上一篇的教程中,明河使用KISSY.DOM的常用方法制作了一个拆合菜单,同时也演练到了几个常用方法,比如addClass/removeClass、attr/removeAttr、show/hide等。
拆合菜单还远远不够完美,比如缺少动画,代码不够优雅,通用性太差等,再以后的教程中还会继续完善拆合菜单,今天先继续讲解kissy中的dom方法。
今天讲解DOM的遍历操作的方法和创建操作的方法。
首先看总体页面效果略
一、遍历操作的方法
有关便利操作的方法,我们首先来看实例。
在day-6.js里的代码:
KISSY.use('dom,event', function (S,DOM,Event) { //获取拆合菜单的父节点的id var menu = DOM.get("#menu"); Event.on('#btn-3','click',function(evt){ var menuParent = DOM.parent(menu); alert(menuParent.id); }); //获取拆合菜单的子节点li的个数 Event.on('#btn-4','click',function(evt){ var menuChildrens = DOM.children(menu); alert(menuChildrens.length); }); Event.on('#btn-5','click',function(evt){ var menuChildrens = DOM.children(menu); //上一个节点 var preItem = DOM.prev(menuChildrens[1]); //上一个节点的标题节点 var preItemTitle = DOM.children(preItem,'div'); //下一个节点 var nextItem = DOM.next(menuChildrens[1]); //下一个节点的标题节点 var nextItemTitle = DOM.children(nextItem,'div'); alert('上一个菜单项的标题为:'+DOM.text(preItemTitle)+',下一个菜单项的标题为:'+DOM.text(nextItemTitle)); }); }); |
btn-3、btn-4、btn-5的效果略
(1)parent、next、children、prev的说明:
parent:获取符合选择器的第一个元素的祖先元素;
next:获取符合选择器的第一个元素的下一个同级节点;
children:获取符合选择器的所有非文字节点的子节点;
prev:获取符合选择器的第一个元素的上一个同级节点;
其实children、next、prev、parent都有第二个参数,第二个参数是一个过滤器,比如示例中下一个节点的子节点有二个div、ul,但是我们只需用到div就可以了,这时候设置第二个参数为'div',那么就只取div节点了。
(2)隐藏子菜单方法改善—siblings
首先看一段上节的代码:
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; }); }); |
这段代码的用途是当你单击一个菜单项后,先隐藏所有子菜单,然后再显示当前菜单项下的子菜单,实际上这里的逻辑有个不对的地方,理论上来讲不该隐藏包括当前菜单项下的子菜单,应该是先隐藏除了当前菜单项下的子菜单下其他子菜单,然后再处理当前菜单项下的子菜单。
先不要着急,我们来看下siblings的用法:
siblings:获取符合选择器的第一个元素的相应同级节点
在day-6.js代码追加:
KISSY.use('dom,event', function (S,DOM,Event) { //隐藏除了第二个子菜单外的子菜单 Event.on('#btn-6','click',function(evt){ var menuChildrens = DOM.children(menu); var sibItems = DOM.siblings(menuChildrens[1]); //遍历同级节点并隐藏其子菜单 S.each(sibItems,function(v){ DOM.hide(DOM.children(v,'ul')); }); }); }); |
当然要想实现此功能,需要将源代码中DOM.hide(childrenMenus);删除,以便于拆合菜单的初始状态为全部展开。
掌握了siblings方法,就可以解决在上节的实例中的逻辑问题,于是优化后的代码为:
KISSY.use('dom,event', function (S,DOM,Event) { var childrenMenus = DOM.query("#menu ul"); var menuItemHeader = DOM.query("#menu div"); DOM.hide(childrenMenus); Event.on(menuItemHeader,'click',function(ev){ var nextMenu = DOM.next(ev.target); //隐藏除目标子菜单之外的子菜单 var sibItems = DOM.siblings(DOM.parent(ev.target)); S.each(sibItems,function(v){ DOM.hide(DOM.children(v,'ul')); DOM.removeClass(DOM.children(DOM.children(v,'div')),'arrow-down'); }); //获取子菜单的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; }); }); |
二、创建操作的方法
有关便利操作的方法,我们首先来看实例。
在day-6.js的代码追加:
KISSY.use('dom,event', function (S,DOM,Event) { //向第二个子菜单添加新的菜单项 Event.on('#btn-7','click',function(evt){ var menuChildrens = DOM.children(menu); var secondUl = DOM.children(menuChildrens[1],'ul'); //创建一个新的li节点 var newLi = DOM.create('<li class="new"><a>test13</a></li>'); DOM.append(newLi,secondUl); }); //删除新加入的菜单项 Event.on('#btn-8','click',function(evt){ var menuChildrens = DOM.children(menu); var secondUl = DOM.children(menuChildrens[1],'ul'); var newLi = DOM.children(secondUl,'.new'); //删除样式名为new的菜单项 DOM.remove(newLi); }); //替换第二个子菜单的所有菜单项 Event.on('#btn-9','click',function(evt){ var menuChildrens = DOM.children(menu); var secondUl = DOM.children(menuChildrens[1],'ul'); alert(DOM.html(secondUl)); DOM.html(secondUl,'<li class="new"><a>test</a></li>'); alert(DOM.html(secondUl)); }); }); |
点击id为btn-7的效果略
点击id为btn-8即是将所有新增加的子菜单项删除。
点击id为btn-9后的效果略
create、remove、html说明:
create:创建节点。DOM.create('<div></div>');等价于document.createElement('div');甚至可以支持更多属性,也可以直接内联属性。可用append(node,parent ) node追加到 parent 子节点最后。
remove:将符合选择器的所有元素从 DOM 中移除。
html:获取符合选择器的第一个元素的innerHTML。