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

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

ただいまの
回答率

89.52%

カテゴリで要素をフィルタリングさせ、ラジオボタンとセレクトボックスの選択値を連動させたい

解決済

回答 1

投稿 編集

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

shiromoco

score 17

レスポンシブで要素の絞り込み処理をさせたいと考えております。
やりたいこととしては下記内容です。

  1. ウィンドウ内に要素が入ったらフェードイン(フェードインする順番は左上からパネルが1枚ずつ表示されるイメージにしたいです。)
  2. 各カテゴリの合計数を取得して表示
  3. ラジオボタンでカテゴリを選択したらその下の要素をフィルタリング(1つの要素に複数のカテゴリあり)
  4. スマホ時にはradioボタンではなくセレクトボックスにしたいので、ラジオボタンとセレクトボックスのカテゴリを連動させる
  5. カテゴリを選択してフィルタリングしたら「#secB」内のフィルタリングされた要素のみ再度フェードインで表示させる

上記のうち、1〜4までは単体では機能したのですが、3と4を1つのファイルにまとめたら4の「ラジオボタンとプルダウンのカテゴリを連動」が動かなくなってしまいました。
どのように修正したらこの2つの動きは共存できるでしょうか?

また、5を実現するためにJavaScriptの「(1) フェード表示」に click した場合の処理も1カテゴリ分入れてみたのですが、思っていたような挙動になりませんでした。
どのような処理にしてあげたらこの挙動を実現できるでしょうか?

ソースがコンパクトにできず、長くなってしまい申し訳ございません。

ご教示いただけますと幸いです。
何卒よろしくお願いいたします。

 追記 

1.ウィンドウ内に要素が入ったらフェードイン

「.transparent」を指定した要素が1枚ずつ順番に表示されるようなイメージにしたいです。
(イメージ画像でお伝えすると、「#secA → パネル1 → パネル2 → パネル3・・・」というイメージです)
また、jsには処理として入っていましたが、言葉で明記できていなかった機能として、画面途中でリロードした時にすでにスクロールが終わっていて画面から外れている要素にも「fadein」を追加して表示させておきたいです。

4.スマホ時にはradioボタンではなくセレクトボックスにしたいので、ラジオボタンとセレクトボックスのカテゴリを連動させる

ラジオボタンで「カテゴリB」を選択したらセレクトボックスでも「カテゴリB」になるように連動させたいと考えています。

伝わりにくそうな表現の箇所について追記させていただきます。
何卒よろしくお願いいたします。

 イメージ画像 
イメージ説明

$(function() {

    // (1) フェード表示
    $(function() {
        $(window).on('load resize scroll', function() {
            var count = 0;
            var windowY = $(window).scrollTop() + $(window).height();

            $('.transparent').each(function() {
                if ($(this).hasClass('fadein')) {
                    return;
                }

                var diffY = windowY - $(this).offset().top;

                if (diffY > $(this).offset().top) {
                    $(this).addClass('fadein');
                }
                else if (diffY > 0) {
                    $(this).delay(count++ * 500).queue(function() {
                        $(this).addClass('fadein');
                    });
                }
            });
        });
        $('category_btn').on('click', function() {
            var count = 0;
            var windowY = $(window).scrollTop() + $(window).height();

            $('.transparent.cB').each(function() {
                if ($('.transparent').hasClass('fadein')) {
                    $(this).removeClass('fadein');
                }

                var diffY = windowY - $(this).offset().top;

                if (diffY > $(this).offset().top) {
                    $(this).addClass('fadein');
                }
                else if (diffY > 0) {
                    $(this).delay(count++ * 500).queue(function() {
                        $(this).addClass('fadein');
                    });
                }
            });
        });
    });

    // (2) category数
    $(function(){
        $(window).on('load', function(){
            var categoryA = $('.category_block .cA').length;
            var categoryB = $('.category_block .cB').length;
            var categoryC = $('.category_block .cC').length;

            $('.category_btn.cA .category_num').html('(' + categoryA + ')').parents('#secB');
            $('.category_btn.cB .category_num').html('(' + categoryB + ')').parents('#secB');
            $('.category_btn.cC .category_num').html('(' + categoryC + ')').parents('#secB');
        });
    });

    // (3) category分け
    $(function(){
        categoryBtn = $('.category_filter').find('input[type="radio"]');
        categoryBtn.each(function() {
            $(this).click(function(e){
                var selected = $(this).parents('.category_btn').attr('class');
                e.preventDefault();
                categoryBtn.parents('.category_btn').removeClass('active');
                $(this).parents('.category_btn').addClass('active');
                $('body').removeClass(function(index, className) {
                    return (className.match(/\bcategory-\S+/g) || []).join(' ');
                }).addClass('category-' + selected);
            });
        });
    });

    // (4) radioとselectを連動
    $(function(){
        $('.category_filter input[type="radio"]').change(function () {
            var radio_valule = $('input:checked').val();
            var select_valule = $('select option:selected').val();
            if (radio_valule === 'val_a') {
                $('.category_filter select').val('val_a').attr('selected');
            } else if (radio_valule === 'val_b') {
                $('.category_filter select').val('val_b').attr('selected');
            } else if (radio_valule === 'val_c') {
                $('.category_filter select').val('val_c').attr('selected');
            }
        });
        $('.category_filter select').change(function () {
            var radio_valule = $('input:checked').val();
            var select_valule = $('select option:selected').val();
            if (select_valule === 'val_a') {
                $('.category_filter input[type="radio"]:eq(0)').prop('checked', true);
            } else if (select_valule === 'val_b') {
                $('.category_filter input[type="radio"]:eq(1)').prop('checked', true);
            } else if (select_valule === 'val_c') {
                $('.category_filter input[type="radio"]:eq(2)').prop('checked', true);
            } else {
                $('.category_filter input[type="radio"]').removeAttr('checked');
            }
        });
    });

});
<div id="contents">
    <section id="secA">
        <div class="transparent">
            <p class=“img_main"><img src="./img/main.jpg" alt=""></p>
            <p class="text">テキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p>
        </div>
    </section>
    <section id="secB">
        <div class="container">
            <div class="category_filter transparent">
                <div class="category_input">
                    <label class="cA category_btn active">
                        <input type="radio" name="test" value="val_a" checked="">カテゴリA<span class="category_filter_num"></span>
                    </label>
                    <label class="cB category_btn">
                        <input type="radio" name="test" value="val_b">カテゴリB<span class="category_filter_num"></span>
                    </label>
                    <label class="cC category_btn">
                        <input type="radio" name="test" value="val_c">カテゴリC<span class="category_filter_num"></span>
                    </label>
                </div>
                <div class="category_select">
                    <select>
                        <option value="val_a" selected="selected">全て</option>
                        <option value="val_b">カテゴリB</option>
                        <option value="val_c">カテゴリC</option>
                    </select>
                </div>
            </div>
            <div class="category_block">
                <div class="category_detail cA cB transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリB</div>
                            <p class="category_overview">パネル1</p>
                        </div></a></div>
                <div class="category_detail cA cC transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリC</div>
                            <p class="category_overview">パネル2</p>
                        </div></a></div>
                <div class="category_detail cA cB transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリB</div>
                            <p class="category_overview">パネル3</p>
                        </div></a></div>
                <div class="category_detail cA cC transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリC</div>
                            <p class="category_overview">パネル4</p>
                        </div></a></div>
                <div class="category_detail cA cC transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリC</div>
                            <p class="category_overview">パネル5</p>
                        </div></a></div>
                <div class="category_detail cA cB transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリB</div>
                            <p class="category_overview">パネル6</p>
                        </div></a></div>
                <div class="category_detail cA cB transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリB</div>
                            <p class="category_overview">パネル7</p>
                        </div></a></div>
                <div class="category_detail cA cB transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリB</div>
                            <p class="category_overview">パネル8</p>
                        </div></a></div>
                <div class="category_detail cA cC transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリC</div>
                            <p class="category_overview">パネル9</p>
                        </div></a></div>
                <div class="category_detail cA cB transparent"><a href="">
                        <div class="category_detail_inner">
                            <div class="category_block_detail_ico">カテゴリB</div>
                            <p class="category_overview">パネル10</p>
                        </div></a></div>
            </div>
        </div>
    </section>
</div>
.category_block {
    width: 100%;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}
. category_detail {
    width: 33.333%;
    position: relative;
}
. category_detail:before {
    padding-top: 100%;
    display: block;
    content: "";
}

.category_block .category_detail {
    transition: all 500ms ease-out;
    opacity: 0;
}
body.category-cA .category_block .category_detail.fadein.cA,
body.category-cB .category_block .category_detail.fadein.cB,
body.category-cC .category_block .category_detail.fadein.cC {
    opacity: 1;
    display: block;
    transition: all 500ms ease-out;
}
body.category-cB .category_block .category_detail.cA,
body.category-cC .category_block .category_detail.cA {
    display: none;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

あなたのコードに沿った回答ではありませんが, CSSとVanilla JS(素のJavaScript+DOM)で作るとしたら動きとしてはこんな感じ?

なお

1.ウィンドウ内に要素が入ったらフェードイン

については考慮していません.これについては適宜IntersectionObserverかライブラリを導入して下さい. スクリーンに表示されたタイミングでdisplay:noneを解除するとCSSアニメーションが着火します.

<fieldset id="selector">
    <legend>filter</legend>
    <form id="inputs">
        <label>カテゴリA<input type="radio" name="selRadio" value="catA"/></label>
        <label>カテゴリB<input type="radio" name="selRadio" value="catB"/></label>
        <label>カテゴリC<input type="radio" name="selRadio" value="catC"/></label>
        <select name="selSelect">
            <option value="catA">カテゴリA</option>
            <option value="catB">カテゴリB</option>
            <option value="catC">カテゴリC</option>
        </select>
    </form>
</fieldset>
<div id="items">
    <div class="catA">A</div>
    <div class="catB">B</div>
    <div class="catC">C</div>
    <div class="catA catB">AB</div>
    <div class="catA catC">AC</div>
    <div class="catB catC">BC</div>
    <div class="catA catB catC">ABC</div>
</div>
/*アニメーションは全てCSSで行う*/
#items>div{
    display: inline-block;
    width: 100px;
    height: 100px;
    border: 1px black solid;
    vertical-align: bottom;
    display: none;
    animation: fadeIn 3s ease 0s backwards;
}
/*#selectorのクラス値と一致したパネルのみを表示する*/
#selector.catA+#items>.catA,
#selector.catB+#items>.catB,
#selector.catC+#items>.catC{
    display: inline-block;
}
@keyframes fadeIn{
    0%{opacity: 0}
    100%{opacity: 1}
}
"use strict";
function select(category){
    //ラジオボタンとドロップダウンの選択状態を揃える
    inputs.selRadio.value = inputs.selSelect.value = category;
    //パネルを消すためにクラスを張り替える
    selector.className = "";
    //パネル毎にアニメーションの開始タイミングをずらす
    [].forEach.call(document.querySelectorAll(`.${category}`),
    (elem, i) => elem.style.animationDelay = `${i*0.2}s`);
    //パネルを一度消すために, パネルの表示は非同期的に行う
    setTimeout(()=> {
        selector.classList.add(category);
    }, 100);
}
//イベントは上位ノードで処理する
selector.onchange = e => select(e.target.value);
//カテゴリの初期選択状態を設定する
select("catA");


動作例
https://jsfiddle.net/defghi1977/chdwzg2e/5/

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/01 04:57 編集

    早速ご回答くださりありがとうございます!
    不勉強で申し訳ございません、Vanilla JSというフレームワークがあるのですね。
    調べてみたいと思います。

    また、挙動について言葉が不足している箇所があったようですので修正させていただきました。
    「1.ウィンドウ内に要素が入ったらフェードイン」の際には、私のソースベースになってしまいますが、「.transparent」を指定した要素が1枚ずつ順番に表示されるようなイメージにしたいです。
    (イメージ画像でお伝えすると、「#secA → パネル1 → パネル2 → パネル3・・・」というイメージです)

    また、作成いただいた動作例ですとラジオボタンとセレクトボックスは個別に動いているようなのですが、ラジオボタンで「カテゴリB」を選択したらセレクトボックスでも「カテゴリB」になるように連動させたいと考えています。

    また、もし可能でしたら今はまだVanilla JSを使ったことがないためjQueryでご教示いただけますと幸いです。

    何卒よろしくお願いいたします。

    キャンセル

  • 2018/04/01 05:36

    > もし可能でしたら今はまだVanilla JSを使ったことがないためjQueryでご教示いただけますと幸いです。
    Vanilla JSはjQuery等のライブラリを用いない素のJavaScript/HTMLDOMを指す俗語です.
    従って, 今回私が提示したコードをそのままjQueryと混在させても動作します.

    キャンセル

  • 2018/04/01 07:16 編集

    コードの方、ご調整くださりありがとうございます。
    また、Vanilla JSについてまだちゃんと調べられていなかったため、よく分かっていないコメントをしてしまい失礼いたしました。
    まだ詳細には確認できていないのですが、まずはお礼申し上げます。
    確認をして後ほど改めて連絡させていただきます。

    キャンセル

  • 2018/04/01 23:19

    連絡が遅くなってしまいましたが、いただいたコードを少し調整して無事に実装することができました!
    ご丁寧に対応くださりありがとうございました。

    キャンセル

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

  • ただいまの回答率 89.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる