こんにちは、ノベルティの山本です。
今回は、サイトのファーストビューにニューススライダーを入れたいときに複数の記事を入れるのはなかなか幅を取ってしまって入れにくいです。
そんな時に、カウンター付きのスライダーがあれば便利かと思うのでサンプルコード付きで紹介したいと思います。

はじめに

今回は、PHP,JS,SCSSのコードをそれぞれ紹介したいと思います。
ちなみにWordPressを使用している前提で話を進めますが、htmlでもPHPのコードを少しいじれば使えるのでこのまま読み進めていただいても問題ないかと思います。
サンプルコードを使用して吐き出されるコードのデモはこちらのサイトで使用していますのでアクセスしていただければご確認いただけます。

PHPのサンプルコード

<section id="news">
    <div class="inner">
        <div class="wrapper">
            <div class="header">
                <div class="title">
                    <span>NEWS</span>
                </div>
            </div>
            <div class="content">
                <?php
                    $args = array(
                        'post_type' => 'news',
                        'ignore_sticky_posts' => 1,
                        'orderby' => 'date',
                        'order' => 'DESC',
                        'posts_per_page' => 4
                    );
                    $post_list = get_posts($args);
                ?>
                <ul>
                    <?php foreach ($post_list as $post) : setup_postdata ($post); ?>
                        <li>
                            <a href="<?php the_permalink(); ?>">
                                <div class="paragraph">
                                    <time datetime="<?php the_modified_time('c'); ?>"><?php the_time('Y.m.d'); ?></time>
                                    <div class="title clamp">
                                        <h4>
                                            <?php the_title(); ?>
                                        </h4>
                                    </div>
                                </div>
                            </a>
                        </li>
                    <?php endforeach; wp_reset_query(); ?>
                    <?php wp_reset_postdata(); ?>
                </ul>
            </div>
            <div class="position">
                <div class="btn">
                    <a href="<?php echo home_url('/') ?>news">
                        <span>一覧を見る</span>
                    </a>
                </div>
            </div>
        </div>
        <div class="position sp">
            <div class="btn">
                <a href="<?php echo home_url('/') ?>news">
                    <span>一覧を見る</span>
                </a>
            </div>
        </div>
    </div>
</section>

こちらのコードでは、12行目でカスタム投稿タイプのnewsを取得していて、その下は日付が新しいもの順に4記事取得する様に記述しています。
そのほかのところは特に気になる箇所はないかと思いますが、これから記述するSCSSと相互に関係してくるコードなのであまり書き換えない方が無難かと思います。

SCSSのサンプルコード

#news {
    position: absolute;
    bottom: 0;
    height: 100px;
    width: 100%;
    z-index: 10;
    .wrapper {
        display: flex;
        height: 100%;
        padding: 0 30px;
        background: $color-white;
        .header {
            margin: 0 40px 0 30px;
            .title {
                display: flex;
                align-items: center;
                height: 100%;
                span {
                    font-size: 18px;
                    font-weight: bold;
                }
            }
        }
        .content {
            display: flex;
            margin: 0 40px 0 0;
            width: calc(100% - 200px - 60px - 60px);
            ul {
                position: relative;
                height: 100%;
                width: calc(100% - 120px);
                overflow: hidden;
                li {
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    visibility: hidden;
                    transition: visibility 0s 1s;
                    will-change: visibility;
                    padding: 0 30px 0 0;
                    opacity: 0;
                    transition: opacity .4s ease;
                    &.current {
                        opacity: 1;
                        visibility: visible;
                        transition-delay: 0s;
                    }
                    a {
                        display: flex;
                        align-items: center;
                        .paragraph {
                            width: 100%;
                            time {
                                margin: 0 30px 0 0;
                            }
                            .title {
                                display: flex;
                                align-items: center;
                            }
                        }
                    }
                }
                li.current .content h2 {
                    transform: translateY(0);
                    opacity: 1;
                    transition-delay: 1s;
                }
                li.current .content a {
                    transform: translateY(0);
                    opacity: 1;
                    transition-delay: 1.1s;
                }
                li.prev_slide .image {
                    clip: rect(0, 0, 50rem, 0);
                }
            }
            nav {
                display: flex;
                align-items: center;
                .prev,
                .next {
                    position: relative;
                    display: inline-block;
                    height: 15px;
                    width: 15px;
                    border: 0;
                    cursor: pointer;
                    background: transparent;
                    &::before {
                        content: '';
                        position: absolute;
                        top: 50%;
                        left: 0;
                        transform: translateY(-50%);
                        width: 15px;
                        height: 15px;
                        background-position: center;
                        background-repeat: no-repeat;
                    }
                }
                .next::before {
                    background-image: url("../images/icon/next.svg");
                }
                .prev::before {
                    background-image: url("../images/icon/back.svg");
                }
                .counter {
                    margin: 0 25px;
                    span {
                        &:last-child {
                            &::before {
                                content: '/';
                                margin: 0 6px;
                            }
                        }
                    }
                    
                }
                .prev:hover::after, .next:hover::after {
                    width: 3.5rem;
                }
            }
            .content {
                position: absolute;
                top: 0;
                right: 0;
                width: 100%;
                height: 100%;
                padding: 2rem 0 0 2rem;
                font-size: 9rem;
                text-align: right;
            }
            .content h2 {
                text-overflow: ellipsis;
                overflow: hidden;
                transform: translateY(-30%);
                opacity: 0;
                transition: transform .5s, opacity .5s;
                will-change: transform, opacity;
            }
            .content a {
                display: inline-block;
                font-size: 2rem;
                text-transform: lowercase;
                padding: 1.5rem;
                opacity: 0;
                transform: translateY(-100%);
                transition: transform .5s .1s, opacity .5s .1s;
                will-change: transform, opacity;
            }
            a {
                .paragraph {
                    display: flex;
                    .title {
                        h3 {
                            overflow-wrap: break-word;
                        }
                    }
                }
            }
        }
        .position {
            align-items: center;
            .btn {
                a {
                    background: transparent;
                    border: 1px solid $color-black;
                    span {
                        color: $color-black;
                    }
                }
            }
        }
    }
    .position {
        &.sp {
            display: none;
        }
    }
}

SCSSに関しては、コードが長すぎるので説明を省略しますが、とりあえず実装環境にコードを記述してみてから色々と触ってみていただけたらと思います。

JSのサンプルコード

function newsSlider() {
    function init(item) {
        var items = item.querySelectorAll('li'),
			current = 0,
			autoUpdate = true,
			timeTrans = 10000;
        //navタグを吐き出すコードです
        var nav = document.createElement('nav');
        nav.className = 'arrows';
        //戻るボタンを吐き出すコードです
        var prevbtn = document.createElement('button');
        prevbtn.className = 'prev';
        prevbtn.setAttribute('aria-label', 'Prev');
        //次へボタンを吐き出すコードです
        var nextbtn = document.createElement('button');
        nextbtn.className = 'next';
        nextbtn.setAttribute('aria-label', 'Next');
        //カウンターを吐き出すコードです
        var counter = document.createElement('div');
        counter.className = 'counter';
        counter.innerHTML = "<span>1</span><span>" + items.length + "</span>";
        //記事数が1以上であればulタグの後に吐き出されたコードを入れます
        if (items.length > 1) {
            nav.appendChild(prevbtn);
            nav.appendChild(counter);
            nav.appendChild(nextbtn);
            item.children[0].children[0].children[1].appendChild(nav);
        }
        items[current].className = "current";
        if (items.length > 1) items[items.length-1].className = "prev_slide";
        var navigate = function(dir) {
            items[current].className = "";
            if (dir === 'right') {
                current = current < items.length-1 ? current + 1 : 0;
            } else {
                current = current > 0 ? current - 1 : items.length-1;
            }
            var nextCurrent = current < items.length-1 ? current + 1 : 0,
                prevCurrent = current > 0 ? current - 1 : items.length-1;
            items[current].className = "current";
            items[prevCurrent].className = "prev_slide";
            items[nextCurrent].className = "";
            //update counter
            counter.firstChild.textContent = current + 1;
        }
        item.addEventListener('mouseenter', function() {
            autoUpdate = false;
        });
        item.addEventListener('mouseleave', function() {
            autoUpdate = true;
        });
        setInterval(function() {
            if (autoUpdate) navigate('right');
        }, timeTrans);
        prevbtn.addEventListener('click', function() {
            navigate('left');
        });
        nextbtn.addEventListener('click', function() {
            navigate('right');
        });
    }
    [].slice.call(document.querySelectorAll('#news')).forEach(function(item) {
        init(item);
    });
};
newsSlider();

こちらも説明を省かせていただきますが、後半にあるイベントリスナーのコードは、マウスオーバーしているときには自動で次のスライドに進むのを省いたりしているだけのコードです。
アニメーション自体は、JSでclassを付与したり外したりしてアニメーションをさせています。

ソースコード

こちらのソースコードはほとんど原型が残っていませんが、確かコードペンこちらのコードを参考にしていると思います。
コードペンは、ソースコードを共有するサイトです。SNSのような使われ方をしています。
凡庸なコードだったりちょっとしたスライドや、アニメーションのコードが割と参考になったりする気がします。

PAGE TOP