翻出之前做的小练习–原生JS实现QQ列表展开收缩
功能
1
每次点击一级菜单,展开对应的二级菜单,则收起其他一级菜单和对应的二级菜单,并且清除被点击过的二级菜单的背景颜色
2
a,第一点击二级菜单里的每一项,背景颜色为红色。第二次点击时,清除背景色。
b,第二次点击二级菜单里的项时,如果其背景色为红色,那么清除背景色。
主要思路
:为每个点击元素添加开关属性,避免事件干扰。每次点击前清空之前的操作。
注意点:
当点击二级菜单项后(背景颜色为红色),再次点击一级菜单项,要清楚二级菜单项的背景颜色
(ps: 元素命名比较随便,未做到语义化;代码未考虑精简,略显冗余(不过可读性强~~);试着考虑到渐进增强,平稳退化~~)
完成效果图:
下面是代码:
html:
<ul id="box">
<li>
<h2><span></span>我的好友</h2>
<ul>
<li class="li1">张三</li>
<li class="li1">张三</li>
<li class="li1">张三</li>
<li class="li1">张三</li>
</ul>
</li>
<li>
<h2><span></span>企业好友</h2>
<ul>
<li class="li1">李四</li>
<li class="li1">李四</li>
<li class="li1">李四</li>
<li class="li1">李四</li>
<li class="li1">李四</li>
</ul>
</li>
<li>
<h2><span></span>黑名单</h2>
<ul>
<li class="li1">张小三</li>
<li class="li1 noborder">李小四</li>
</ul>
</li>
</ul>
css
<style type="text/css">
ul,
h2 {
margin: 0;
padding: 0;
list-style: none;
}
#box {
margin: 100px auto;
width: 200px;
min-height: 150px;
border: 1px solid #000;
}
h2 {
height: 50px;
font: 30px/50px "微软雅黑";
background: aqua;
cursor: pointer;
-webkit-user-select: none;
}
span {
display: inline-block;
width: 0;
height: 0;
border: 8px solid transparent;
border-left-color: darkgray;
margin-left: 8px;
}
#box li li {
height: 30px;
border-bottom: 1px solid #000;
font: 20px/30px "微软雅黑";
text-indent: 10px;
cursor: pointer;
}
#box li ul {
display: none;
}
#box .noborder {
border: none;
}
.bg1 {
background: goldenrod;
}
</style>
JS部分:
<script type="text/javascript">
window.onload = function() {
//找元素
var oBox = document.getElementById('box');
var aH2 = oBox.getElementsByTagName('h2');
var aUl = oBox.getElementsByTagName('ul');
var aSpan = oBox.getElementsByTagName('span');
var aLi = oBox.getElementsByClassName('li1');
for(var i = 0; i < aH2.length; i++) { //遍历所有的h2元素
aH2[i].index = i; //存储每个h2的下标
aH2[i].onoff = true; //给每个h2添加自定义属性(开关)
aH2[i].onclick = function() { //每个给h2添加点击事件
//每次点击h2元素清空所有二级列表的背景颜色和开关的值
for(var i = 0; i < aLi.length; i++) {
aLi[i].style.background = '';
aLi[i].onoff = true;
}
if(this.onoff) { //如果被点击的这个h2开关为真
for(var j = 0; j < aUl.length; j++) { //遍历二级列表ul
if(aH2[j].className != '') { //如果h2上css样式不为空,就改变其开关值(避免出现二次点击)
aH2[j].onoff = !aH2[j].onoff;
}
//清空所有h2,span,二级列表ul点击前的样式
aH2[j].className = '';
aSpan[j].style.cssText = '';
aUl[j].style.display = 'none';
}
//为被点击的h2和所对应的span,二级列表ul设定所需样式;并设置开关值为假
aH2[this.index].className = 'bg1';
aSpan[this.index].style.cssText = 'border-left-color: transparent;border-top-color: darkgray;'
aUl[this.index].style.display = 'block';
this.onoff = false;
} else { //如果被点击的这个h2开关为假
//为被点击的h2和所对应的span,二级列表ul设定所需样式;并设置开关值为假
aH2[this.index].className = '';
aSpan[this.index].style.cssText = '';
aUl[this.index].style.display = 'none';
this.onoff = true;
}
}
};
for(var i = 0; i < aLi.length; i++) { //遍历所有的二级列表下的li元素
aLi[i].onoff = true; //给每个li添加自定义属性(开关)
aLi[i].index = i; //存储每个li的下标
aLi[i].onclick = function() { //给每个li添加点击事件
if(this.onoff) { //如果被点击的这个h2开关为真
for(var k = 0; k < aLi.length; k++) {
if(aLi[k].style.background != '') {
aLi[k].onoff = !aLi[k].onoff; //如果li上style样式不为空,就改变其开关值(避免出现二次点击)
}
aLi[k].style.background = ''; //清空所有li上的style样式
}
aLi[this.index].style.background = 'red'; //重新为被点击的li设置style样式
this.onoff = false; //为被点击的li设置开关为假
} else { //点击的时候被点击的li上的开关为假的时候
aLi[this.index].style.background = ''; //清空其上的style样式并设置其开关为真
this.onoff = true;
}
}
}
};
</script>