原生JS实现可折叠导航栏

实现效果

在这里插入图片描述

制作过程

首先页面分为两个div,一个导航一个内容。其中内容中需要一个按钮用来控制折叠。


<div class="left-nav"></div>
<div class="cont">
	<button>按钮</button>
</div>

加入样式

.left-nav{
	width:280px;
	height:1000px;
	background:#343A40;
	position: fixed;
	left:0;
	top:0;
	color:rgba(255,255,255,.7);
	font-size: 1.0rem;
	overflow: hidden;
	z-index: 2;
	white-space:nowrap;
}
.cont{
	width:auto;
	margin-left:280px;
	min-width: 1050px;
}

折叠效果是通过触发事件后,循环改变nav的宽度和cont的左边距实现cont盖住nav的视觉效果。但在代码中,并不能真的用for循环来做,那样在移动过程中js就会一直卡在循环中而不能执行其他代码,所以这里可以使用setInterval函数来做,它会每隔一段时间调用一次某个方法,格式为setInterval(调用函数,调用间隔时间,调用函数参数1,参数2,…);当任务完成时再通过clearInterval函数结束循环调用。
为了使移动更平滑,每次调用时只移动到目标位置之间的距离的10%.实现折叠的函数代码如下:

/*关闭/打开导航*/
function closeNav(nav,body,navTargetWidth){
	var thisTarget = nav.getBoundingClientRect().width + (navTargetWidth - nav.getBoundingClientRect().width)*0.1;	//这次目标宽度
	nav.style.width = (Math.abs(thisTarget-navTargetWidth)<0.5?navTargetWidth:thisTarget) + "px";
	body.style.marginLeft = nav.style.width;
	if(nav.getBoundingClientRect().width == navTargetWidth){
		clearInterval(CWLN);
	}
}

调用时机为触发指定事件时调用,这里事件分为,点击按钮,鼠标进入导航栏,鼠标移出导航栏三种。
当点击按钮后,判断当前导航栏是收缩还是展开状态,如果是收缩状态就将导航栏的宽和内容块的左外边距逐渐增长为展开时的值,反之同理。而判断是通过一个变量来标识导航栏状态实现。

var leftNavIsClose = false;
var leftNav = document.getElementsByClassName("left-nav")[0];
var body = document.getElementsByClassName("body")[0];
var minWidth_leftNav = 60;
var maxWidth_leftNav = 280;
CWLN = null;
document.getElementById("close-left-nav").onclick = function(){
	if(leftNavIsClose)
		CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
	else
		CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
	leftNavIsClose = !leftNavIsClose;
}

当鼠标进入和离开导航栏时:

document.getElementsByClassName("left-nav")[0].onmouseenter = function(){
	clearInterval(CWLN);
	CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
}
document.getElementsByClassName("left-nav")[0].onmouseleave = function(){
	if(leftNavIsClose){
		clearInterval(CWLN);
		CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
	}
}

效果
在这里插入图片描述

完整源码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style>
			.left-nav{
				width:280px;
				height:1000px;
				background:#343A40;
				position: fixed;
				left:0;
				top:0;
				color:rgba(255,255,255,.7);
				font-size: 1.0rem;
				overflow: hidden;
				z-index: 2;
			}
			.body{
				width:auto;
				margin-left:280px;
				min-width: 1050px;
			}
		</style>
	</head>
	<body>
		<div class="left-nav">导航&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;导航导航</div>
		<div class="body">
			<button id="close-left-nav">按钮</button><br/>
			内容内容内容
		</div>
	</body>
	<script>
		/*关闭/打开导航*/
		function closeNav(nav,body,navTargetWidth){
			var thisTarget = nav.getBoundingClientRect().width + (navTargetWidth - nav.getBoundingClientRect().width)*0.1;	//这次目标宽度
			nav.style.width = (Math.abs(thisTarget-navTargetWidth)<0.5?navTargetWidth:thisTarget) + "px";
			body.style.marginLeft = nav.style.width;
			if(nav.getBoundingClientRect().width == navTargetWidth){
				clearInterval(CWLN);
			}
		}
		var leftNavIsClose = false;
		var leftNav = document.getElementsByClassName("left-nav")[0];
		var body = document.getElementsByClassName("body")[0];
		var minWidth_leftNav = 60;
		var maxWidth_leftNav = 280;
		CWLN = null;
		document.getElementById("close-left-nav").onclick = function(){
			if(leftNavIsClose)
				CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
			else
				CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
			leftNavIsClose = !leftNavIsClose;
		}
		document.getElementsByClassName("left-nav")[0].onmouseenter = function(){
			clearInterval(CWLN);
			CWLN = setInterval(closeNav,10,leftNav,body,maxWidth_leftNav);
		}
		document.getElementsByClassName("left-nav")[0].onmouseleave = function(){
			if(leftNavIsClose){
				clearInterval(CWLN);
				CWLN = setInterval(closeNav,10,leftNav,body,minWidth_leftNav);
			}
		}
	</script>
</html>
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值