天天看點

無縫輪播圖的實作對比---CSS3版, JS版

概述

什麼是輪播圖: 網頁頂部自動切換圖檔的區域.

什麼是無縫輪播圖: 切換圖檔到最後一張時, 繼續點選下一張,左滑至第一張,無縫銜接的感覺。

糊塗了沒, 直接看效果圖:

http://www.bobgao.cn/#!/demo/banner2

實作思路

無縫輪播圖, 有幾個要點:

1. 待輪播圖檔依次鋪開,輪播區域隻顯示一張; (css即可完成, 輪播區域overflow: hidden, position: relative; 圖檔清單 position: absolute)

2. 輪播邊界,需要緩沖圖檔實作無縫銜接效果; 例如總共5張圖檔待輪播, 清單中應該放7張,順序如下: 5123451

3. 輪播圖檔的過渡效果, 這裡有兩種方式: 一種純JS實作, 一種CSS3 (transition) + 部分js實作。

CSS3版

這裡的css3版指的是: 過渡效果用css3 transition.

線上demo: http://www.bobgao.cn/#!/demo/banner2

html

<div id="demo2" class="demo2">
  <div class="banner_wrap" ng-mouseover="stopInterval()" ng-mouseleave="startInterval()">
    <!-- 圖檔 -->
    <div class="photo">
      <ul class="photo_wrap">
        <div id="img_div" class="img_div" ng-class="{'img_div_pause': isPause}" style="left: -1280px;">
          <img src="css/images/demo/banner/banner5.png">
          <img src="css/images/demo/banner/banner1.png">
          <img src="css/images/demo/banner/banner2.png">
          <img src="css/images/demo/banner/banner3.png">
          <img src="css/images/demo/banner/banner4.png">
          <img src="css/images/demo/banner/banner5.png">
          <img src="css/images/demo/banner/banner1.png">
        </div>
      </ul>
    </div>
    <!-- 切換箭頭 -->
    <div class="arrow">
      <!-- ie 9 -->
      <span class="left_arrow" ng-click="arrowClick(0)">&#60;</span>
      <span class="right_arrow" ng-click="arrowClick(1)">&#62;</span>
      <!-- <i class="arrow_left" ng-click="arrowClick(0)"></i> -->
      <!-- <i class="arrow_right" ng-click="arrowClick(1)"></i> -->
    </div>

    <!-- 分頁圖示 -->
    <div class="pagination">
      <li ng-click="pagiClick(0)">
          <span ng-class="{'page_active': isPageActiveFir}"></span>
      </li>
      <li ng-click="pagiClick(1)">
          <span ng-class="{'page_active': isPageActiveSec}"></span>
      </li>
      <li ng-click="pagiClick(2)">
          <span ng-class="{'page_active': isPageActiveTir}"></span>
      </li>
      <li ng-click="pagiClick(3)">
          <span ng-class="{'page_active': isPageActiveFou}"></span>
      </li>
      <li ng-click="pagiClick(4)">
          <span ng-class="{'page_active': isPageActiveFiv}"></span>
      </li>
    </div>
  </div>
</div>
           

部分css

/* banner2 */
.demo2 li{ list-style: none;}
.demo2 .banner_wrap{
  width: %;
  height: px;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  position: relative;
}
/* 圖檔 */
.demo2 .banner_wrap .photo{
  position: absolute;
  top: ;
  left: ;
  height: px;
  width: %;
  background-color: #1E1B8E;
  z-index: ;
}
.demo2 .banner_wrap .photo .photo_wrap{
  width: px;
  height: px;
  margin:  auto;
  overflow: hidden;
  position: relative;
}
.demo2 .banner_wrap .photo .photo_wrap .img_div{
  width: px;
  height: px;
  position: absolute;
  z-index: ;
  /* transform: translateX(-1280px); */
  opacity: ;
  transition: all .s ease-in-out;
}
.demo2 .banner_wrap .photo .photo_wrap .img_div_pause{
  transition: height .s ease-in-out;
}
.demo2 .banner_wrap .photo .photo_wrap .img_div img{
  width: px;
  height: px;
  float: left;
}
           

重要js

/**
   * 實作動畫
   */
  function animate(offset) {
    var imgDiv = document.getElementById('img_div');
    var left = parseInt(imgDiv.style.left) + offset;
    var len = ;

    // 增加樣式
    imgDiv.style.left = left + 'px';

    // 處理邊界值
    if (left === ) {
      setTimeout(function(){
        $scope.$apply(function() {
          // 先暫停, 再改樣式, 最後恢複過渡效果
          $scope.isPause = true;
          imgDiv.style.left = - * len + 'px';
          setTimeout(function() {
            $scope.isPause = false;
          }, );
        });
      }, );
    }
    if (left === (- * (len+) )) {
      setTimeout(function(){
        $scope.$apply(function() {
          $scope.isPause = true;
          imgDiv.style.left = '-1280px';
          setTimeout(function() {
            $scope.isPause = false;
          }, );
        });
      }, );
    }
  }
           

JS版

js版指的是: 輪播的過渡效果用js實作。參考網上資源,demo如下:

線上demo: http://www.bobgao.cn/views/demo/banner3.html

html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>焦點輪播圖</title>
    <style type="text/css">
        *{ margin: ; padding: ; text-decoration: none;}
        body { padding: px;}
        #container { width: px; height: px; border: px solid #333; overflow: hidden; position: relative;}
        #list { width: px; height: px; position: absolute; z-index: ;}
        #list img { float: left; width: px; height: px;}
        #buttons { position: absolute; height: px; width: px; z-index: ; bottom: px; left: px;}
        #buttons span { cursor: pointer; float: left; border: px solid #fff; width: px; height: px; border-radius: %; background: #333; margin-right: px;}
        #buttons .on {  background: orangered;}
        .arrow { cursor: pointer; display: none; line-height: px; text-align: center; font-size: px; font-weight: bold; width: px; height: px;  position: absolute; z-index: ; top: px; background-color: RGBA(,,,.); color: #fff;}
        .arrow:hover { background-color: RGBA(,,,.);}
        #container:hover .arrow { display: block;}
        #prev { left: px;}
        #next { right: px;}
    </style>
    <script type="text/javascript">

        window.onload = function () {
            var container = document.getElementById('container');
            var list = document.getElementById('list');
            var buttons = document.getElementById('buttons').getElementsByTagName('span');
            var prev = document.getElementById('prev');
            var next = document.getElementById('next');
            var index = ;
            var len = ;
            var animated = false;
            var interval = ;
            var timer;


            function animate (offset) {
                if (offset == ) {
                    return;
                }
                animated = true;
                var time = ;
                var inteval = ;
                var speed = offset/(time/inteval);
                var left = parseInt(list.style.left) + offset;

                console.log('speed', speed);
                console.log('left', left);

                var go = function (){
                    if ( (speed >  && parseInt(list.style.left) < left) || (speed <  && parseInt(list.style.left) > left)) {
                        list.style.left = parseInt(list.style.left) + speed + 'px';
                        setTimeout(go, inteval);
                    }
                    else {
                        list.style.left = left + 'px';
                        if(left>-){
                            list.style.left = - * len + 'px';
                        }
                        if(left<(- * len)) {
                            list.style.left = '-600px';
                        }
                        animated = false;
                    }
                }
                go();
            }

            function showButton() {
                for (var i = ; i < buttons.length ; i++) {
                    if( buttons[i].className == 'on'){
                        buttons[i].className = '';
                        break;
                    }
                }
                buttons[index - ].className = 'on';
            }

            function play() {
                timer = setTimeout(function () {
                    next.onclick();
                    play();
                }, interval);
            }
            function stop() {
                clearTimeout(timer);
            }

            next.onclick = function () {
              if (animated) {
                return;
              }
              if (index == ) {
                index = ;
              }
              else {
                index += ;
              }
              console.log('index', index);
              animate(-);
              showButton();
            }
            prev.onclick = function () {
                if (animated) {
                    return;
                }
                if (index == ) {
                    index = ;
                }
                else {
                    index -= ;
                }
                animate();
                showButton();
            }

            for (var i = ; i < buttons.length; i++) {
                buttons[i].onclick = function () {
                    if (animated) {
                        return;
                    }
                    if(this.className == 'on') {
                        return;
                    }
                    var myIndex = parseInt(this.getAttribute('index'));
                    var offset = - * (myIndex - index);

                    animate(offset);
                    index = myIndex;
                    showButton();
                }
            }

            // container.onmouseover = stop;
            // container.onmouseout = play;

            // play();

        }
    </script>
</head>
<body>

<div id="container">
    <div id="list" style="left: -600px;">
        <img src="../../css/images/demo/banner/banner5.png" alt=""/>
        <img src="../../css/images/demo/banner/banner1.png" alt=""/>
        <img src="../../css/images/demo/banner/banner2.png" alt=""/>
        <img src="../../css/images/demo/banner/banner3.png" alt=""/>
        <img src="../../css/images/demo/banner/banner4.png" alt=""/>
        <img src="../../css/images/demo/banner/banner5.png" alt=""/>
        <img src="../../css/images/demo/banner/banner1.png" alt=""/>
    </div>
    <div id="buttons">
        <span index="1" class="on"></span>
        <span index="2"></span>
        <span index="3"></span>
        <span index="4"></span>
        <span index="5"></span>
    </div>
    <a href="javascript:;" id="prev" class="arrow">&lt;</a>
    <a href="javascript:;" id="next" class="arrow">&gt;</a>
</div>

</body>
</html>
           

總結

  1. css3版優點: 過渡效果好, js邏輯少; 缺點: ie9以上才支援transition.
  2. js版優點: 浏覽器相容性好, 整體代碼比較精簡; 缺點: 過渡效果一般, js邏輯較複雜。

歡迎學習,交流。

繼續閱讀