Help us understand the problem. What is going on with this article?

jQueryで十字型スライダーの作り方

More than 3 years have passed since last update.

なぜつくろうとしたか

仕事で十字のスライダー(カルーセル)の実装の必要があり、プラグインでは対応できないと感じたのでつくりました。

a9695c25-a02d-232c-32a1-575aea6badfc.gif

デモ
(Herokuの無料プランでサーバーを立てているので、初回の接続は時間が掛かります)

作り方

参考ページ

jQueryを使ったスライダーの作り方とその仕組み
横方向へのスライダーは、こちらのページを参照してください。
ここから手を加えて、縦方向にも動くようにします。

ソース

1ファイルでサクッと動作確認するために、html,css,jsをまとめてあります。

ソースはGitHubにもあげてます。

cross_slider.html

cross_slider.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>slide</title>
    <style>
        .slider .slide-x {
            width: 315px;
            height: 360px;
            float: left;
            margin: 0;
            padding: 0;
        }

        .slider .slide-set {
            position: absolute;
            }

        .slider {
            width: 315px;
            height: 360px;
            overflow: hidden;
            position: relative;
            border: 1px solid #ddd;
            border-bottom: 3px solid #ddd;
            margin: auto;
        }
    </style>
</head>
<body>

<div id="wrap">
    <div class="slider">
        <div class="slide-set">

            <div class="slide-y">
                <div class="slide-x">
                    <h1>slide1-1</h1>
                </div>

                <div class="slide-x">
                    <h1>slide1-2</h1>
                </div>

                <div class="slide-x">
                    <h1>slide1-3</h1>
                </div>
            </div>

            <div class="slide-y">
                <div class="slide-x">
                    <h1>slide2-1</h1>
                </div>

                <div class="slide-x">
                    <h1>slide2-2</h1>
                </div>

                <div class="slide-x">
                    <h1>slide2-3</h1>
                </div>
            </div>

            <div class="slide-y">
                <div class="slide-x">
                    <h1>slide3-1</h1>
                </div>

                <div class="slide-x">
                    <h1>slide3-2</h1>
                </div>

                <div class="slide-x">
                    <h1>slide3-3</h1>
                </div>
            </div>

        </div>
    </div>
</div>

<button class="slider-left">左へ</button>
<button class="slider-right">右へ</button>
<button class="slider-above">上へ</button>
<button class="slider-below">下へ</button>

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
    $(function () {
        "use strict";

        var slideNumX = $('.slide-x').length;  // .slide-xの数を取得して代入
        var slideNumY = $('.slide-y').length;  // .slide-yの数を取得して代入
        slideNumX = slideNumX / slideNumY;  // 1行あたりの.slide-xの数を求める

        var slideWidth = $('.slide-x').outerWidth(); // .slide-xの幅を取得して代入
        var slideSetWidth = slideWidth * slideNumX; // .slideの幅×数で求めた値を代入
        $('.slide-set').css('width', slideSetWidth); // .slideSetのスタイルシートにwidth: slideSetWidthを指定

        var slideHeight = $('.slide-x').outerHeight(); // .slide-yの幅を取得して代入
        var slideSetHeight = slideHeight * slideNumY; // .slide-yの長さ×数で求めた値を代入
        $('.slide-set').css('height', slideSetHeight); // .slideSetのスタイルシートにheight: slideSetHeightを指定

        var slideCurrentX = 0; // 現在地を示す変数X軸
        var slideCurrentY = 0; // 現在地を示す変数Y軸

        // アニメーションを実行する独自関数
        function slidingX() {
            // slideCurrentXが0以下だったら
            if (slideCurrentX < 0) {
                slideCurrentX = slideNumX - 1;
                // 一番左上端か判定
                if (slideCurrentY === 0) {
                    slideCurrentY = slideNumY - 1;
                } else {
                    slideCurrentY--;
                }
                slidingY();

                // slideCurrentXがslideNumXを超えたら
            } else if (slideCurrentX > slideNumX - 1) { // slideCUrrentX >= slideNumXでも可
                slideCurrentX = 0;
                // 一番右下端か判定
                if (slideCurrentY === slideNumY - 1) {
                    slideCurrentY = 0;
                } else {
                    slideCurrentY++;
                }
                slidingY();
            }

            $('.slide-set').stop(false, true).animate({
                left: slideCurrentX * -slideWidth
            }, 500);
        }

        function slidingY() {
            // slideCurrentYが0以下だったら
            if (slideCurrentY < 0) {
                slideCurrentY = slideNumY - 1;
                // 一番左上端か判定
                if (slideCurrentX === 0) {
                    slideCurrentX = slideNumX - 1;
                } else {
                    slideCurrentX--;
                }
                slidingX();

                // slideCurrentYがslideNumYを超えたら
            } else if (slideCurrentY > slideNumY - 1) { // slideCUrrentX >= slideNumでも可
                slideCurrentY = 0;
                // 一番右下端か判定
                if (slideCurrentX === slideNumX - 1) {
                    slideCurrentX = 0;
                } else {
                    slideCurrentX++;
                }
                slidingX();
            }

            $('.slide-set').stop(false, true).animate({
                top: slideCurrentY * -slideHeight
            }, 500);
        };

        // 左へボタンが押されたとき
        $('.slider-left').click(function () {
            slideCurrentX--;
            slidingX();
        });

        // 右へボタンが押されたとき
        $('.slider-right').click(function () {
            slideCurrentX++;
            slidingX();
        });

        // 下へボタンが押されたとき
        $('.slider-below').click(function () {
            slideCurrentY++;
            slidingY();
        });

        // 上へボタンが押されたとき
        $('.slider-above').click(function () {
            slideCurrentY--;
            slidingY();
        });
    }());
</script>
</body>
</html>

解説

css

        .slider .slide-x {
            width: 315px;
            height: 360px;
            float: left;
            margin: 0;
            padding: 0;
        }

        .slider .slide-set {
            position: absolute;
            }

        .slider {
            width: 315px;
            height: 360px;
            overflow: hidden;
            position: relative;
            border: 1px solid #ddd;
            border-bottom: 3px solid #ddd;
            margin: auto;
        }

cssはwidth,height両方をに固定にします。

html

    <div class="slider">
        <div class="slide-set">

            <div class="slide-y">
                <div class="slide-x">
                    <h1>slide1-1</h1>
                </div>

                <div class="slide-x">
                    <h1>slide1-2</h1>
                </div>

                <div class="slide-x">
                    <h1>slide1-3</h1>
                </div>
            </div>

            <div class="slide-y">
                <div class="slide-x">
                    <h1>slide2-1</h1>
                </div>

                <div class="slide-x">
                    <h1>slide2-2</h1>
                </div>

                <div class="slide-x">
                    <h1>slide2-3</h1>
                </div>
            </div>

            <div class="slide-y">
                <div class="slide-x">
                    <h1>slide3-1</h1>
                </div>

                <div class="slide-x">
                    <h1>slide3-2</h1>
                </div>

                <div class="slide-x">
                    <h1>slide3-3</h1>
                </div>
            </div>

        </div>
    </div>

このソースは、3×3の箱を並べてあるイメージです。
slide-yで縦軸の制御、slide-xで横軸の制御を行っています。

JavaScript

    $(function () {
        "use strict";

        var slideNumX = $('.slide-x').length;  // .slide-xの数を取得して代入
        var slideNumY = $('.slide-y').length;  // .slide-yの数を取得して代入
        slideNumX = slideNumX / slideNumY;  // 1行あたりの.slide-xの数を求める

        var slideWidth = $('.slide-x').outerWidth(); // .slide-xの幅を取得して代入
        var slideSetWidth = slideWidth * slideNumX; // .slideの幅×数で求めた値を代入
        $('.slide-set').css('width', slideSetWidth); // .slideSetのスタイルシートにwidth: slideSetWidthを指定

        var slideHeight = $('.slide-x').outerHeight(); // .slide-yの幅を取得して代入
        var slideSetHeight = slideHeight * slideNumY; // .slide-yの長さ×数で求めた値を代入
        $('.slide-set').css('height', slideSetHeight); // .slideSetのスタイルシートにheight: slideSetHeightを指定

        var slideCurrentX = 0; // 現在地を示す変数X軸
        var slideCurrentY = 0; // 現在地を示す変数Y軸

参考ソース元の横軸制御に追加して、縦軸の制御するための変数を定義してあげましょう。

        slideNumX = slideNumX / slideNumY;  // 1行あたりの.slide-xの数を求める

slide-xは縦の箱の数分存在するので、slide-yの数で割ってあげて、1行あたりのslide-xの数を求めてあげましょう。

        function slidingX() {
            // slideCurrentXが0以下だったら
            if (slideCurrentX < 0) {
                slideCurrentX = slideNumX - 1;
                // 一番左上端か判定
                if (slideCurrentY === 0) {
                    slideCurrentY = slideNumY - 1;
                } else {
                    slideCurrentY--;
                }
                slidingY();

                // slideCurrentXがslideNumXを超えたら
            } else if (slideCurrentX > slideNumX - 1) { // slideCUrrentX >= slideNumXでも可
                slideCurrentX = 0;
                // 一番右下端か判定
                if (slideCurrentY === slideNumY - 1) {
                    slideCurrentY = 0;
                } else {
                    slideCurrentY++;
                }
                slidingY();
            }

            $('.slide-set').stop(false, true).animate({
                left: slideCurrentX * -slideWidth
            }, 500);
        }

横軸移動のためのslidingX関数を定義してあげます。

            // slideCurrentXが0以下だったら
            if (slideCurrentX < 0) {
                slideCurrentX = slideNumX - 1;
                // 一番左上端か判定
                if (slideCurrentY === 0) {
                    slideCurrentY = slideNumY - 1;
                } else {
                    slideCurrentY--;
                }
                slidingY();

表示されている箱が一番左上の場合で、「左へ」が押された場合は、一番右下まで移動してあげるよう処理をしてあげます。

                // slideCurrentXがslideNumXを超えたら
            } else if (slideCurrentX > slideNumX - 1) { // slideCUrrentX >= slideNumXでも可
                slideCurrentX = 0;
                // 一番右下端か判定
                if (slideCurrentY === slideNumY - 1) {
                    slideCurrentY = 0;
                } else {
                    slideCurrentY++;
                }
                slidingY();
            }

同じように、一番右端が表示されている場合に「右へ」が押された場合は、一番左上まで移動します。

        function slidingY() {
            // slideCurrentYが0以下だったら
            if (slideCurrentY < 0) {
                slideCurrentY = slideNumY - 1;
                // 一番左上端か判定
                if (slideCurrentX === 0) {
                    slideCurrentX = slideNumX - 1;
                } else {
                    slideCurrentX--;
                }
                slidingX();

                // slideCurrentYがslideNumYを超えたら
            } else if (slideCurrentY > slideNumY - 1) { // slideCUrrentX >= slideNumでも可
                slideCurrentY = 0;
                // 一番右下端か判定
                if (slideCurrentX === slideNumX - 1) {
                    slideCurrentX = 0;
                } else {
                    slideCurrentX++;
                }
                slidingX();
            }

            $('.slide-set').stop(false, true).animate({
                top: slideCurrentY * -slideHeight
            }, 500);
        };

横軸移動のslidingX関数と同様に、縦軸移動のslidingY関数を定義していきます。
最初は複雑そうに思えますけど、分解すると簡単です。

ryuchan00
Qiitaはブログにするほどでもない小ネタを書く場所と決めています。
http://leokun0210.hatenablog.com/
pepabo
「いるだけで成長できる環境」を標榜し、エンジニアが楽しく開発できるWebサービス企業を目指しています。
https://pepabo.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away