效果图
分析组成部分
1、10个li
标签,文字居中,后面的图片居中。停留时cursor=pointer
2、鼠标停留时,后面图标随之移动
3、鼠标移出时,图标回到第一个li
4、当其中的某个li
被点击时,就算停留在了其他li
,图标在移出后,依旧回到被点击的li
上
Body
<nav id="nav">
<span id="tmall"></span>
<ul>
<li>双十一狂欢</li>
<li>服装会场</li>
<li>数码家电</li>
<li>家居建材</li>
<li>母婴童装</li>
<li>手机会场</li>
<li>美妆会场</li>
<li>进口会场</li>
<li>飞猪旅行</li>
</ul>
</nav>
CSS
*{
margin: 0;
padding: 0;
border: 0;
list-style: none;
}
body{
background-color: pink;
}
#nav{
width: 900px;
height: 63px;
background:url("图片/12.jpg") no-repeat right center #fff;
background-size: 100px;
border-radius: 5px;
position: relative;
margin:100px auto;
}
#tmall{
width: 88px;
height: 56px;
background:url("图片/11.png") no-repeat center;
background-size:84px 50px ;
position: absolute;
}
#nav ul{
position: relative;
}
#nav ul li{
float: left;
width: 88px;
height: 63px;
text-align: center;
line-height: 63px;
cursor: pointer;
}
由于图标部分使用<span>
标签,所以在父盒子设置position
为relative
,在span
中用absolute
。使用定位也利于Js部分的操作。
JS
1、首先获取需要的标签nav
以及它的孩子
2、接下来需要遍历所有的li
标签,来事件监听。
i onmouseover
ii onmouseout
iii onmousedown
3、写好大致框架之后,就开始实现特效部分
4、由于每次事件触发时,图标的运动其实就是一个缓动动画的过程
缓动动画简述:
拥有起点和终点,且父级盒子有position属性为relative,本身为absolute
begin:开始位置
end:动画最后的结束位置
缓动系数公式:
begin+=(end-begin)*缓动系数;缓动系数取值一般为(0-1)
使用定时器:
每过一个时间间隔就更新一次begin的值,从而达到变化的效果。
同时在使用定时器时,不需要先清后设置。因为是要制作变速的效果
5、接下来就是完善事件监听的代码。
分析:
在每一次的over事件触发时,图标移动到当前li
的位置
意思就是:动画的终点位置,就是当前li
距离当前nav
的距离
在每一次down事件触发时,无论鼠标之后over在哪个li
,最终都会回到被点击后的li
意思就是:此时,动画的起点为当前被点击后的li
的位置
在每一次out事件触发时,图标回到起始位置
起始位置:没点击的时候:起始位置表示begin为0时。被点击了的:起始位置begin为被点击的li
的位置
window.onload = function () {
//1、获取需要的标签
var nav=$("nav");
var tmall=nav.children[0];
//console.log(tmall);
var ul=nav.children[1];
//console.log(ul);
var lis=ul.children;
var beginX=0;
for(let i=0;i<lis.length;i++)
{
lis[i].onmouseover = function () {
end = this.offsetLeft;
};
lis[i].onmousedown = function () {
beginX = this.offsetLeft;
};
lis[i].onmouseout = function () {
end=beginX;
}
}
var begin =0,end=0;
setInterval(function () {
begin+=(end-begin)*0.2;
tmall.style.left = begin+"px";
},10);
function $(id) {
return typeof id ==="string"?document.getElementById(id):null;
}
}
遇到的问题:
刚开始没想明白为什么在onmouseout
里面不直接写end=0
????
不是鼠标离开后要回到刚开始的位置吗????
后来才反应过来:
当没有li
被点击时,beginX
的值始终为0;
当有li
被点击了,beginX
的值已经变化为被点击处的位置。而下一次的回到起始位置,BeginX就应该是被点击处的位置;
所以我们在事件监听之前,设置变量BeginX
用beginX来接收被点击了的li的位置。
然后直接传这个值给OUT事件的end。
每次问题自己想通以后就觉得自己好sha哈哈哈哈哈,感觉怎么会连这个都没想到。