给大家分享一个由原生JS实现的苹果官网产品展示特效,看起来很不错,效果如下:
以下是代码实现,欢迎大家复制粘贴。
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>苹果官网产品展示特效</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
body {
background: #EBEBED;
_position: relative;
_height: 100%;
}
img {
border: none;
display: block;
}
li {
list-style: none;
}
.page {
-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 1px 3px;
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 1px 3px;
box-shadow: rgba(0, 0, 0, 0.3) 0 1px 3px;
background: #FFFFFF;
border-color: #E5E5E5 #DBDBDB #D2D2D2;
border-style: solid;
border-width: 1px;
margin: 5px auto 0;
width: 980px;
}
.miaov_box {
overflow: hidden;
position: relative;
width: 820px;
z-index: 0;
height: 158px;
margin: 0 70px;
}
.miaov_box_head {
width: 1680px;
}
.miaov_box_head li {
width: 140px;
float: left;
text-align: center;
}
a {
text-decoration: none;
font: 12px/18px "Lucida Grande",
"Lucida Sans Unicode",
Helvetica,
Arial,
Verdana,
sans-serif;
color: #7F7F7F;
}
.miaov_box_head li a:hover {
color: #333;
}
.miaov_box_foot {
height: 30px;
text-align: center;
background: #fff;
overflow: hidden;
background: -moz-linear-gradient(center bottom,
rgba(223, 223, 223, 1) 0%,
rgba(242, 242, 242, 1) 66%,
rgba(242, 242, 242, 1) 90%,
rgba(230, 230, 230, 1) 93%,
rgba(190, 190, 190, 1) 96%,
rgba(150, 150, 150, 1) 100%);
background: -webkit-gradient(linear,
left bottom,
left top,
from(rgba(223, 223, 223, 1)),
color-stop(66%, rgba(242, 242, 242, 1)),
color-stop(90%, rgba(242, 242, 242, 1)),
color-stop(93%, rgba(230, 230, 230, 1)),
color-stop(96%, rgba(210, 210, 210, 1)),
to(rgba(140, 140, 140, 1)));
border-bottom: 1px solid #ebebeb;
position: relative;
}
.caret {
/* 三角形标签 */
background: url(images/13.gif) no-repeat scroll 0 0;
display: block;
height: 8px;
margin: 0 0 -8px -7px;
position: absolute;
width: 15px;
}
.miaov_box_foot a {
display: inline-block;
margin: 0 15px;
padding: 8px 0 6px;
cursor: pointer;
text-shadow: 0 1px 0 #FFFFFF;
}
.miaov_box_foot .show {
cursor: default;
color: #2B2B2B;
}
.miaov_box_foot a:hover {
color: #000;
}
.miaov {
height: 36px;
line-height: 26px;
text-align: center;
position: fixed;
_position: absolute;
bottom: 0;
width: 100%;
}
.miaov a {
color: #777;
font-size: 16px;
}
.miaov a:hover {
color: #555;
}
.miaov_head {
height: 36px;
width: 980px;
overflow: hidden;
margin: 0 auto;
}
.miaov_head .left {
float: left;
}
.miaov_head .right {
float: right;
}
.miaov_head a {
line-height: 36px;
color: #777;
}
.miaov_head a:hover {
color: #555;
}
</style>
<script type="text/javascript" src="js/move.js"></script>
<script type="text/javascript">
//封装函数通过class去选取元素(由于IE8以下对getElementsByClassName不支持)
function getByClass(oParent, sClass) {
//选取父对象下所有的元素
var aEle = oParent.getElementsByTagName('*');
//声明空结果数组
var aResult = [];
var i = 0;
//遍历选择的所有元素
for (i = 0; i < aEle.length; i ) {
//如果当前元素的className等于传入的sClass
if (aEle[i].className == sClass) {
//将其压入结果数组中
aResult.push(aEle[i]);
}
}
//返回结果
return aResult;
}
window.onload = function () {
//获取id为div1的对象
var oDiv = document.getElementById('div1');
//通过getByClass选取class为miaov_box_head的数组,取数组中的第1个,选取下面的li
var aLi = getByClass(oDiv, 'miaov_box_head')[0].getElementsByTagName('li');
//通过getByClass选取class为miaov_box_foot的数组,取数组中的第1个,选取下面的a
var aBtn = getByClass(oDiv, 'miaov_box_foot')[0].getElementsByTagName('a');
//通过getByClass选取class为caret'的数组,取数组中的第1个
var oCaret = getByClass(oDiv, 'caret')[0];
//存储第一个li的left值
var aPos = [];
var timer = null;
var i = 0;
//循环遍历li
for (i = 0; i < aLi.length; i ) {
aLi[i].index = i;
//存储每个li的left值
aPos[i] = aLi[i].offsetLeft;
}
//循环遍历li
for (i = 0; i < aLi.length; i ) {
//将每一个li的定位改成绝对定位
aLi[i].style.position = 'absolute';
//重新给每一个li赋值left
aLi[i].style.left = aPos[i] 'px';
}
//为内容为Products添加点击事件(所有li向右)
aBtn[0].onclick = function () {
//i等于最后一张图片
var i = aLi.length - 1;
//清除定时器,防止多次点击造成重叠
clearTimeout(timer);
//后一半向右出去
function next() {
var obj = aLi[i];
//如果i为所有li的后一半
if (i >= aLi.length / 2) {
//调用插件里的miaoStartMove函数让li向左弹性运动900px
miaovStartMove(aLi[i], { left: 900 }, MIAOV_MOVE_TYPE.FLEX);
//设定一次性定时器100毫秒之后再执行next
timer = setTimeout(next, 100);
//执行上一个
i--;
}
else {
//设定一次性定时器150毫秒之后再执行next2
timer = setTimeout(next2, 150);
}
}
//前一半向右进来
function next2() {
//如果i为所有li的前一半
if (i >= 0) {
//调用插件里的miaoStartMove函数让前一半li向右弹性运动到后一半对应位置
miaovStartMove(aLi[i], { left: aPos[i] }, MIAOV_MOVE_TYPE.FLEX);
//设定一次性定时器100毫秒之后再执行next2
timer = setTimeout(next2, 100);
}
//执行上一个
i--;
}
//执行next
next();
//清空第二个a元素的class
aBtn[1].className = '';
//为第一个a元素加上class
this.className = 'show';
//调用插件里的miaoStartMove函数让oCaret箭头向左缓冲运动到当前元素宽度的中间
miaovStartMove(oCaret, { left: this.offsetLeft this.offsetWidth / 2 }, MIAOV_MOVE_TYPE.BUFFER);
};
//为内容为iTunes and more添加点击事件(所有li向左)
aBtn[1].onclick = function () {
//i等于第一张图片
var i = 0;
//清除定时器,防止多次点击造成重叠
clearTimeout(timer);
//前一半向左出去
function next() {
var obj = aLi[i];
if (i < aLi.length / 2) {
//调用插件里的miaoStartMove函数让每一个li向左弹性运动-200px
miaovStartMove(aLi[i], { left: -200 }, MIAOV_MOVE_TYPE.FLEX);
//设定一次性定时器100毫秒之后再执行next
timer = setTimeout(next, 100);
//执行下一个
i ;
}
else if (i == aLi.length / 2) {
//设定一次性定时器150毫秒之后再执行next2
timer = setTimeout(next2, 150);
}
}
//后一半向左进来
function next2() {
if (i < aLi.length) {
//调用插件里的miaoStartMove函数让另一半li向左弹性运动到上一半对应位置
miaovStartMove(aLi[i], { left: aPos[i - aLi.length / 2] }, MIAOV_MOVE_TYPE.FLEX);
//设定一次性定时器100毫秒之后再执行next2
timer = setTimeout(next2, 100);
}
//执行下一个
i ;
}
//执行next
next();
//清空第一个a元素的class
aBtn[0].className = '';
//为第二个a元素加上class
this.className = 'show';
//调用插件里的miaoStartMove函数让oCaret箭头向右缓冲运动到当前元素宽度的中间
miaovStartMove(oCaret, { left: this.offsetLeft this.offsetWidth / 2 }, MIAOV_MOVE_TYPE.BUFFER);
};
};
</script>
</head>
<body>
<div class='miaov_head'>
<a target="_blank" class='left'></a>
<a target="_blank" class='right'></a>
</div>
<div id="div1" class="page">
<div class="miaov_box">
<ul class="miaov_box_head">
<!-- 以下所有图片为产品图 -->
<li>
<a>
<img src="images/1.jpg" alt="" />iPod shuffle
</a>
</li>
<li>
<a>
<img src="images/2.jpg" alt="" />iPod nano
</a>
</li>
<li>
<a>
<img src="images/3.jpg" alt="" />iPod classic
</a>
</li>
<li>
<a>
<img src="images/4.jpg" alt="" />iPod touch
</a>
</li>
<li>
<a>
<img src="images/5.jpg" alt="" />Apple TV
</a>
</li>
<li>
<a>
<img src="images/6.jpg" alt="" />Accessories
</a>
</li>
<li>
<a>
<img src="images/7.jpg" alt="" />Download iTunes 10
</a>
</li>
<li>
<a>
<img src="images/8.jpg" alt="" />iTunes Gift Cards
</a>
</li>
<li>
<a>
<img src="images/9.jpg" alt="" />Nike iPod
</a>
</li>
<li>
<a>
<img src="images/10.jpg" alt="" />(PRODUCT) RED
</a>
</li>
<li>
<a>
<img src="images/11.jpg" alt="" />MobileMe
</a>
</li>
<li>
<a>
<img src="images/12.jpg" alt="" />In-Ear Headphones
</a>
</li>
</ul>
</div>
<div class="miaov_box_foot">
<span style="left: 424px;" class="caret"></span>
<a class="show">Products</a>
<a>iTunes and more</a>
</div>
</div>
</body>
</html>
以下是上面代码中引入的封装的运动函数move.js代码。
代码语言:javascript复制function css(obj, attr, value) {
if (arguments.length == 2)
return parseFloat(obj.currentStyle ? obj.currentStyle[attr] : document.defaultView.getComputedStyle(obj, false)[attr]);
else if (arguments.length == 3)
switch (attr) {
case 'width':
case 'height':
case 'paddingLeft':
case 'paddingTop':
case 'paddingRight':
case 'paddingBottom':
value = Math.max(value, 0);
case 'left':
case 'top':
case 'marginLeft':
case 'marginTop':
case 'marginRight':
case 'marginBottom':
obj.style[attr] = value 'px';
break;
case 'opacity':
obj.style.filter = "alpha(opacity:" value * 100 ")";
obj.style.opacity = value;
break;
default:
obj.style[attr] = value;
}
return function (attr_in, value_in) { css(obj, attr_in, value_in) };
}
var MIAOV_MOVE_TYPE = {
BUFFER: 1,
FLEX: 2
};
function miaovStartMove(obj, oTarget, iType, fnCallBack, fnDuring) {
var fnMove = null;
if (obj.timer) {
clearInterval(obj.timer);
}
switch (iType) {
case MIAOV_MOVE_TYPE.BUFFER:
fnMove = miaovDoMoveBuffer;
break;
case MIAOV_MOVE_TYPE.FLEX:
fnMove = miaovDoMoveFlex;
break;
}
obj.timer = setInterval(function () {
fnMove(obj, oTarget, fnCallBack, fnDuring);
}, 15);
}
function miaovDoMoveBuffer(obj, oTarget, fnCallBack, fnDuring) {
var bStop = true;
var attr = '';
var speed = 0;
var cur = 0;
for (attr in oTarget) {
cur = css(obj, attr);
if (oTarget[attr] != cur) {
bStop = false;
speed = (oTarget[attr] - cur) / 5;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
css(obj, attr, cur speed);
}
}
if (fnDuring) fnDuring.call(obj);
if (bStop) {
clearInterval(obj.timer);
obj.timer = null;
if (fnCallBack) fnCallBack.call(obj);
}
}
function miaovDoMoveFlex(obj, oTarget, fnCallBack, fnDuring) {
var bStop = true;
var attr = '';
var speed = 0;
var cur = 0;
for (attr in oTarget) {
if (!obj.oSpeed) obj.oSpeed = {};
if (!obj.oSpeed[attr]) obj.oSpeed[attr] = 0;
cur = css(obj, attr);
if (Math.abs(oTarget[attr] - cur) > 1 || Math.abs(obj.oSpeed[attr]) > 1) {
bStop = false;
obj.oSpeed[attr] = (oTarget[attr] - cur) / 5;
obj.oSpeed[attr] *= 0.7;
var maxSpeed = 65;
if (Math.abs(obj.oSpeed[attr]) > maxSpeed) {
obj.oSpeed[attr] = obj.oSpeed[attr] > 0 ? maxSpeed : -maxSpeed;
}
css(obj, attr, cur obj.oSpeed[attr]);
}
}
if (fnDuring) fnDuring.call(obj);
if (bStop) {
clearInterval(obj.timer);
obj.timer = null;
if (fnCallBack) fnCallBack.call(obj);
}
}