![](https://box.kancloud.cn/04c9fbc0b67581e1b5e7726cc508967c_592x291.png)
```
var box = document.getElemenById("box");
var spanList = box.getElementsByTagName("span");
for(var i=0;i<span.List.length;++i){
var curSpan = spanList[i];
var curPre = utils.prev(curSpan); //->获取当前的span的上一个哥哥元素节点
if(curPre&&curPre.tagName.toLowerCase()==='em'){
curSpan.style.cursor = "pointer";
}
}
```
使用时间委托实现展开子级
```
box.onclick = function(e){
e = e||window.event;
var tar = e.target||e.srcElement;
//如果点击的是em/span标签我们才进行展开收缩操作
if(/^(em|span)$/i.test(tar.tagName)){
var parent = tar.parentNode; //->获取父亲
var oEm = utils.children(parent,"em")[0]; //->获取父亲子集中的第一个em标签
var firstUl = utils.children(parent,"ul")[0]; //->获取父亲子集中的第一个ul标签
if(firstUl){ //->只有存在我们才进行相关操作
//->如果这个ul当前是隐藏我们让其显示,否则的话让其隐藏
var isBlock = utils.getCss(firstUl,"display")==="block")?true:false;
if(isBlock){ //->当前是显示的
firstUl.style.displa = "none";
if(oEm){
utils.removeClass(oEm,"open");
}
//->当外层的收起,里层所有的ul都要隐藏,并且所有的em都要移除open样式
var allUl = parent.getElementsByTagName("ul"),allEm = parent.getElementsByTagName("em");
for(var i=0;i<allUl.length;++i){
allUl[i].style.display = "none";
utils.removeClass(allEm[i],"open");
}
}else{ //-> 当前隐藏的
firstUl.style.displa = "block";
if(oEm){
utils.addClass(oEm,"open");
}
}
}
}
}
```
---
jQ版
```
var $box = $("#box");
// $("#box>span")
$box.find("span").each(function(index,item){
//$(this) -> 每一次循环的时候,当前循环的这个元素
var $pre = $(this).prev();
if($pre[0]&&$pre[0].tagName.toLowerCase()==="em"){
$(this).css("cursor","pointer");
}
});
```
```
//jQuery中除了bind、unbind、on、off、click、mouseover...这些绑定事件的方式外,还提供了一种 delegate(1.7版本以前用的是live)
$box.delegate("em","click",fn); //->给$box绑定点击事件,如果当前的事件源是em的话,我们执行fn
$box.delegate("span","click",fn);
function fn(){
var $par = $(this).parent();
var $ul = $($par.children("ul")[0]);
var $em = $($par.children("em")[0]);
if($ul.length>0){
var isBlock = $ul.css("display")==="block"?true:false; //进来就保存后面有用
$ul.toggle();
$em.toggleClass("open");
//->当前的如果是收缩的话,我们需要把下面子子孙孙中所有ul/em都隐藏和移出open样式
if(isBlock){
$par.find("ul").css("display","none");
$par.find("em").removeClass("open");
}
// if(isBlock){
// $ul.slideUp();
// $em.removeClass("oepn");
// $par.find("ul").css("display","none");
// $par.find("em").removeClass("oepn");
// }else{
// $ul.slideDown();
// $em.addClass("open");
// }
}
}
```
- 空白目录
- window
- location
- history
- DOM
- 什么是DOM
- JS盒子模型
- 13个核心属性
- DOM优化
- 回流与重绘
- 未整理
- 文档碎片
- DOM映射机制
- DOM库封装
- 事件
- 功能组件
- table
- 图片延迟加载
- 跑马灯
- 回到顶部
- 选项卡
- 鼠标跟随
- 放大镜
- 搜索
- 多级菜单
- 拖拽
- 瀑布流
- 数据类型的核心操作原理
- 变量提升
- 闭包(scope)
- this
- 练习题
- 各种数据类型下的常用方法
- JSON
- 数组
- object
- oop
- 单例模式
- 高级单例模式
- JS中常用的内置类
- 基于面向对象创建数据值
- 原型和原型链
- 可枚举和不可枚举
- Object.create
- 继承的六种方式
- ES6下一代js标准
- babel
- 箭头函数
- 对象
- es6勉强笔记
- 流程控制
- switch
- Ajax
- eval和()括号表达式
- 异常信息捕获
- 逻辑与和或以及前后自增
- JS中的异步编程思想
- 上云
- 优化技巧
- 跨域与JSONP
- 其它跨域相关问题
- console
- HTML、XHTML、XML
- jQuery
- zepto
- 方法重写和方法重载
- 移动端
- 响应式布局开发基础
- 项目一:创意简历