自适应导航条js原生版
看到bootstrap等第三方库中的导航条非常简单好用,没想到自己用原生试着实现用了这么多行代码😳
效果如下:
实现思路:
html+css:
- 最外层nav宽度100%。高给固定值
- 中间内容部分全部用一个div包裹,宽度百分比,margin: 0 auto; 实现居中
- 左侧的logo图片外包div,给的固定宽高
- 中间的navbar包裹ul列表用的百分比宽度,使其宽度能够在屏幕缩放的时候随之变化
- 右侧按钮部分隐藏
- 媒体查询屏幕宽度<768px时,将navbar定位至nav下方,高度给0,并将按钮显示
js:
- 用布尔值作为开关控制点击状态
- 先设置bol = true,让判断走if语句
- 点击一次后,定时器执行navbar和nav的高度增大至预设值,关闭定时器
- 定时器后将bol改为false,这样下次点击就会执行else中语句
- else中定时器控制nav及navbar高度减小至预设值,关闭定时器
- 定时器后将bol再改为true,这样下次点击就会执行if中语句
遇到的坑:
遇到的比较棘手的问题就是开关状态、点击事件、定时器到底该如何嵌套,不过最后还是把思路理清楚了
- 先用布尔值判定是走if语句(高度+)还是else语句(高度-)
- 再到点击按钮
- 点击按钮后再触发定时器
- 高度变化至设定值时关闭定时器,及改变布尔值
还有个问题就是因为navbar定位之后失去了撑开下方区块的功能,最后只能将父级nav的高度同步增大,不知道是不是有点绕了
上代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自适应导航栏</title>
<style>
/*简单清除默认样式*/
* {
margin: 0;
padding: 0;
}
/*导航宽屏时主体部分*/
nav {
width: 100%;
height: 50px;
background-color: #444;
overflow: hidden;
min-width: 320px;
}
.nav {
max-width: 80%;
margin: 0 auto;
height: 50px;
}
.logo {
width: 50px;
height: 50px;
float: left;
}
.logo img {
width: 100%;
display: block;
}
.navbar {
width: 80%;
height: 50px;
float: right;
}
.navbar ul {
list-style: none;
height: 50px;
overflow: hidden;
float: right;
}
.navbar li {
height: 50px;
float: left;
padding: 0 10px;
}
.navbar a {
display: block;
width: 100%;
height: 50px;
line-height: 50px;
text-decoration: none;
text-align: center;
color: #fff;
font-size: 16px;
font-weight: bold;
}
/*媒体查询屏幕宽度小于768px时生效以下效果*/
@media screen and (max-width: 768px) {
/*
1、navbar定位到nav下方,宽度撑满屏幕
2、高度给成0
3、超出部分不显示
4、其他样式相应调整
*/
.navbar {
float: right;
position: absolute;
top: 50px;
left: 0;
width: 100%;
height: 0px;
background-color: #444;
overflow: hidden;
}
.navbar ul {
width: 100%;
height: 200px;
}
.navbar li {
width: 80%;
margin: 0 auto;
float: none;
}
.navbar a { text-align: left; }
}
/*按钮部分,宽屏时是隐藏的*/
.btn {
border: 0;
border-radius: 5px;
margin-top: 5px;
width: 40px;
height: 40px;
background-color: #aaa;
float: right;
display: none;
opacity: 0.8;
transition: all 0.5s;
cursor: pointer;
}
.btn:hover { opacity: 1; }
.btn span {
display: block;
width: 60%;
height: 5px;
border-radius: 5px;
margin: 6px 20%;
background-color: #fff;
}
/*媒体查询屏幕宽度小于768px时,按钮出现*/
@media screen and (max-width: 768px) {
.btn { display: block; }
}
/*内容部分*/
.content{
width: 100%;
height: 500px;
background-color: #ddd;
/*overflow: hidden;*/
}
.content h2{
width: 80%;
margin: 0 auto;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 60px;
color: #fff;
padding-top: 50px;
}
@media screen and (max-width: 768px) {
.content h2{
font-size: 40px;
}
}
</style>
</head>
<body>
<nav>
<div class="nav">
<div class="logo">[站外图片上传中……(5)]</div>
<div id="btn" class="btn">
<span></span>
<span></span>
<span></span>
</div>
<div id="navbar" class="navbar">
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">公司简介</a></li>
<li><a href="#">产品介绍</a></li>
<li><a href="#">联系方式</a></li>
</ul>
</div>
</div>
</nav>
<div id="content" class="content">
<h2>这是下方内容</h2>
</div>
</body>
<script>
//获取节点
var btn = document.getElementById('btn');
var navbar = document.getElementById('navbar');
var nav = document.getElementsByTagName('nav')[0];
//设置布尔值作为开关
var bol = true;
//设置定时器
var timer = null;
//设定navbar(就是会移到下方的部分)
var t = navbar.offsetHeight;
var maxH = 200;
var minH = 0;
//设定nav(就是最外面的父级)
//因为navbar已经定位,所以他无法将下方内容顶开,所以需要同时变更父级的高度来顶开下方内容
var navT = nav.offsetHeight;
var navMaxH = 250;
var navMinH = 50;
btn.onclick = function () {
// 判定布尔值
if (bol){
navbar.style.borderTop = "1px solid #fff";
timer = setInterval(function () {
t+=10;
navT+=10;
//父级nav上限
if (navT>=navMaxH){
navT = navMaxH;
}
// navbar上限
if (t>=maxH){
t = maxH;
navT = navMaxH;
clearInterval(timer);
}
navbar.style.height = t + 'px';
nav.style.height = navT + 'px';
}, 10)
//布尔值改为false,下次点击时,就会执行else中的语句
bol = false;
}else{
navbar.style.borderTop = "0";
timer = setInterval(function () {
t-=10;
navT-=10;
//父级nav下限
if (navT<=navMinH){
navT = navMinH;
}
//navbar下限
if (t<=minH){
t = minH;
navT = navMinH;
clearInterval(timer);
}
navbar.style.height = t + 'px';
nav.style.height = navT + 'px';
}, 10)
//布尔值改为true,下次点击时,就会执行if中的语句
bol = true;
}
}
</script>
</html>
网友评论