昨天在
淘宝UED网站上看到导航菜单很不错,于是自己动手写了一个。
效果如下:
顺便做了一种变体,实际上只是改变了CSS和一点HTML而已:
代码如下:
var
SlideNavi
=
Class.create({
initialize: function (naviItems,currentClassName,slider){
var self = this ;
this .naviItems = naviItems;
this .currentClassName = currentClassName;
this .slider = slider;
this .currentIndex = 0 ;
var currentTab = function (){
return self.naviItems[self.currentIndex];
}
this .timeInterval = new Object();
var getStep = function (target,current){
var step = (target - current) / 5;
if (Math.abs(step) < 1 && step != 0 ){
step = (target - current) > 0 ? 1 : - 1 ;
}
return Math.round(step);
}
var tabHover = function (item){
// 更改slider的位置和长短
clearInterval(self.timeInterval);
var initLeft = parseInt(self.slider.getStyle( " left " ));
var initRight = initLeft + self.slider.getWidth();
var targetLeft = parseInt(item.positionedOffset().left);
var targetRight = targetLeft + item.getWidth();
if (initLeft == targetLeft)
return ;
var leftToRight = true ;
if (initLeft > targetLeft)
leftToRight = false ;
if (leftToRight){
newTargetLeft = targetLeft + Math.round((targetLeft - initLeft) * 0.1 );
newTargetRight = targetRight + Math.round((targetRight - initRight) * 0.05 );
} else {
newTargetLeft = targetLeft + Math.round((targetLeft - initLeft) * 0.05 );
newTargetRight = targetRight + Math.round((targetRight - initRight) * 0.1 );
}
function slide(){
var stepLeft = getStep(newTargetLeft,initLeft);
var stepRight = getStep(newTargetRight,initRight);
if (stepLeft != 0 ){
initLeft += stepLeft;
}
if (stepRight != 0 ){
initRight += stepRight;
}
self.slider.setStyle({
left:initLeft + " px " ,
width:initRight - initLeft + " px "
});
if (stepLeft == 0 && stepRight == 0 ){
function moveBack(){
var newStepLeft = getStep(targetLeft,newTargetLeft);
var newStepRight = getStep(targetRight,newTargetRight);
if (newStepLeft != 0 ){
newTargetLeft += newStepLeft;
}
if (newStepRight != 0 ){
newTargetRight += newStepRight;
}
self.slider.setStyle({
left:newTargetLeft + " px " ,
width:newTargetRight - newTargetLeft + " px "
});
if (newStepLeft == 0 && newStepRight == 0 )
clearInterval(self.timeInterval);
}
clearInterval(self.timeInterval);
self.timeInterval = setInterval(moveBack, 10 );
}
}
self.timeInterval = setInterval(slide, 10 );
}
var changeTab = function (item){
if (item != currentTab()){
currentTab().removeClassName(self.currentClassName);
item.addClassName(self.currentClassName);
self.currentIndex = item.index;
}
tabHover(item);
}
var tabBack = function (event){
tabHover(currentTab());
}
changeTab(currentTab());
this .naviItems.each( function (item,index){
item.index = index;
item.observe( " mouseover " ,tabHover.bind(item,item));
item.observe( " mouseout " ,tabBack);
item.firstDescendant().observe( " click " ,changeTab.bind(item,item));
});
}
});
initialize: function (naviItems,currentClassName,slider){
var self = this ;
this .naviItems = naviItems;
this .currentClassName = currentClassName;
this .slider = slider;
this .currentIndex = 0 ;
var currentTab = function (){
return self.naviItems[self.currentIndex];
}
this .timeInterval = new Object();
var getStep = function (target,current){
var step = (target - current) / 5;
if (Math.abs(step) < 1 && step != 0 ){
step = (target - current) > 0 ? 1 : - 1 ;
}
return Math.round(step);
}
var tabHover = function (item){
// 更改slider的位置和长短
clearInterval(self.timeInterval);
var initLeft = parseInt(self.slider.getStyle( " left " ));
var initRight = initLeft + self.slider.getWidth();
var targetLeft = parseInt(item.positionedOffset().left);
var targetRight = targetLeft + item.getWidth();
if (initLeft == targetLeft)
return ;
var leftToRight = true ;
if (initLeft > targetLeft)
leftToRight = false ;
if (leftToRight){
newTargetLeft = targetLeft + Math.round((targetLeft - initLeft) * 0.1 );
newTargetRight = targetRight + Math.round((targetRight - initRight) * 0.05 );
} else {
newTargetLeft = targetLeft + Math.round((targetLeft - initLeft) * 0.05 );
newTargetRight = targetRight + Math.round((targetRight - initRight) * 0.1 );
}
function slide(){
var stepLeft = getStep(newTargetLeft,initLeft);
var stepRight = getStep(newTargetRight,initRight);
if (stepLeft != 0 ){
initLeft += stepLeft;
}
if (stepRight != 0 ){
initRight += stepRight;
}
self.slider.setStyle({
left:initLeft + " px " ,
width:initRight - initLeft + " px "
});
if (stepLeft == 0 && stepRight == 0 ){
function moveBack(){
var newStepLeft = getStep(targetLeft,newTargetLeft);
var newStepRight = getStep(targetRight,newTargetRight);
if (newStepLeft != 0 ){
newTargetLeft += newStepLeft;
}
if (newStepRight != 0 ){
newTargetRight += newStepRight;
}
self.slider.setStyle({
left:newTargetLeft + " px " ,
width:newTargetRight - newTargetLeft + " px "
});
if (newStepLeft == 0 && newStepRight == 0 )
clearInterval(self.timeInterval);
}
clearInterval(self.timeInterval);
self.timeInterval = setInterval(moveBack, 10 );
}
}
self.timeInterval = setInterval(slide, 10 );
}
var changeTab = function (item){
if (item != currentTab()){
currentTab().removeClassName(self.currentClassName);
item.addClassName(self.currentClassName);
self.currentIndex = item.index;
}
tabHover(item);
}
var tabBack = function (event){
tabHover(currentTab());
}
changeTab(currentTab());
this .naviItems.each( function (item,index){
item.index = index;
item.observe( " mouseover " ,tabHover.bind(item,item));
item.observe( " mouseout " ,tabBack);
item.firstDescendant().observe( " click " ,changeTab.bind(item,item));
});
}
});
基本原理还是很简单,看代码就能明白,但是为了达到缓冲效果还是有一点麻烦,首先要判断slider向左还是向右滑动,根据不同的方向来决定slider的left和width属性,然后还要往回移动,这个就需要再用一次setInterval就可以达到效果。出于学习,我还是使用了prototype1.6。
分类:
Javascript
本文转自快乐就好博客园博客,原文链接:http://www.cnblogs.com/happyday56/archive/2009/06/25/1510798.html,如需转载请自行联系原作者