大二的我有幸通过实习岗位加入一个公司的项目,大致做的是一个中小学生网上在线学习的网站,后端运用php,前端主要借助bootstrap4快速开发。
最近在做页面整体框架的左垂直导航栏时,有一个需求让现在的我着实有点头疼,需求内容大致如下:
- 首先,满足每个垂直导航块的一级菜单内部包含二级菜单。
- 其次,每次打开一个一级菜单,其余的一级菜单自动关闭。
- 接着,一级菜单的第一个默认打开,并且其中二级菜单的第一个默认选中。
- 最后,所有的二级菜单,必须有且仅有一个选中,其他未选中。意思是不能每个二级菜单相互独立,要相互关联。
需求分析
上面明确要求尽量用bootstrap4已经有的插件,毕竟用框架更加的稳定,测试上线时也不会出现特别奇怪的bug。
其实看到这个需求,再结合自己的bootstrap4知识,我第一个想到的是,运用折叠和列表组来完成。这两个玩意结合可以很好的满足前三个需求,唯一难办的是最后一个二级菜单相关联,我发现bootstrap4的列表组list-group下面的li必须作为直接子元素,否则列表组就崩了。
所以,运用collapse折叠和list-group列表组的嵌套显然是不合适的,你很难将不同的list-group相互关联,我查了不少资料,意识到如果纯的bootstrap4完成需求可能就要修改源码,我对这个不是很在行,毕竟前端自学的才半年左右,直接修改源码可能会导致其他插件出毛病,对于未知的东西,我不是很敢修改。
这是默认样式,满足需求三
它满足需求一和二
可是,它的每一个菜单的二级子菜单都是独立的,不关联的,不符合需求四。
我打算加一段js代码来覆盖bootstrap4的选择效果。
我删除了每一个二级菜单,也就是列表项的data-toggle="list"属性,加入了name=‘link’属性,js代码会根据这一属性,将所有有这一属性的列表项相关联,做到点击效果唯一。
下面是模拟的完整代码,项目代码我不能发出来
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap 实例</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
$(function(){
function clickNav(event) {
var target = event.currentTarget;
//上次选择的a的样式
if($("a[name='link']")){
var arrLink = $("a[name='link']");
for(i = 0; i < arrLink.length; i++) {
var link = arrLink[i];
if(link.classList.contains('active')) {
link.classList.remove('active');
}
}
}
target.classList.add('active');
}
if($("a[name='link']")){
var arrLink = $("a[name='link']");
console.log(arrLink.length);
for(i = 0; i < arrLink.length; i++){
var link = arrLink[i];
//默认链接第一个有active
if(i===0){
if(!link.classList.contains('active')){
link.classList.add('active');
}
}
else{
link.classList.remove('active');
}
link.onclick = clickNav;
}
}
});
</script>
</head>
<body>
<div class="container " style='width:300px;'>
<div id="accordion">
<div class="card">
<div class="card-header">
<a class="card-link" data-toggle="collapse" href="#collapseOne">
选项一
</a>
</div>
<div id="collapseOne" class="collapse show" data-parent="#accordion">
<div class="card-body">
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action active"name='link'>First item</a>
<a href="#" class="list-group-item list-group-item-action"name='link'>Second item</a>
<a href="#" class="list-group-item list-group-item-action"name='link'>Third item</a>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<a class="collapsed card-link" data-toggle="collapse" href="#collapseTwo">
选项二
</a>
</div>
<div id="collapseTwo" class="collapse" data-parent="#accordion">
<div class="card-body">
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action"name='link'>First item</a>
<a href="#" class="list-group-item list-group-item-action"name='link'>Second item</a>
<a href="#" class="list-group-item list-group-item-action"name='link'>Third item</a>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<a class="collapsed card-link" data-toggle="collapse" href="#collapseThree">
选项三
</a>
</div>
<div id="collapseThree" class="collapse" data-parent="#accordion">
<div class="card-body">
<div class="list-group">
<a href="#" class="list-group-item list-group-item-action"data-toggle="list"name='link'>First item</a>
<a href="#" class="list-group-item list-group-item-action"data-toggle="list"name='link'>Second item</a>
<a href="#" class="list-group-item list-group-item-action"data-toggle="list"name='link'>Third item</a>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
最后我把这个想法实现后,忽然需求又改了,不要求所有的二级子菜单相关联了,我最头疼的问题么得了,有点伤感哦,但还是赶紧来csdn把自己的想法保存下来。如果读者有更好的想法希望不吝赐教,毕竟我自学前端的时间不长,能力和认识都有限,作为一个江苏普通二本计科院的大二狗,很珍惜这次校内实习的机会,希望借助项目来提升自己,为将来发展前端打地基。