javascriptで画像をスライドするプラグインを自作

no-img

画像をスライドするプラグインを自作しました。
とにかく軽量でシンプルなものを目指して作ってみました。

以下にソースをおいておきます。

※サムネイルで以下のサイトのデザインテンプレートを利用しています。
Market-Me.fr

  1. ソースコード
    1. slider.css
    2. slider.js
  2. 使い方
    1. ソースコードを読み込む
    2. HTMLの書き方
  3. カスタマイズ、注意
    1. 画像(imgタグ)のコンテナサイズ。slider.jsの15、16行目
    2. スライドアニメーションの時間(transition)。slider.jsの12行目
  4. まとめ

ソースコード

slider.css

.slider {
    text-align: center;
    overflow: hidden;
    padding-bottom: 40px;
    position: relative;
    /* 背景色を必ず指定してください */
    background-color: #fff;
}
/* 左右ボタンのDOMはjsで生成し.sliderの最後の子要素として追加 */
.slider > .left-button,
.slider > .right-button {
    display: block;
    width: 30px;
    height: 30px;
    line-height: 30px;
    border-radius: 50%;
    position: absolute;
    bottom: 0;
    background-color: #bbb;
    font-size: 30px;
    color: #fff;
    font-weight: bold;
    cursor: pointer;
    user-select: none;
    opacity: .5;
}
.slider > .left-button {
    left: calc(50% - 50px);
}
.slider > .right-button {
    left: calc(50% + 50px);
}
.slider > .left-button:hover,
.slider > .right-button:hover {
    opacity: .7;
}
/* コンテナ */
/* 中央の画像、ボタンエリアの位置取りをする */
/* width、heightはjsで指定(1つ目のアイテム(画像)からheight、widthを取得して指定) */
.slider > .container {
    position: relative;
    display: inline-block;
}
/* 全アイテムに適用 */
.slider > .container > * {
    display: none;
    position: absolute;
    top: 0;
}
/* 端から端に移動する際、裏を通して隠すため */
/* hideクラスはjsで操作 */
.slider > .container > .hide {
    z-index: -10;
}
/* 5つのみ表示(display: block) */
/* 画像の間隔は25px */
/* ■ □ □ □ □ */
.slider > .container > .slider-left-left {
    display: block;
    right: calc(200% + 50px);
}
/* □ ■ □ □ □ */
.slider > .container > .slider-left {
    display: block;
    right: calc(100% + 25px);
}
/* □ □ ■ □ □ */
.slider > .container > .slider-center {
    display: block;
    margin: 0 auto;
    right: 0;
}
/* □ □ □ ■ □ */
.slider > .container > .slider-right {
    display: block;
    right: calc(-100% - 25px);
}
/* □ □ □ □ ■ */
.slider > .container > .slider-right-right {
    display: block;
    right: calc(-200% - 50px);
}

slider.js

var slider_el = document.getElementsByClassName('slider')[0];
var container_el = slider_el.getElementsByClassName('container')[0];
// --------------------------------------------------------------------------------------------
// プロパティカスタマイズ用 ここから
// スライドアニメーションのtransitionを指定できます
var transition = 0.8;
// 画像のwidth、heightを指定できます(数値のみで指定してください(px))
// var width = 600;
// var height = 400;
// width, heightを指定した場合、以下2行をコメントアウトしてください
var width = container_el.firstElementChild.width;
var height = container_el.firstElementChild.height;
// 上記2行は画像のもともとのサイズを利用する場合に有効にしてください
// カスタマイズここまで ここまで
// --------------------------------------------------------------------------------------------
// スライドさせる関数
// 前半で表示する要素(5つ)を選択し、後半でクラスの付け直し
// vectorが真のときは左にスライド、偽のときは右にスライド
function slide(vector = true) {
    if (vector) count += 1;
    else count -= 1;
    // jsは負の値も剰余になるみたいだから、lenを足したりlenで剰余とったりしてる
    var left_left_el = slider_items_el[((-2 + count) % len + len) % len];
    var left_el = slider_items_el[((-1 + count) % len + len) % len];
    var center_el = slider_items_el[((0 + count) % len + len) % len];
    var right_el = slider_items_el[((1 + count) % len + len) % len];
    var right_right_el = slider_items_el[((2 + count) % len + len) % len];
    // それぞれにクラスを与える。className.add()ではないため完全に書き換え!(ここでhideや別のクラスもリセットされます)
    left_left_el.className = 'slider-left-left';
    left_el.className = 'slider-left';
    center_el.className = 'slider-center';
    right_el.className = 'slider-right';
    right_right_el.className = 'slider-right-right';
    // 端から端に移動する要素は隠したい為、クラスを与えてスタイルシートのスタイルを適用させます
    if (vector) right_right_el.classList.add('hide');
    else left_left_el.classList.add('hide');
}
// 1つ目の画像のサイズをコンテナのサイズとする
container_el.style.height = height + 'px';
container_el.style.width = width + 'px';
// アイテムの数を取得
var container_child_count = container_el.childElementCount;
// 操作ボタンをクリエイト
var left_button_el = document.createElement('div');
left_button_el.className = 'left-button';
left_button_el.textContent = '<';
slider_el.appendChild(left_button_el);
var right_button_el = document.createElement('div');
right_button_el.className = 'right-button';
right_button_el.textContent = '>';
slider_el.appendChild(right_button_el);
// 表示されていない分も含め5個並べておくため
// アイテムの数が4以下の場合は、数を2倍に複製して対処
if (container_child_count == 3) {
    let slider_items_el = slider_el.querySelectorAll('.container > *');
    container_el.appendChild(slider_items_el[0].cloneNode()); //4個目に1個目を複製
    container_el.appendChild(slider_items_el[1].cloneNode()); //5個目に2個目を複製
    container_el.appendChild(slider_items_el[2].cloneNode()); //...以下同様
} else if (container_child_count == 4) {
    let slider_items_el = slider_el.querySelectorAll('.container > *');
    container_el.appendChild(slider_items_el[0].cloneNode());
    container_el.appendChild(slider_items_el[1].cloneNode());
    container_el.appendChild(slider_items_el[2].cloneNode());
    container_el.appendChild(slider_items_el[3].cloneNode());
}
// 同盟の変数が手前にありますが、複製している場合があるのでノードリストに割り当てなおします
var slider_items_el = slider_el.querySelectorAll('.container > *');
var len = slider_items_el.length;
// transtionのスタイルを指定
for (let i = 0; i < len; i++) {
    slider_items_el[i].style.transition = transition + 's';
    slider_items_el[i].style.width = width + 'px';
    slider_items_el[i].style.height = height + 'px';
}
// slider_items_elの何番目がドコ?っていうのを管理する為(左にスライドすると増え、右にスライドすると減ります)
var count = 0;
// いい感じにクラスを指定
slider_items_el[-2 + len].className = 'slider-left-left';
slider_items_el[-1 + len].className = 'slider-left';
slider_items_el[0].className = 'slider-center';
slider_items_el[1].className = 'slider-right';
slider_items_el[2].className = 'slider-right-right';
// スライド動作中かどうかを判定する為のフラグ
// true → スライド中(スライド不可)
// false → スライド中ではない(スライド可)
var proceeding = false;
// ボタンクリック時のイベント
// 高速クリックで描写が崩れるため
// transition * 0.66 秒間は処理をスルー
left_button_el.addEventListener('click', function () {
    if (proceeding === false) {
        proceeding = true
        slide(true);
        setTimeout(function () {
            proceeding = false;
        }, transition * 0.66 * 1000);
    }
});
right_button_el.addEventListener('click', function () {
    if (proceeding === false) {
        proceeding = true
        slide(false);
        setTimeout(function () {
            proceeding = false;
        }, transition * 0.66 * 1000);
    }
});

使い方

ソースコードを読み込む

まず、ソースコードを読み込む必要がありますね。
上記からコピペしてください(セキュリティうんぬんでアップロードできませんでしたorz)。

ファイル名は、なんでもかまいませんが、見出しのようにslider.cssslider.jsとした体で、説明していきます。

読み込む方法ですが、一応書いておくと、
headタグ内で、

<link rel="stylesheet" href="./css/slider.css">

bodyタグの最後で、

<script src="./js/slider.js"></script>

こうしておけば問題ないでしょう。
パスは各自であわせてくださいね。

関数を呼び出したりする必要はありませんが、要素を指定するためにクラスをつける必要があります。
以下で説明します。

HTMLの書き方

    <div class="slider">
        <div class="container">
            <img src="./img/img1.png" alt="">
            <img src="./img/img2.png" alt="">
            <img src="./img/img3.png" alt="">
        </div>
    </div>

例を見ながら説明します。

sliderクラスのdivに、containerクラスのdivを入れてください。
そして、containerクラスのdivの中にスライドさせたい画像を入れてください。

いれれる画像の数は3個以上です。2個以下の動作は知りません。逆に上限は特にない(はず)です。

スライドさせたい要素以外は入れないでください!
あと、imgタグにはクラスを指定しないでください!
jsファイルでクラスを書き換えてしまいますので、どうしてもクラスを指定したい場合は、どうにかしてください。

これで一応動作するはずですが、注意があるので以下に続きます。

カスタマイズ、注意

cssファイルで.sliderに背景色を指定しています。

これがないと見えてはいけないものが見えてしまいますので、ご自身のサイトに合わせて変更してください(デフォルトでは、#000を指定しています)。

jsファイルの上部でカスタマイズ項目を用意しています。
用意している項目は以下の2つです。

画像(imgタグ)のコンテナサイズ。slider.jsの15、16行目

画像のサイズを指定したい場合はここで指定してください。
詳細はソースコードに記載していますが、19、20行目のコメントアウトも忘れずに。

単位はいりません!

もともとの(画像ファイルが持つ)サイズのまんまでいいよ!って場合は特に書き換える必要はありません。

スライドアニメーションの時間(transition)。slider.jsの12行目

transitionに指定する秒数を変更したい場合はここで指定してください。

デフォルトは0.8になっています。ここも単位はいりません!

まとめ

なるべく簡潔なコードにしたつもりなので、全体が把握しやすくカスタマイズもしやすくなっていればいいですが(願望)、もしご不明な点等がございましたら、コメントかなんかで御連絡ください!

最近の記事