質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • JavaScript

    11187questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    4882questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

スワイプタブ切替機能をページ内に複数設置したい

解決済

回答 2

投稿 2017/11/24 18:53 ・編集 2017/11/27 10:04

  • 評価
  • クリップ 0
  • VIEW 93

kiwoharu

score 1

前提・実現したいこと

【2017/11/27追記】
HTML・CSSソース、全て記載しました。HTML・CSS・JSは参考サイトのソースをそのまま記述しています。

■ スマートニュースやグノシーのような、スワイプタブ切替機能を実装する

グノシーやスマートニュースで実装されている、スワイプタブを導入したサイトを作成しています。
実現したいことは、スワイプタブを複数設置してもそれぞれ動くようにしたいです。
(サイトの構成上、3つ以上、別カテゴリのスワイプタブをページ内に設置します。)

▼参考サイト ※スマホで見てください。
https://gunosy.com/ 
http://s.news.mynavi.jp/ 

発生している問題・エラーメッセージ

1つだけの場合、上記サイトの通りに実装はできたのですが、複数設置した場合、全てのスワイプタブが動かなくなります。

該当のソースコード

<!doctype html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <!-- TITLE -->
    <title>スワイプタブ切り替え</title>

    <!-- META -->
    <meta name="keywords" content="">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="format-detection" content="telephone=no">

    <!-- CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" />
    <style type="text/css">
        <!-- ▼_____________ スワイプタブ切替用CSS : START _____________▼ -->
        body{
            font-family:-apple-system,’Lucida Grande’,‘Helvetica Neue’,’Hiragino Kaku Gothic ProN’,‘游ゴシック’,’メイリオ’,meiryo,sans-serif;
            -webkit-text-size-adjust: 100%;
        }
        .container{
            max-width: 400px;
            margin: auto;
        }
        .tabContainer {
            overflow-x: auto;
        }
        .tabContainer::-webkit-scrollbar {
            height: 5px;
        }
        .tabContainer::-webkit-scrollbar-track {
            background: #000;
        }
        .tabContainer::-webkit-scrollbar-thumb {
            background: #000;
        }
        .tab{
            display: table;
            margin-top: 20px;
        }
        .tab__button{
            display: table-cell;
            text-align: center;
            background-color: #000;
            vertical-align: middle;
            border: 2px solid white;
            border-bottom-width: 4px;
            min-width: 80px;
        }
        .tab__button.active{
            border-bottom: none;
        }
        .tab__button a{
            padding: 10px;
            color: #fff;
            display: block;
            text-decoration: none;
            font-size: 12px;
        }
        .contents__content{
            background-color: #ccc;
            text-align: center;
        }
        .contents__content div{
            clear: left;
        }
        .contents__content div a{
            display: table;
            width: 100%;
            text-decoration: none;
            padding: 10px;
            border-bottom:1px solid #000;
            color:#222;
            text-align: left;
            line-height: 1.5em;
            font-size: 14px;
        }
        .contents__content div a span{
            display: table-cell;
            padding-left: 10px;
            padding-right: 10px;
        }
        .contents__content div a:before{
            content:'';
            width: 50px;
            height: 50px;
            display: block;
            background-color: #fff;
            display: table-cell;
        }
        <!-- ▲_____________ スワイプタブ切替用CSS : END _____________▲ -->
    </style>
</head>
<body>
    <div class="wrapper">

        <!-- ▼_____________ HTMLソース : START _____________▼ -->
        <div class="container">
            <div class="tabContainer">
                <div class="tab">
                    <div class="tab__button active"><a href="#">トップ</a></div>
                    <div class="tab__button"><a href="#">エンタメ</a></div>
                    <div class="tab__button"><a href="#">スポーツ</a></div>
                    <div class="tab__button"><a href="#">グルメ</a></div>
                    <div class="tab__button"><a href="#">コラム</a></div>
                    <div class="tab__button"><a href="#">国内</a></div>
                </div>
            </div>
            <div class="contents">

                <div class="contents__content">
                    <div><a href="#"><span>トップコンテンツトップコンテンツトップコンテンツトップコンテンツトップコンテンツ</span></a></div>
                    <div><a href="#"><span>トップコンテンツトップコンテンツトップコンテンツトップコンテンツトップコンテンツ</span></a></div>
                    <div><a href="#"><span>トップコンテンツトップコンテンツトップコンテンツトップコンテンツトップコンテンツ</span></a></div>
                    <div><a href="#"><span>トップコンテンツトップコンテンツトップコンテンツトップコンテンツトップコンテンツ</span></a></div>
                    <div><a href="#"><span>トップコンテンツトップコンテンツトップコンテンツトップコンテンツトップコンテンツ</span></a></div>
                    <div><a href="#"><span>トップコンテンツトップコンテンツトップコンテンツトップコンテンツトップコンテンツ</span></a></div>
                </div>

                <div class="contents__content">
                    <div><a href="#"><span>エンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツ</span></a></div>
                    <div><a href="#"><span>エンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツ</span></a></div>
                    <div><a href="#"><span>エンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツ</span></a></div>
                    <div><a href="#"><span>エンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツ</span></a></div>
                    <div><a href="#"><span>エンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツ</span></a></div>
                    <div><a href="#"><span>エンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツエンタメコンテンツ</span></a></div>
                </div>

                <div class="contents__content">
                    <div><a href="#"><span>スポーツコンテンツスポーツコンテンツスポーツコンテンツスポーツコンテンツ</span></a></div>
                    <div><a href="#"><span>スポーツコンテンツスポーツコンテンツスポーツコンテンツスポーツコンテンツ</span></a></div>
                    <div><a href="#"><span>スポーツコンテンツスポーツコンテンツスポーツコンテンツスポーツコンテンツ</span></a></div>
                    <div><a href="#"><span>スポーツコンテンツスポーツコンテンツスポーツコンテンツスポーツコンテンツ</span></a></div>
                    <div><a href="#"><span>スポーツコンテンツスポーツコンテンツスポーツコンテンツスポーツコンテンツ</span></a></div>
                    <div><a href="#"><span>スポーツコンテンツスポーツコンテンツスポーツコンテンツスポーツコンテンツ</span></a></div>
                </div>

                <div class="contents__content">
                    <div><a href="#"><span>グルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツ</span></a></div>
                    <div><a href="#"><span>グルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツ</span></a></div>
                    <div><a href="#"><span>グルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツ</span></a></div>
                    <div><a href="#"><span>グルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツ</span></a></div>
                    <div><a href="#"><span>グルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツ</span></a></div>
                    <div><a href="#"><span>グルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツグルメコンテンツ</span></a></div>
                </div>

                <div class="contents__content">
                    <div><a href="#"><span>コラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツ</span></a></div>
                    <div><a href="#"><span>コラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツ</span></a></div>
                    <div><a href="#"><span>コラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツ</span></a></div>
                    <div><a href="#"><span>コラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツ</span></a></div>
                    <div><a href="#"><span>コラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツ</span></a></div>
                    <div><a href="#"><span>コラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツコラムコンテンツ</span></a></div>
                </div>

                <div class="contents__content">
                    <div><a href="#"><span>国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ</span></a></div>
                    <div><a href="#"><span>国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ</span></a></div>
                    <div><a href="#"><span>国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ</span></a></div>
                    <div><a href="#"><span>国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ</span></a></div>
                    <div><a href="#"><span>国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ</span></a></div>
                    <div><a href="#"><span>国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ国内コンテンツ</span></a></div>
                </div>

            </div>
        </div>
        <!-- ▲_____________ HTMLソース : END _____________▲ -->

    </div><!-- /.wrapper -->


    <!-- JS -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.12/jquery.bxslider.min.js"></script>

    <script>
        $(document).ready(function(){

            /******************************************
            事前準備
            *******************************************/

            //タブボタンの数を取得
            var tabQuantity = $('.tab__button').length;

            //タブの長さとボディの長さの差分を取得
            var tabExtraDistance = $('.tab').width() - $('.tabContainer').width();

            /******************************************
            スライダー発動
            *******************************************/

            var slider = $('.contents').bxSlider({
                pager:false,
                controls:false,
                onSlideBefore: function($slideElement, oldIndex, newIndex){
                    //スライドする時に関数を呼び出す。newIndexはスライダーの現在地。
                    slideChange(newIndex);
                }
            });

            /******************************************
            スライドする時に発動する関数。タブの表示調整を行う。
            *******************************************/

            function slideChange(newIndex){

                //クラスを調整
                $('.tab__button').removeClass('active');
                $('.tab > div:nth-child(' + ( newIndex + 1 ) + ')').addClass('active');

                //スクロールするべき距離を取得。タブ全体の長さ / ( タブの個数 - 1 ) * スライドの現在地
                var scrollDestination = ( tabExtraDistance / (tabQuantity - 1) ) * ( newIndex );

                //スクロール位置を調整
                $('.tabContainer').animate({ scrollLeft: scrollDestination }, 'slow');

            }

            /******************************************
            タブボタンクリックで発動する関数
            *******************************************/

            $('.tab__button').on('click',function(e){

                //何番目の要素かを取ってスライドを移動する
                var nth = $('.tab__button').index(this);
                slider.goToSlide(nth);

                //クリックイベントを無効化
                e.preventDefault();

            })

        });
    </script>

</body>
</html>

試したこと

上記のJSの書き方だと、それぞれのスワイプタブに対しての動かし方じゃないのかと考え、
例えばタブボタンクリックで発動する部分においては、クリックした直近の親から、該当の要素を探して・・・
と書き換えてみたのですが書き方が悪くうまくいきませんでした。
スワイプタブそれぞれ違った動きなどの指定は特にないので、複数設置してもそれぞれ動くように書き換えられればと考えています。
この場合、どのように書き換えれば対応可能なのでしょうか?ご教示お願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/11/26 20:58

    HTMLも提示してください。

    キャンセル

  • kiwoharu

    2017/11/27 10:01 編集

    遅くなりまして大変失礼いたしました。HTMLソース全て追記いたしました。お手数ですが再度ご確認よろしくお願いいたします。

    キャンセル

回答 2

checkベストアンサー

+1

かんたんにやるならば、<div class="container"> 単位でHTMLを作成して、下記のようにすれば動くと思います。

$( document ).ready( function() {
    /* 中身 */
} );

$( function() {
    $( '.container' ).each( function() {
        /* 中身  */
    } );
} );

【.each() | jQuery API Documentation】
https://api.jquery.com/each/

【jQueryのeach()で複数の要素、配列、オブジェクトをループ処理】
http://www.flatflag.nir87.com/each-1325

【jQueryのeachの仕組みを徹底的にわかりやすく解説してみた。 ・ DQNEO起業日記】
http://dqn.sakusakutto.jp/2012/05/jquery_each_call.html

投稿 2017/11/27 16:30

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/30 10:42

    ご回答ありがとうございました!!!
    「.each()」を使ってループ処理させる点は気づきませんでした。

    現状のソースをもとに、該当箇所の「 $( '.container' ).each( function() { 」で修正してみました。
    複数設置でグレーのコンテンツエリアをフリックすると、それぞれスライダーが動くことはできたのですが、
    上部に連動しているタブが、今現在スワイプしているスワイプタブ以外も動いてしまったのと、
    タブそのものをクリックしても、下のスライダーが連動して動かなかったので、
    「$( '.container' ).each( function() { ~~~ } );」の中身を書き換えたら動くようになりました!

    ループ処理させる部分はずっと気が付かなかった点でしたので、こちらベストアンサーにさせていただきます。
    ご回答ありがとうございました!

    キャンセル

0

kei344さんの回答をもとに、jsを以下のように書き換えたら、動くようになりました。
※HTML/CSSの変更は最初の「該当のソースコード」から変更はなし。
※複数設置の場合、「<div class="container"> ~ </div>」の部分を増やしていくだけ

修正後のソースコード (JSのみ)

$(function(){
    $('.container').each(function() {

        var $root = $(this);
        var navItem = $('.tab__button');

        /******************************************
        事前準備
        *******************************************/
        //タブボタンの数を取得
        var tabQuantity = $root.find(navItem).length;

        //タブの長さとボディの長さの差分を取得
        var tabExtraDistance = $root.find('.tab').width() - $root.find('.tabContainer').width();

        /******************************************
        スライダー発動
        *******************************************/
        var slider = $(this).find('.contents').bxSlider({
            pager:false,
            controls:false,
            onSlideBefore: function($slideElement, oldIndex, newIndex){
                //スライドする時に関数を呼び出す。newIndexはスライダーの現在地。
                slideChange(newIndex);
            }
        });

        /******************************************
        スライドする時に発動する関数。タブの表示調整を行う。
        *******************************************/
        function slideChange(newIndex){

            //クラスを調整
            $root.find(navItem).removeClass('active');
            $root.find('.tab > div:nth-child(' + ( newIndex + 1 ) + ')').addClass('active');

            //スクロールするべき距離を取得。タブ全体の長さ / ( タブの個数 - 1 ) * スライドの現在地
            var scrollDestination = ( tabExtraDistance / (tabQuantity - 1) ) * ( newIndex );

            //スクロール位置を調整
            $root.find('.tabContainer').animate({ scrollLeft: scrollDestination }, 'slow');
        }

        /******************************************
        タブボタンクリックで発動する関数
        *******************************************/
        $root.find(navItem).on('click',function(e){

            //何番目の要素かを取ってスライドを移動する
            var nth = $root.find(navItem).index(this);
            slider.goToSlide(nth);

            //クリックイベントを無効化
            e.preventDefault();
        })

    });
});
  • 「.container」を親として、そこから各タブエリアやタブボタン、スライドするコンテナーエリアを指定する記述に変更(”$root.find”という記述で指定)
  • スライダーの挙動や関数などの処理事態への変更はしていません。

投稿 2017/11/30 10:55

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • JavaScript

    11187questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    4882questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。