javascript底部具有跟随效果的横向导航菜单

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

本章节分享一段代码实例,它实现了底部具有跟随效果的导航菜单功能。

下面就给出代码,并且详细介绍一下它的实现过程。

代码实例如下:

<!DOCTYPE html>
<html>
<head>
<meta charset=" utf-8">
<meta name="author" content="http://www.pipipi.net/" />
<title>前端教程网</title>
<style type="text/css">
*{
  margin:0;
  padding:0;
}
body {
  font:12px "B8BF53",san-serif;
  color:#808080;
  padding-top:6px;
}
a {
  text-decoration:none;
  color:#808080
}
a:hover {
  text-decoration:underline;
  color:#ba2636
}
ul, li { list-style:none; }
#nav{
  padding:41px 0 0 0;
  height:27px;
  width:542px;
  overflow:hidden;
  float:right;
  margin-right:17px;
  position:relative;
}
#nav ul{
  height:27px;
  width:100%;
}
#nav ul li{
  width:67px;
  height:24px;
  float:left;
  padding-right:28px;
  display:inline;
  cursor:pointer;
  overflow:hidden
}
#nav a{
  background:#999;
  width:100%;
  height:24px;
  display:block;
  float:left;
  outline:none;
  color:#fff;
  line-height:24px;
  text-align:center;
  font-size:16px;
  font-weight:bold;
  overflow:hidden
}
#navCur{
  position:absolute;
  left:0;
  bottom:0;
  height:3px;
  color:#F00;
  width:67px;
  margin:0;
  padding:0;
  display:block;
  float:none;
  background:#FF0000;
  cursor:pointer;
  overflow:hidden
}
</style>
 <script type="text/javascript">
var done=function(){
  var curPostion,thisLeft, curPostion_1;
  var obj = getId('nav').getElementsByTagName('ul')[0],
      timer = null ,
      navCur = getId('navCur'),
      liArr = getId('nav').getElementsByTagName('li'),
      liLength = liArr.length-1;
  for (var x=0;x<liArr.length; x++ ){
    liArr[liLength].style.paddingRight = "0";
    var li = liArr[x],curPostion = navCur.offsetLeft;
    if(li.className == "cur"){
      navCur.style.left = li.offsetLeft + "px";
    }
    li.onmouseover=function(){
      clearTimeout(timer);
      thisLeft = this.offsetLeft;
      if (thisLeft > navCur.offsetLeft) {
        hover();
      }
      else {
        curPostion_1 = this.offsetLeft;
        out();
      }
    };
    li.onmouseout=function(){
      clearTimeout(timer);
      if (curPostion < navCur.offsetLeft) {
        curPostion_1 = curPostion;
        out();
      }
      else {
        thisLeft = curPostion;
        hover();
      }
    };
  }
  function hover(){
    if (navCur.offsetLeft <= thisLeft) {
      var a = Math.max(parseInt((thisLeft - navCur.offsetLeft) / 15), 3);
      navCur.style.left = navCur.offsetLeft + a + "px";
      timer = setTimeout(arguments.callee, 5);
    }
    else{
      navCur.style.left = thisLeft + "px";
      clearTimeout(timer);
    }
  }
  function out(){
    if (navCur.offsetLeft >= curPostion_1) {
      var a = Math.max(parseInt((navCur.offsetLeft - curPostion_1) / 15), 3);
      navCur.style.left = navCur.offsetLeft - a + "px";
      timer = setTimeout(arguments.callee, 5);
    }
    else {
      navCur.style.left = curPostion_1 + "px";
      clearTimeout(timer);
    }
  }
  function getId(id){
    return document.getElementById(id)
  }
}
window.onload=function(){
  done();
}
</script>
</head>
<body>
<div id="nav">
  <ul class="cf">
    <li><a href="" hidefocus="true">1</a></li>
    <li><a href="1" hidefocus="true">2</a></li>
    <li class="cur"><a href="2" hidefocus="true">3</a></li>
    <li><a href="3" hidefocus="true">4</a></li>
    <li><a href="4" hidefocus="true">5</a></li>
    <li><a href="5" hidefocus="true">6</a></li>
  </ul>
  <span id="navCur"></span>
</div>
</body>
</html>

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

一.代码注释:

(1).var done=function(){},此函数实现了跟随效果。

(2).var curPostion,thisLeft, curPostion_1,生命了三个变量,是用来存储元素的offsetLeft属性值,后面会用到。

(3).var obj = getId('nav').getElementsByTagName('ul')[0],getId()模拟实现了类似于jQuery的id选择器功能。这段代码是获取ul元素集合中的第一个ul元素,当然在此例中只有一个ul元素。

(4).timer = null,声明一个变量并赋值为null,用作定时器函数的标识。

(5).navCur = getId('navCur'),获取id属性值为navCur的元素对象。

(6).liArr = getId('nav').getElementsByTagName('li'),获取指定ul元素下的li元素集合。

(7).liLength = liArr.length-1,获取li元素集合最大索引值,因为索引是从0开始计算的。

(8).for (var x=0;x<liArr.length; x++ ){},遍历集合中的每一个元素。

(9).liArr[liLength].style.paddingRight = "0",设置最后一个li元素的右内边距是0,否则的话最后一个li会掉到第二行。

(10).var li = liArr[x],curPostion = navCur.offsetLeft,第一个赋值语句是将当前li元素对象赋值给变量li,第二个是将navCur对象(底部跟随元素)的offsetLeft属性值赋值给变量curPostion。

(11).if(li.className == "cur"){

  navCur.style.left = li.offsetLeft + "px";

},如果当前li元素的class属性值是cur,那么就将跟随条的left属性值设置为当前li元素的offsetLeft值,也就是将跟随条设置在此li元素的下面。

(12).li.onmouseover=function(){},为当前li元素注册onmouseover事件处理函数。

(13).clearTimeout(timer),停止当前定时器函数的执行,这一点很重要,如果连续两次快速移动到同一个导航栏目上,如果不停止前一个定时器函数的执行,难么就会造成两个定时器函数重合执行的情况。

(14).thisLeft = this.offsetLeft,将当前的元素的offsetLeft值赋值给变量thisLeft。

(15).if (thisLeft > navCur.offsetLeft) {

  hover();

},如果当前的元素的offsetLeft大于跟随元素的offsetLeft值,也就是跟随条在当前li元素的左边,那么就调用hover()。

(16).else {

  curPostion_1 = this.offsetLeft;

  out();

},如果不大于的话,就将当前元素的offsetLeft赋值给变量curPostion_1,然后调用out()函数。

(17).function hover(){},此函数实现了跟随条从左侧弹性跟随到当前li元素底部。

(18).if (navCur.offsetLeft <= thisLeft) {

  var a = Math.max(parseInt((thisLeft - navCur.offsetLeft) / 15), 3);

  navCur.style.left = navCur.offsetLeft + a + "px";

  timer = setTimeout(arguments.callee, 5);

},如果当前跟随元素的offsetLeft属性值小于当前li元素的offsetLeft属性值。

那么就通过var a = Math.max(parseInt((thisLeft - navCur.offsetLeft) / 15), 3)获取跟随条每次移动的幅度,因为跟随条的navCur.offsetLeft值会越来越大,那么差就越来越小,就出现了弹性运动效果。

timer = setTimeout(arguments.callee, 5),通过递归的方式不断执行hover()方法。

(19).else{

  navCur.style.left = thisLeft + "px";

  clearTimeout(timer);

},否则,将跟随元素的left属性值设置为li元素的thisLeft值,这样就完成跟随效果。

最后停止定时器函数的执行。

二.相关阅读:

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

(2).offsetLeft属性可以参阅js offsetLeft一章节。

(3).className属性可以参阅js className一章节。

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

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

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

回复

我来回复
  • 暂无回复内容