[不安裝套件] 製作響應式 RWD 輪播效果 Slider

如題,我個人並不是很排斥安裝 javascript 套件,因為畢竟人家花心思做出來的東西就是會想得比較全面,可是有時候我們就是用不到這麼多功能,所以可以自己動手做的就試著做做看吧!

 

rwd slider - 再不寫就要忘了
原諒我網站空間有限,我只想放這麼小的圖

 

HTML

圖片的部分可以先抓 google 的,只要在 google 搜尋 「圖片 1000×400」,他就很聰明會幫你找到符合尺寸的照片。

<div class="slider">
  <div class="slider--content">
    <div class="slider--item">
      <img src="..." />
    </div>
    <div class="slider--item">
      <img src="..." />
    </div>
    <div class="slider--item">
      <img src="..." />
    </div>
  </div>
  <div class="slider--controls">
    <a href="#" class="slider--controls--left">prev</a>
    <a href="#" class="slider--controls--right">next</a>
  </div>
</div>

content 就是我放所有圖片的地方,controls 是放控制上一張或下一張的按鈕。

 

SCSS

接著我們加入 css。

如果是用 scss 的話就會知道 class name 命名方式會影響 scss 寫法的便利性XD

像我中間都是用 --item--controls,所以 scss 就可以用&--item 直接接下去寫。

.slider {
  position: relative; // 設定定位的基準點
  &--item {
    position: absolute; // 讓所有的照片都先疊在一起
    width: 100%;
    text-align: center;
    img {
      width: 100%;
      max-width: 100%;
      max-height: 100%; // 這邊一定要設定圖片的最大寬度和高度,可以達到 rwd 的效果
    }
    &:not(:first-child) {
      opacity: 0; // 因為我們的動畫有加上淡入淡出,所以其他還沒出場的人請先都隱藏,不然淡出之後就會發現後面還有一張照片
    }
  }
  &--controls {
    a {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      text-decoration: none;
      display: inline-block;
      padding: 20px;
      background-color: rgba(#f75857, 0.8);
      color: white;
      transition: 0.4s;
      &:hover {
        background-color: rgba(#f75857, 1);
      }
    }
    &--left {
      left: 0;
      border-top-right-radius: 10px;
      border-bottom-right-radius: 10px;
    }
    &--right {
      right: 0;
      border-top-left-radius: 10px;
      border-bottom-left-radius: 10px;
    }
  }
}

寫到這邊你會發現我們的按鈕並沒有在圖片的上下垂直的位置:

因為我們在--item那邊用了position: absolute,現在 slider 是沒有高度的~(所有的內容都被絕對定位了)

等一下我們會用 js 來手動把 slider 高度補上去。

 

然後我們還需要一些出場和入場的動畫:

@keyframes showRight {
  0% {
    left: 100%;
    opacity: 0;
  }
  100% {
    left: 0;
    opacity: 1;
  }
}

@keyframes hideRight {
  0% {
    left: 0;
    opacity: 1;
  }
  100% {
    left: -100%;
    opacity: 0;
  }
}

@keyframes showLeft {
  0% {
    left: -100%;
    opacity: 0;
  }
  100% {
    left: 0;
    opacity: 1;
  }
}
@keyframes hideLeft {
  0% {
    left: 0;
    opacity: 1;
  }
  100% {
    left: 100%;
    opacity: 0;
  }
}

 

Javascript

current:首先我們需要計算目前播到第幾張了,current 再點選下一張的按鈕的時候要 +1,點到最後一張要歸 0;點選上一張的時候 current 要 -1,點到第一張時要回到最後一張。

items:這邊我們為了擴充性,就是讓你日後隨時想放幾張都可以不用再改 js,所以所有跟上限有關的數字都要用items.length代替,不能直接寫死數字。

handleNext:點下一張的時候,加上進出場動畫,記得要讓動畫 forwards 停在最後狀態,圖片才會一直保持顯示/隱藏的狀態。

handlePrev:點上一張的時候,加上進出場動畫,記得要讓動畫 forwards 停在最後狀態,圖片才會一直保持顯示/隱藏的狀態。

getSliderHeight:我們需要抓到照片隨著螢幕縮放時的高度,然後把他指定給 slider,這樣按鈕在定位的時候就可以抓到目前 slider 高度的一半了。

let current = 0;
const items = document.querySelectorAll(".slider--item");

const handleNext = () => {
  items[current].style.animation = "hideRight 1.5s forwards";
  items[current >= items.length - 1 ? 0 : current + 1].style.animation =
    "showRight 1.5s forwards";
  if (current < items.length - 1) {
    current++;
  } else {
    current = 0;
  }
};

const handlePrev = () => {
  items[current].style.animation = "hideLeft 1.5s forwards";
  items[current > 0 ? current - 1 : 2].style.animation =
    "showLeft 1.5s forwards";
  if (current > 0) {
    current--;
  } else {
    current = items.length - 1;
  }
};
const getSliderHeight = () => {
  document.querySelector(".slider").style.height =
    document.querySelector(".slider--item").clientHeight + "px";
};
window.onresize = getSliderHeight;
getSliderHeight();

寫好 js 之後,要記得把方法指定到按鈕的 click 事件。

<a href="#" class="slider--controls--left" onclick="handlePrev()">prev</a>
<a href="#" class="slider--controls--right" onclick="handleNext()">next</a>

完成!

想看完整程式碼,請到CodePan

學習程式原來可以這麼簡單:六角學院線上課程

初學者如何成為vue前端工程師:查看課程內容

---------------------------

| 軟體開發 | 網站建置 | 網頁系統 | 資料庫網站 |

| 客製化網站 (報名系統、投票系統、掛號系統...) |

| 前後端技術合作 |

歡迎與我們聯繫:jessica@penueling.com

加入Line立即聊聊:@539mjyid

0
0 回復

發表評論

Want to join the discussion?
Feel free to contribute!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。