本文出自明月工作室:https://www.freebytes.net/it/front/bootstrap-nav-yuanli.html
Bootstrap官方导航栏
Bootstrap官方导航栏组件的实现效果,是这样的:
可见,屏幕收缩前,导航栏的每个导航项都横向排列在同一行内;屏幕收缩后, 最右端,出现了一个按钮(toggle), 点击toggle按钮后,发现导航栏整体移动到了下一行,每个导航项变成纵向排列,各自占据100%的宽度。这样,就完成了从PC端到手机端屏幕的响应式变化。
那么,像这样的一个响应式功能,bootstrap到底是如何实现的呢?结合上篇文章的知识,很容易知道,导航栏的响应式变化,必定是基于媒体查询和浮动布局的,问题是它怎么移动到下一行,那个toggle按钮又是如何出现在最右上角的?
原理分析
看了一下Bootstrap导航栏组件的应用代码,提取了关键部分截图如下:
看代码可知,toogle按钮本身就存在于html代码内,并非使用js代码动态添加上去的,但是在大屏幕时,是看不到这个按钮的,所以,这部分必然是使用了CSS的一个重要属性:display:none,实现了按钮的隐藏。那么,整体的实现原理就大概能猜出来了:
- 首先让“Brand”和“toggle按钮”布局在屏幕最上方,导航项布局在其下面。
- Brand浮动在最左边, toggle 浮动在最右边。隐藏 toggle 。
- 将导航项设置为浮动,每项宽度设置为能够并列显示在Brand和toogle之间的宽度。
- 根据媒体查询,当屏幕收缩到固定值时,显示 toggle ,同时隐藏导航项。
- 点击toggle时, 调整每个导航项的宽度为百分百,并显示导航项。
自定义响应式导航栏实现
基于此,在不使用bootstrap代码的情况下,我模拟了一份简单的实现代码(为了方便省略了toggle按钮的点击事件):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>自定义导航条</title>
<style type="text/css">
.link {
font-size: 24px;
background-color: #f5f3e8;
height: 50px;
line-height: 50px;
text-align: center;
float: left;
margin-right: 20px;
display: none;
}
.brand {
float: left;
margin-right: 20px;
font-size: 24px;
background-color: #6bf5dd;
height: 50px;
line-height: 50px;
}
.toggle {
font-size: 24px;
float: right;
background-color: #d1e9f5;
height: 50px;
line-height: 50px;
display: block;
}
.contain {
border: 1px solid #6bf5dd;
box-sizing: border-box;
overflow: hidden;
}
@media screen and (min-width: 768px) {
.link {
width: 10%;
display: block;
}
.toggle {
display: none;
}
}
</style>
<script type="text/javascript">
function changeNav() {
var links = document.getElementsByClassName('link');
for (var i = 0; i < links.length; i++) {
links[i].style.width='100%';
links[i].style.display='block';
}
}
</script>
</head>
<body>
<div class="contain">
<div class="brand">Brand</div>
<button class="toggle" onclick="changeNav()">toggle</button>
<div class="link">Link</div>
<div class="link">Link</div>
<div class="link">Link</div>
<div class="link">Link</div>
<div class="link">Link</div>
</div>
</body>
</html>
效果如下: