仿淘宝UED导航菜单
昨天在淘宝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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架