4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

いまさらながら画像スライダーを作った

Last updated at Posted at 2020-08-16

今までは画像スライダーを実装するのに、Swiper.jsslickといった便利なプラグインを使っていたのですが、**「プラグインを使わずに自分で作ってみよう」**という急なきまぐれで以下のような画像スライダーを自分で実装してみました。

img-slider.gif

ソースコード

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <div class="main">
        <div class="container">
            <div class="btn btn-prev js-prev-btn"></div>
            <div class="btn btn-next js-next-btn"></div>
            <div class="slider-container">
                <ul class="slider-list js-slider-container">
                    <li class="slider-item js-slider-item"><img class="slider-img" src="./image/img1.jpg" alt=""></li>
                    <li class="slider-item js-slider-item"><img class="slider-img" src="./image/img2.jpg" alt=""></li>
                    <li class="slider-item js-slider-item"><img class="slider-img" src="./image/img3.jpg" alt=""></li>
                    <li class="slider-item js-slider-item"><img class="slider-img" src="./image/img4.jpg" alt=""></li>
                </ul>
            </div>
        </div>
    </div>
</body>
<script
  src="https://code.jquery.com/jquery-3.5.1.min.js"
  integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
  crossorigin="anonymous"></script>
<script src="./app.js"></script>
</html>
style.css
.main {
    width: 500px;
    height: 230px;
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    margin: auto;
}
.container {
    width: 100%;
    height: 100%;
    position: relative;
    /* overflow: hidden; */
}
.btn {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 50px;
    height: 50px;
    margin: auto;
    background: rgb(193, 193, 193);
    border-radius: 100%;
    cursor: pointer;
}
.btn:before {
    content: "";
    width: 10px;
    height: 10px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(45deg);
    -webkit-transform: translate(-50%, -50%) rotate(45deg);
    -ms-transform: translate(-50%, -50%) rotate(45deg);
}
.btn-prev {
    left: 0;
}
.btn-prev::before {
    border-left: 2px solid #ffffff;
    border-bottom: 2px solid #ffffff;
}
.btn-next {
    right: 0;
}
.btn-next::before {
    border-right: 2px solid #ffffff;
    border-top: 2px solid #ffffff;
}
.slider-container {
    width: 70%;
    height: 100%;
    margin: 0 auto;
    overflow: hidden;
    position: relative;
}
.slider-list {
    display: flex;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: 0;
    position: absolute;
    top:0;
    left: 0;
}
.slider-item {
    list-style: none;
    min-width: 100%;
}
.slider-img {
    width: 100%;
}

HTML/CSSはデザインによって適宜変更してください。
ポイントは、ulタグの親要素にoverflow: hidden;を指定すること、ulタグにposition: absolute;を指定し、自由に動かせるようにすること、liタグを横並びにすることです。

app.js
$(function() {
    // DOMの取得
    let $jsPrevBtn = $('.js-prev-btn');
    let $jsNextBtn = $('.js-next-btn');
    let $jsSliderContainer = $('.js-slider-container');
    let $jsSliderItemWidth = $('.js-slider-item').width();

    // 定数定義
    const autoTime = 4000; // 自動でスライドするときの時間間隔
    const speed = 600; // スライドするときの速さ
    const easing = "linear" // アニメーションの挙動

    // 変数定義
    let isSlide = false; // スライド中かどうかを判定する変数
    let timer;

    // 自動スライダー
    const autoPlay = () => {
        // 600ミリ秒ごとに自動でスライドする
        timer = setInterval(() => {
            slideNext();
        },  autoTime);
    }
    autoPlay();

    // Nextボタンが押されたら
    $jsNextBtn.on('click', function() {
        slideNext(); // 次の画像にスライド
    });
    // Prevボタンが押されたら
    $jsPrevBtn.on('click', function() {
        slidePrev(); // 前の画像にスライド
    });

    // 関数定義
    function slideNext() {
        if(!isSlide) { // スライド中でなければ
            isSlide = true; // スライド中に変更
            clearInterval(timer); // 一度タイマーをクリア

            // ulタグを画像1枚分左に移動
            $jsSliderContainer.animate({
                left: -$jsSliderItemWidth
            }, speed, easing, function() { // アニメーションが実行されたあとの処理

                // 左に送った画像をリストの最後の子要素に変更
                $jsSliderContainer.append($('.js-slider-item').eq(0));

                // ulタグを元の位置に戻す
                $jsSliderContainer.css({
                    left: 0
                });
                
                // 自動スライダー再開
                isSlide = false;
                autoPlay();
            });
        }
    }

    function slidePrev() {
        if(!isSlide) { // スライド中でなければ
            isSlide = true; // スライド中に変更
            clearInterval(timer); // 一度タイマーをクリア

            // リスト内の最後の子要素を先頭に移動
            $jsSliderContainer.prepend($('.js-slider-item').eq(-1));
            
            $jsSliderContainer.css({
                left: -$jsSliderItemWidth // ulタグを画像1枚分左に移動(これをしないと先頭にきた画像がすぐに表示されてしまう)
            }).animate({
                left: 0 // // ulタグを元の位置に戻す
            }, speed, easing, function(){
      
                // 自動スライダー再開
                isSlide = false;
                autoPlay();
            });
        }
    }
});

解説

今回作った画像スライダーは、リストアイテム(liタグ)を横並びにし、その親要素のulタグを移動させることで画像をスライドさせます。
以下に、動作の様子を図にまとめてみました。

画像スライダー.png

まず、ulタグの親要素にはoverflow: hidden;が指定されているため、画像は1枚分しか表示されません。(ulタグはposition: absoliute;で浮いたような状態になっているため)
画像を左へスライドさせる場合は、その状態でulタグを左へ移動します。すると、リスト全体が左へずれるため、表示される画像は次のものへと変更されます。
最後に、スライドしたことで消えてしまった画像は、リストの末尾に移動させることで、無限に画像をスライドさせることができます。

画像を右へスライドさせる場合はこの逆のことをしているだけです。

この処理を一定間隔で発火 or ボタンをクリックしたときに発火するようにすることで、自動 or 手動の画像スライダーを実装することができます。

まとめ

今回は、プラグインを使わない画像スライダーを実装してみました。
もっと良い方法、良いコードがあると思いますので、コメントで教えていただけると幸いです。
プラグインは便利で時間もかからない優れものですが、あえてプラグインを使わずに自分で1から実装してみると、勉強になりますよ〜。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?