欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TWEEN动画、JQUERY、ES6 — 2、轮播图-渐隐渐现版本

程序员文章站 2022-05-02 20:42:54
...

分析

目录

编译并压缩less(需要先npm安装less)

banner.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
    <!--development-->
    <!--<link rel="stylesheet/less" href="css/banner.less">
    <script src="js/less-2.5.3.min.js"></script>-->

    <!--production-->
    <link rel="stylesheet" href="css/banner.min.css">
</head>
<body>
<div class="container" id="container">
    <!--WRAPPER:控制轮播图切换的区域-->
    <ul class="wrapper">
        <!--<li class="slide">
            <img src="" data-img="img/banner1.jpg" alt="">
        </li>-->
    </ul>
    <!--FOCUS:控制焦点-->
    <ul class="focusBox clearfix">
        <!--<li class="select"></li>
        <li></li>
        <li></li>
        <li class="last"></li>-->
    </ul>
    <!--ARROW:控制切换的箭头-->
    <a href="javascript:;" class="arrow arrowLeft"></a>
    <a href="javascript:;" class="arrow arrowRight"></a>
</div>

<!--IMPORT JS-->
<script src="js/utils.min.js"></script>
<script src="js/animate.min.js"></script>
<script src="js/banner.js"></script>
</body>
</html>
复制代码

banner.less

@import "reset";

/*--BANNER--*/
.container {
  position: relative;
  margin: 20px auto;
  width: 1000px;
  height: 300px;
  overflow: hidden;
  text-align: center;

  .wrapper {
    position: relative;
    height: 300px;
    background: url("../img/default.gif") no-repeat center center #EEE;

    .slide {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;

      //=>init style
      opacity: 0;
      filter: alpha(opacity=0);
      z-index: 0;

      img {
        display: none;
        width: 100%;
        height: 100%;
      }
    }
  }

  .focusBox {
    position: relative;
    top: -40px;
    z-index: 999;
    display: inline-block;
    padding: 4px 8px;
    height: 12px;
    background: rgba(0, 0, 0, .2);
    border-radius: 12px;

    li {
      float: left;
      margin-right: 10px;
      width: 12px;
      height: 12px;
      border-radius: 50%;
      background: #FFF;
      cursor: pointer;

      &.last {
        margin-right: 0;
      }

      &.select {
        background: #DB192A;
      }
    }
  }

  .arrow {
    display: none;
    position: absolute;
    top: 50%;
    z-index: 999;
    margin-top: -30px;
    width: 30px;
    height: 60px;
    background: url("../img/pre.png") no-repeat;
    opacity: 0.3;
    filter: alpha(opacity=30);

    &:hover {
      opacity: 1;
      filter: alpha(opacity=100);
    }

    &.arrowLeft {
      left: 0;
      background-position: 0 0;
    }

    &.arrowRight {
      right: 0;
      background-position: -48px 0;
    }
  }
}
复制代码

reset.less

body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, button, input, textarea, th, td {
  margin: 0;
  padding: 0
}

body {
  font-size: 12px;
  font-style: normal;
  font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif
}

small {
  font-size: 12px
}

h1 {
  font-size: 18px
}

h2 {
  font-size: 16px
}

h3 {
  font-size: 14px
}

h4, h5, h6 {
  font-size: 100%
}

ul, ol {
  list-style: none
}

a {
  text-decoration: none;
  background-color: transparent
}

a:hover, a:active {
  outline-width: 0;
  text-decoration: none
}

table {
  border-collapse: collapse;
  border-spacing: 0
}

hr {
  border: 0;
  height: 1px
}

img {
  border-style: none
}

img:not([src]) {
  display: none
}

svg:not(:root) {
  overflow: hidden
}

html {
  -webkit-touch-callout: none;
  -webkit-text-size-adjust: 100%
}

input, textarea, button, a {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
}

article, aside, details, figcaption, figure, footer, header, main, menu, nav, section, summary {
  display: block
}

audio, canvas, progress, video {
  display: inline-block
}

audio:not([controls]), video:not([controls]) {
  display: none;
  height: 0
}

progress {
  vertical-align: baseline
}

mark {
  background-color: #ff0;
  color: #000
}

sub, sup {
  position: relative;
  font-size: 75%;
  line-height: 0;
  vertical-align: baseline
}

sub {
  bottom: -0.25em
}

sup {
  top: -0.5em
}

button, input, select, textarea {
  font-size: 100%;
  outline: 0
}

button, input {
  overflow: visible
}

button, select {
  text-transform: none
}

textarea {
  overflow: auto
}

button, html [type="button"], [type="reset"], [type="submit"] {
  -webkit-appearance: button
}

button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0
}

button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText
}

[type="checkbox"], [type="radio"] {
  box-sizing: border-box;
  padding: 0
}

[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button {
  height: auto
}

[type="search"] {
  -webkit-appearance: textfield;
  outline-offset: -2px
}

[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration {
  -webkit-appearance: none
}

::-webkit-input-placeholder {
  color: inherit;
  opacity: .54
}

::-webkit-file-upload-button {
  -webkit-appearance: button;
  font: inherit
}

.clearfix:after {
  display: block;
  height: 0;
  content: "";
  clear: both
}
复制代码

banner.json

[
  {
    "id": 1,
    "img": "img/banner1.jpg",
    "desc": "海,你好",
    "link": "http://www.baidu.cn/"
  },
  {
    "id": 2,
    "img": "img/banner2.jpg",
    "desc": "梦想起飞",
    "link": "http://www.baidu.cn/"
  },
  {
    "id": 3,
    "img": "img/banner3.jpg",
    "desc": "把握未来,掌握先机",
    "link": "http://www.baidu.cn/"
  },
  {
    "id": 4,
    "img": "img/banner4.jpg",
    "desc": "好好学习",
    "link": "http://www.baidu.cn/"
  }
]
复制代码

banner.js

// var bannerRender = (function () {


//     return {
//         init: function () {

//         }
//     }
// })();

// bannerRender.init();





var bannerRender = (function () {
    var container = document.getElementById('container'),
        wrapper = utils.getElementsByClassName('wrapper', container)[0],
        focusBox = utils.getElementsByClassName('focusBox', container)[0],
        arrow = utils.children(container, 'a'),
        arrowLeft = arrow[0],
        arrowRight = arrow[1];
    var bannerData = null,
        wrapperList = null,
        focusList = null,
        wrapperImgList = null;

    //=>1、ajax获取数据
    function queryData() {
        var xhr = new XMLHttpRequest();
        xhr.open('get', 'json/banner.json', false);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                bannerData = utils.toJSON(xhr.responseText);
            }
        };
        xhr.send(null);
    }

    //=>2、绑定数据
    function bindData() {
        if (!bannerData) return;
        var str = ``,
            strFocus = ``;
        for (var i = 0; i < bannerData.length; i++) {
            var item = bannerData[i];
            str += `<li class="slide">
                <img src="" data-img="${item.img}" alt="">
            </li>`;

            strFocus += `<li class="${i === bannerData.length - 1 ? 'last' : ''}"></li>`;
        }
        wrapper.innerHTML = str;
        focusBox.innerHTML = strFocus;

        //=>5、数据绑定完需要获取所有的LI以及IMG,后面会用到
        wrapperList = wrapper.getElementsByTagName('li');
        focusList = focusBox.getElementsByTagName('li');
        wrapperImgList = wrapper.getElementsByTagName('img');
    }

    //=>6、设置默认展示
    function initDefault(index) {
        index = index || 0;
        utils.css(wrapperList[index], {
            opacity: 1,
            zIndex: 1
        });
        focusList[index].className += ' select';//=>一定是加等于(因为部分LI有自己的原有样式)
    }

    //=>8、图片延迟加载
    function computed() {
        if (!wrapperImgList) return;
        for (var i = 0; i < wrapperImgList.length; i++) {
            var curImg = wrapperImgList[i];
            if (curImg.isLoad) continue;
            lazyImg(curImg);
        }
    }

    function lazyImg(curImg) {
        curImg.isLoad = true;
        var tempImg = new Image;//创建一个临时
        tempImg.onload = function () {
            curImg.src = this.src;
            curImg.style.display = 'block';
            tempImg = null;
        };
        tempImg.src = curImg.getAttribute('data-img');
    }

    //=>10、实现轮播图的自动切换
    var step = 0,//->记录当前展示的是第几个SLIDE(索引)
        prevStep = 0,//->记录上一个展示的SLIDE索引
        autoInterval = 2000,//->自动切换的时间因子
        autoTimer = null,//->自动切换的定时器
        count = 0;//->总共的SLIDE数量

    
    function autoMove() {
        step++;
        if (step === count) {
            step = 0;
        }
        change();
    }

    //=>轮播图公共切换方法
    function change() {
        if (step === prevStep) return;
        var curSlide = wrapperList[step],
            preSlide = wrapperList[prevStep];

        //->当前展示的SLIDE层级变为1 & 上一个展示的SLIDE层级变为0
        utils.css(curSlide, 'zIndex', 1);
        utils.css(preSlide, 'zIndex', 0);

        //->让当前展示的SLIDE透明度从0~1(动画)
        animate({
            curEle: curSlide,
            target: {opacity: 1},
            duration: 200,
            callBack: function () {
                //=>上一个SLIDE隐藏(透明度为0)
                utils.css(preSlide, 'opacity', 0);
            }
        });

        //->当前展示的这一个SLIDE就是下一次切换的上一次SLIDE
        prevStep = step;

        //=>14、切换的时候要执行selectFocus让其焦点对齐
        selectFocus();
    }

    //=>13、焦点对齐的方法(这里用的是循环所有的焦点给当前索引加样式);还有种方式:可以用清除上一个焦点样式给当前焦点加样式
    function selectFocus() {
        for (var i = 0; i < focusList.length; i++) {
            var item = focusList[i];
            if (i === focusList.length - 1) {//最后一个焦点有last做特殊处理
                item.className = i === step ? 'last select' : 'last';
                continue;
            }
            item.className = i === step ? 'select' : '';
        }
    }

    //=>15、鼠标划入划出BANNER区域控制自动切换的暂停和开始 用onmouseout和onmouseover有问题,后面会写
    function bindMouseEvent() {
        container.onmouseenter = function () {
            clearInterval(autoTimer);
            arrowLeft.style.display = arrowRight.style.display = 'block';//鼠标滑进来左右箭头显示
        };
        container.onmouseleave = function () {
            autoTimer = setInterval(autoMove, autoInterval);
            arrowLeft.style.display = arrowRight.style.display = 'none';//鼠标离开左右箭头隐藏
        };
    }

    //=>16、滑过焦点实现切换
    function bindFocus() {
        for (var i = 0; i < focusList.length; i++) {
            focusList[i].myIndex = i;
            focusList[i].onmouseenter = function () {
                step = this.myIndex;
                change();
            }
        }
    }

    //=>17、点击左右按钮切换
    function bindArrow() {
        arrowLeft.onclick = function () {
            step--;
            if (step < 0) {
                step = count - 1;
            }
            change();
        };
        arrowRight.onclick = autoMove;
    }

    return {
        init: function () {
            // 9、执行computed延迟加载
            // setTimeout(computed,500);//可以看延迟加载效果
            window.onload = computed;//=>当页面加载完成后做图片的延迟加载(放在上面也无所谓,因为事件绑定是异步编程:写在上面,也是需要等下面的代码都加载完成,页面才加载完成,才会触发LOAD事件)
            // 3、执行queryData()
            queryData();
            // 4、执行bindData()
            bindData();
            // 7、执行
            initDefault(step);

            //=>实现轮播图的切换
            count = bannerData.length;//11、获取总共的SLIDE数量
            autoTimer = setInterval(autoMove, autoInterval);//12、执行autoMove

            //=>18、其它切换方式
            bindMouseEvent();
            bindFocus();
            bindArrow();
        }
    }
})();
bannerRender.init();
复制代码

其余文件同之前封装的库(动画库animate和dom库utils)