前些天浏览Q空间,发现一些图片下标有个长图的标签,于是忍不住把鼠标放上去,此时看到图片往上滚动起来。当鼠标再次移入时,如果鼠标在图片上半部分,则图片往上滚动。反之鼠标在图片下半部分,则图片往下滚动。越来越觉得腾讯的UE做的不错。好吧,说太多没用,直接上效果图(不过图片录的效果有点卡):

那么此种效果是如何实现,最初的我以为它是用纯js实现的。可是发现在低版本的浏览器下,鼠标放置图片区域,却没有图片滚动的效果。于是,查看代码及实现原理,发现它是用css的 transition 属性来完成的。

关键点:

  1. 鼠标移入时,利用css3方法来改变图片的margin-top值以达到图片滚动的效果。

  2. 通过鼠标在图片的位置,来判断图片是向下还是向上滚动。 (clientY, offsetTop)

  3. 使用 transition : marginTop duration linear . 这个css3方法。这里 duration 是指在在一定时间内完成动画效果,因为marginTop值的不断变化(减小),因此要做到图片匀速运动,则需要 duration 是个动态的值。

  4. 需要判断用户是否为第一次移入图片,如果是,则图片默认往上滚动,如果不是,则通过鼠标位置来判断图片上滚或者下滚。

实例代码如下:

<style>
#img_box{display:block;width:335px;height:400px;overflow:hidden;margin:0 auto;}
</style>

<a id="img_box">
<img src="qlove.jpg">
</a>

<script>
function $(selector){
var aResult=[],aEle=document.getElementsByTagName("*");
if(document.querySelectorAll){
aResult=document.querySelectorAll(selector);
}
else{
for(var i=0,len=aEle.length;i<len;i++){
if(aEle[i].className===selector.replace(".","")||aEle[i].id===selector.replace("#","")){
aResult.push(aEle[i]);
}
}
}
return aResult;
}
(function(){
var oImgBox=$("#img_box")[0],oImg=oImgBox.getElementsByTagName("img")[0],iMarginTop=0,oTxt=$("#txt")[0],bFirst=true,bM=false;

function getStyle(obj,attr){
return obj.currentStyle?obj.currentStyle[attr]:getComputedStyle(obj,false)[attr];
}

oImgBox.onmouseover=oImgBox.onmousemove=function(ev){
var e=ev||event,
mouseY=e.clientY,
iH=oImgBox.offsetHeight,
iTop=oImgBox.offsetTop,
duration=10; //定义初始周期

if(bFirst){ //判断是否第一次移入,如果是,则默认往下滚
move(oImg.offsetHeight-iH);
if(mouseY>iTop+iH/2&&mouseY<iTop+iH){
bFirst=false;
}
}

else{
if(mouseY>iTop&&mouseY<iTop+iH/2){
move(oImg.offsetHeight-iH);
}
else if(mouseY>iTop+iH/2&&mouseY<iTop+iH){
move(0);
}
}

function move(iTarget){
duration=Math.abs((-(iTarget)-parseInt(iMarginTop))*0.01);
oImg.style.marginTop=-iTarget+"px";
oImg.style.transition="margin-top "+duration+"s linear";
oImg.style.MozTransition="margin-top "+duration+"s linear";
timer=setInterval(function(){
iMarginTop=getStyle(oImg,"marginTop");
},30)
}
}

oImgBox.onmouseout=function(){
oImg.style.marginTop=iMarginTop;
bFirst=false;
}
})()
</script>