LoginSignup
2
1

More than 3 years have passed since last update.

Svelte3 横並びのメニューを作る!

Last updated at Posted at 2019-12-14

Svelteでこんな感じのよくある横並びメニューを作りたい!
そして画面からはみ出た分は横スクロールもできるようにしたい!
と思ったのでその際の実装をメモしておきます。

スクリーンショット 2019-12-14 10.43.41.png

リストタグを横並びにする&スクロールもできるようにする

まずは横並びのメニューを作成&横スクロール可能にする実装です。

スクロールバーも非表示にしています
Chrome/Safari以外のブラウザなどシラヌ

ちなみにoverflow-x: hidden;を指定するとスクロールルバーは消えるけど横スクロールもできなくなるぞっ!!!!

こうすると

<div class="menu">
    <ul>
        {#each menus as menu}
            <li>{menu}</li>
        {/each}
    </ul>
</div>

<script>
    const menus = ['menu1', 'menu2', 'menu3', 'menu4', 'menu5'];
</script>

<style>
    .menu {
        width: 100%;
    }
    ul {
        padding: 0;
        /* 先頭に表示される"・"を消す */
        list-style: none;
        /* 左右の表示領域からあふれる時にスクロールバーを表示する */
        overflow-x: auto;
        /* 横並びにした時に返しを行わせない */
        white-space: nowrap;
    }
    /* スクロールバーを非表示にする */
    ul::-webkit-scrollbar {
        display: none;
    }
    li {
        /* リストを横並びにする */
        display: inline-block;

        /* 見た目整える用 */
        width: 100px;
        height: 50px;
        background: #fa8072;
        margin-right: 5px;
    }
</style>

こんな感じになる!

scroll1.gif

クリックしたメニューのスタイルを変える

クリックした要素が分かるようにスタイルを変えたい!という時の実装です。

class:focus={pos === i}のように記述することで
pos === iの条件を満たす場合だけfocusというclassをつける事ができるので
クリック時につけたいstyleを追加しておけばクリックされた要素の見た目を変えられます。

こうすると

<div class="menu">
    <ul>
        {#each menus as menu, i}
            <li class:focus={pos === i} on:click={() => pos = i}>{menu}</li>
        {/each}
    </ul>
</div>

<script>
    let pos;
    const menus = ['menu1', 'menu2', 'menu3', 'menu4', 'menu5'];
</script>

<style>
    .menu {
        width: 100%;
    }
    ul {
        padding: 0;
        /* 先頭に表示される"・"を消す */
        list-style: none;
        /* 左右の表示領域からあふれる時にスクロールバーを表示する */
        overflow-x: auto;
        /* 横並びにした時に返しを行わせない */
        white-space: nowrap;
    }
    /* スクロールバーを非表示にする */
    ul::-webkit-scrollbar {
        display: none;
    }
    li {
        /* リストを横並びにする */
        display: inline-block;

        /* 見た目整える用 */
        width: 100px;
        height: 50px;
        background: #fa8072;
        margin-right: 5px;
    }
    /* クリックされた要素のスタイル */
    .focus {
        background: #87ceeb;
    }
</style>

こんな感じになる!

scroll2.gif

クリック時にイイ感じの場所にメニューをスクロールさせる

見切れているメニューをクリックした時に見切れたままにするのは気持ちが悪いので
クリックされたメニューをいい感じの場所にスクロールさせたい!という時の実装です。

ulタグにbind:this={menu}を追加することでulのDOM要素を操作できるようになります。
scrollToで水平方向のスクロール位置を指定することでulタグ内の任意の位置にスクロールさせることができるようになります。

こうすると

<div class="menu">
    <ul bind:this={menu}>
        {#each menus as menu, i}
            <li class:focus={pos === i} on:click={() => onClickMenu(i)}>{menu}</li>
        {/each}
    </ul>
</div>

<script>
    let pos;
    let menu;
    const menus = ['menu1', 'menu2', 'menu3', 'menu4', 'menu5'];

    const onClickMenu = i => {
        pos = i;
        menu.scrollTo({
            top: 0,
            left: 80 * i,
            behavior: 'smooth',
        })
    };
</script>

<style>
    .menu {
        width: 100%;
    }
    ul {
        padding: 0;
        /* 先頭に表示される"・"を消す */
        list-style: none;
        /* 左右の表示領域からあふれる時にスクロールバーを表示する */
        overflow-x: auto;
        /* 横並びにした時に返しを行わせない */
        white-space: nowrap;
    }
    /* スクロールバーを非表示にする */
    ul::-webkit-scrollbar {
        display: none;
    }
    li {
        /* リストを横並びにする */
        display: inline-block;

        /* 見た目整える用 */
        width: 100px;
        height: 50px;
        background: #fa8072;
        margin-right: 5px;
    }
    /* クリックされた要素のスタイル */
    .focus {
        background: #87ceeb;
    }
</style>

こんな感じになる!!

scroll3.gif

bind:thisを使う時に気をつけること

bind:this={menu}はコンポーネントがマウントされるまでは変数menuの値はundefinedにため以下のような実装だとエラーになるので
onMount()on:clickで使用する関数の中で使用しなければならないです。

<div class="menu">
    <ul bind:this={menu}>
        {#each menus as menu, i}
            <li class:focus={pos === i} on:click={() => onClickMenu(i)}>{menu}</li>
        {/each}
    </ul>
</div>

<script>
  let menu;
  menu.scrollTo({
    top: 0,
    left: 50 * i,
    behavior: 'smooth',
  })
</script>

おわり

いい感じに横スクロールして動くメニューができた!!!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1