苹果官网产品展示特效

2020-11-26 16:03:06 浏览数 (1)

给大家分享一个由原生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);
    }
}

0 人点赞