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()一章节。