96617


ドロップダウンに項目を入れようとして、selectを使用したところ結果が表示されなくなります。  
divの時は動いていたので何か問題があるのだと思うのですが、何が問題なのかがわかりません。  
何か足りない部分があるのでしょうか<(_ _)>

[code]

           <select>
                <option value="all" data-filter="all" class="is-active">全て表示</option>
                <option value="a" data-filter="a">A</option>
                <option value="b" data-filter="b">B</option>
                <option value="c" data-filter="c">C</option>
            </select>
    
            <ul class="genre">
                <li data-genre="a">A+A</li>
                <li data-genre="a-b">A+B</li>
                <li data-genre="a-c">A+C</li>
                <li data-genre="b">B+B</li>
                <li data-genre="b-c">B+C</li>
                <li data-genre="c">C+C</li>
            </ul>
            <script src="script.js"></script>
        </body>
    </html>
    
[/code]

[code]

    const filterButtons = document.querySelectorAll("[data-filter]");
    const genreContents = document.querySelectorAll("[data-genre]");
    
    filterButtons.forEach((filterButton) => {
        filterButton.addEventListener("click", buttonSwitch);
        filterButton.addEventListener("click", genreFilter);
    });
    
    function buttonSwitch() {
        filterButtons.forEach((filterButton) => {
            filterButton.classList.remove("is-active");
            this.classList.add("is-active");
        });
    }
    
    function genreFilter() {
        const buttongenre = this.dataset.filter;
    
        const targetContents = document.querySelectorAll('[data-genre*="' + buttongenre + '"]');
    
        genreContents.forEach((genreContent) => {
            genreContent.animate(
                [
                    {
                        opacity: 0,
                    },
                    {
                        opacity: 1,
                    },
                ],
                {
                    duration: 600,
                    fill: "forwards",
                }
            );
    
            if (buttongenre == "all") {
                genreContent.classList.add("is-show");
            } else {
                genreContent.classList.remove("is-show");
                targetContents.forEach((targetContent) => {
                    targetContent.classList.add("is-show");
                });
            }
        });
    }
    
[/code]


CC BY-SA 4.0
2023-10-28T12:08:08.520
96609
2023-10-30T06:57:35.233
2023-10-29T13:19:17.923
4236
60237
question
javascript html css
select内に入れるとdata属性が効かないのでしょうか？


多くのブラウザでは、メニュー `<select>` 内の `<option>` では `click` イベントが発生しません。「`<option>`
はページに表示されているわけではなく、 `<select>`にデータを与えているだけ」という扱いになるようです。`<option>`
に対するスタイルシートもほとんど無効になります。

`<select>` の `change`
イベントなどで変更を検知するように変更する必要があります。質問文のコードだとそこそこの量のコードを書き換える必要がありそうですね。

以下のような変更が必要かと思います:

  * `forEach()` ですべての `<option>` にリスナを登録するのではなく、`<select>` の `change` イベントに `buttonSwitch` と `genreFilter` を登録する
  * `buttonSwitch()` と `genreFilter()` の中では、`this` のかわりに `this.selectedOptions[0]` を利用する

`is-active` のスタイルは効かないかもしれません。


CC BY-SA 4.0
2023-10-28T23:14:09.027
96613
2023-10-30T06:57:35.233
2023-10-30T06:57:35.233
3475
3475
96609
answer


[`:has()`疑似クラス](https://developer.mozilla.org/ja/docs/Web/CSS/:has)を使うとCSSセレクターに条件を設定することができます。[`:checked`疑似クラス](https://developer.mozilla.org/ja/docs/Web/CSS/:checked)はチェックボックスやラジオボタンだけでなく、現在選択されている`option`要素にも適用されます。  
記述としては冗長になってしまいますが、JavaScriptと違って静的に定義できるところが利点です。  
ただし、現時点でFirefoxが正式対応できていないことに注意してください（対応がずるずる伸びてる…）。

[code]

    body ul.genre li {
      opacity: 0;
    }
    
    body:has(select option:checked[data-filter="all"]) ul.genre li,
    body:has(select option:checked[data-filter="a"]) ul.genre li[data-genre*="a"],
    body:has(select option:checked[data-filter="b"]) ul.genre li[data-genre*="b"],
    body:has(select option:checked[data-filter="c"]) ul.genre li[data-genre*="c"] {
      animation: 600ms forwards genre;
    }
    
    @keyframes genre {
      to {
        opacity: 1;
      }
    }
[/code]

[code]

    <select>
      <option value="all" data-filter="all" class="is-active">全て表示</option>
      <option value="a" data-filter="a">A</option>
      <option value="b" data-filter="b">B</option>
      <option value="c" data-filter="c">C</option>
    </select>
    
    <ul class="genre">
      <li data-genre="a">A+A</li>
      <li data-genre="a-b">A+B</li>
      <li data-genre="a-c">A+C</li>
      <li data-genre="b">B+B</li>
      <li data-genre="b-c">B+C</li>
      <li data-genre="c">C+C</li>
    </ul>
[/code]


CC BY-SA 4.0
2023-10-29T13:13:33.963
96617
2023-10-30T05:28:33.613
2023-10-30T05:28:33.613
4236
4236
96609
answer