js鼠标悬浮水平弹性伸缩的导航菜单

快乐打工仔 分类:实例代码

本章节分享一段代码实例,它实现了鼠标悬浮导航水平伸缩的功能。

下面就给出代码,并进行详细的分析,代码实例如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.pipipi.net/" />
<title>前端教程网</title>
<style>
*{
  margin:0px;
  padding:0px;
}
body{
  background:#fff;
}
.naver{
  list-style-type:none;
  width:700px;
  overflow:hidden;
  margin:100px auto 0;
}
.naver li{
  width:100px;
  height:50px;
  overflow:hidden;
  font-size:16px;
  text-align:center;
  cursor:pointer;
}
.naver li a,.naver li a:hover{
  display: block;
  width:100px;
  height:50px;
  line-height:50px;
  color:#FFF;
  text-decoration:none;
}
.co1{background:#649e37}
.co2{background:#028fbc}
</style>
<script type="text/javascript">
window.onload = function() {
  var oUl = document.getElementById("nav");
  var aLi = oUl.getElementsByTagName("li");
  var index = 0;
  for (index = 0; index < aLi.length; index++) {
    aLi[index].timer = null;
    aLi[index].speed = 0;
    aLi[index].onmouseover = function() {
      startMove(this, 250);
    };
    aLi[index].onmouseout = function() {
      startMove2(this, 100);
    };
  }
};
function startMove(obj, iTarget) {
  if (obj.timer) {
    clearInterval(obj.timer);
  }
  obj.timer = setInterval(function() {
    doMove(obj, iTarget);
  }, 30)
};
function doMove(obj, iTarget) {
  obj.speed += 3;
  if (Math.abs(iTarget - obj.offsetWidth) < 1 && Math.abs(obj.speed) < 1) {
    clearInterval(obj.timer);
    obj.timer = null;
  }
  else {
    if (obj.offsetWidth + obj.speed >= iTarget) {
      obj.speed *= -0.7;
      obj.style.width = iTarget + "px";
    }
    else {
      obj.style.width = obj.offsetWidth + obj.speed + "px";
    }
  }
};
function startMove2(obj, iTarget) {
  if (obj.timer) {
    clearInterval(obj.timer);
  }
  obj.timer = setInterval(function() {
    doMove2(obj, iTarget);
  }, 30)
};
function doMove2(obj, iTarget) {
  obj.speed -= 3;
  if (Math.abs(iTarget - obj.offsetWidth) < 1 && Math.abs(obj.speed) < 1) {
    clearInterval(obj.timer);
    obj.timer = null;
  }
  else {
    if (obj.offsetWidth + obj.speed <= iTarget) {
      obj.speed *= -0.7;
      obj.style.width = iTarget + "px";
    }
    else {
      obj.style.width = obj.offsetWidth + obj.speed + "px";
    }
  }
};
</script>
</head>
<body>
<ul id="nav" class="naver">
  <li class="co1"><a href="#">前端教程网一</a></li>
  <li class="co2"><a href="#">前端教程网二</a></li>
  <li class="co1"><a href="#">前端教程网三</a></li>
  <li class="co2"><a href="#">前端教程网四</a></li>
  <li class="co1"><a href="#">前端教程网五</a></li>
</ul>
</body>
</html>

上面的代码实现了我们的要求,下面介绍一下它的实现过程。

一.代码注释:

(1).window.onload = function() {},当文档内容完全加载完毕再去执行函数中的代码。

(2).var oUl = document.getElementById("nav"),获取id属性值为nav的元素对象。

(3).var aLi = oUl.getElementsByTagName("li"),获取oUl下的li元素集合。

(4).var index = 0,生命一个变量病赋初值为0,在for循环中使用。

(5).for (index = 0; index < aLi.length; index++){},遍历li元素集合中的每一个元素。

(6).aLi[index].timer = null,为当前的li元素对象添加一个timer属性并赋初值为null,用作定时器函数的标识。

(7).aLi[index].speed = 0,初始化元素的伸缩速度。

(8).aLi[index].onmouseover = function() {

  startMove(this, 250);

},为当前li元素注册onmouseover事件处理函数。

当鼠标悬浮的时候就会执行此函数,然后调用startMove()函数,第一个参数this就是当前li元素,第二个参数是元素伸展的最大宽度。

(9).aLi[index].onmouseout = function() {

  startMove2(this, 100);

}为当前li元素注册onmouseout事件处理函数。

当鼠标悬浮的时候就会执行此函数,然后调用startMove2()函数,第一个参数this就是当前li元素,第二个参数是元素收缩的最小宽度。

(10).function startMove(obj, iTarget) {

  if (obj.timer) {

    clearInterval(obj.timer);

  }

  obj.timer = setInterval(function() {

    doMove(obj, iTarget);

  }, 30)

},此函数实现了li元素的伸展或者收缩效果,第一个参数是一个元素对象,第二个参数是目标尺寸。

首先判断当前有定时器函数的执行,如果有,那么就停止当前定时器函数的执行,否则就会出现多个定时器函数重叠执行的情况。

最后,开始一个新的定时器函数的执行。

(11).function doMove(obj, iTarget) {},此方法实现了具有弹性效果的伸展运动,第一个参数是元素对象,第二个参数是目标值。

(12).obj.speed += 3,每一次执行,速度值就会加3。

(13).if (Math.abs( iTarget - obj.offsetWidth)< 1 && Math.abs(obj.speed) < 1) {

  clearInterval(obj.timer);

  obj.timer = null;

},如果当前的目标值减去元素当前的宽度值小于1,并且速度的值小于1

那么就停止定时器函数的执行,也就是伸展任务完成。

(14).else {

  if (obj.offsetWidth + obj.speed >= iTarget) {

    obj.speed *= -0.7;

    obj.style.width = iTarget + "px";

  }

  else {

    obj.style.width = obj.offsetWidth + obj.speed + "px";

  }

},如果不满足上一步骤的条件,那么进行如下判断:

如果当前宽度加上当前速度大于目标宽度的话,就将速度转换为负数,并乘以0.7(不能直接乘以-1,否则的话li元素宽度又会回到原来的尺寸).最后将元素的宽度直接设置为目标尺寸。

如果上面的条件也不满足的话,就在原来宽度基础上加上当前的速度,由于速度是累积的,所以速度会越来越快。

第13和14步实现了弹性效果,虽然代码介绍完毕,不少朋友可能还没有明白会什么会有弹性效果,下面做一下说明:

当开始运动的时候,元素宽度会越来越快的进行伸展。

到达一个临界点(当前的宽度加上当前速度要大于等于目标尺寸)之后,元素宽度里面设置为目标宽度,这时候速度也变成了负数,但是由于是乘以-0.7,所以元素的宽度在弹性变化的时候就不能够收缩到最初的尺寸,于是当元素再次伸展到目标尺寸的时候,速度就比上一次要小,因为执行obj.speed += 3的次数少了。如此往复(往复也就实现了弹性效果)最终会满足13部的判断条件。

二.相关阅读:

(1).getElementsByTagName()可以参阅document.getElementsByTagName()一章节。

(2).onmouseover事件可以参阅javascript mouseover事件一章节。

(3).onmouseout事件可以参阅javascript mouseout事件一章节。

(4).setInterval()可以参阅setInterval()一章节。

(5).Math.abs()可以参阅javascript Math.abs()一章节。

(6).offsetWidth可以参阅js offsetWidth一章节。

回复

我来回复
  • 暂无回复内容