Svelte - change the style of a nav-item when clicked

2.2k views Asked by At

I'm using Bulma CSS to create a nav component in Svelte and I would like to make each navbar-item bold when class:is-active is true. What I have currently done is follows:

    <script>
    import {onMount} from 'svelte';
    let segment;
    
    onMount(() => {
        const linkOne = document.getElementById("linkOne");
        const linkTwo = document.getElementById("linkTwo");
        const linkThree = document.getElementById("linkThree");
        const linkFour = document.getElementById("linkFour");
        const linkFive = document.getElementById("linkFive");
        
        linkOne.addEventListener('focusin', (event) => {
            event.target.style["font-weight"] = 'bold';    
        });

        linkOne.addEventListener('blur', (event) => {
            event.target.style["font-weight"] = 'normal';    
        });
        
        linkTwo.addEventListener('focusin', (event) => {
            event.target.style["font-weight"] = 'bold';    
        });

        linkTwo.addEventListener('blur', (event) => {
            event.target.style["font-weight"] = 'normal';    
        });
        
        linkThree.addEventListener('focusin', (event) => {
            event.target.style["font-weight"] = 'bold';    
        });

        linkThree.addEventListener('blur', (event) => {
            event.target.style["font-weight"] = 'normal';    
        });
        
        linkFour.addEventListener('focusin', (event) => {
            event.target.style["font-weight"] = 'bold';    
        });

        linkFour.addEventListener('blur', (event) => {
            event.target.style["font-weight"] = 'normal';    
        });
        
        linkFive.addEventListener('focusin', (event) => {
            event.target.style["font-weight"] = 'bold';    
        });

        linkFive.addEventListener('blur', (event) => {
            event.target.style["font-weight"] = 'normal';    
        });
    });
</script>
<nav class="navbar" role="navigation" aria-label="main navigation">
    <div class="navbar-brand">
        <a href="/" class="navbar-item">
        </a>
    </div>
    <div class="nav-menubar">
        <div class="navbar-menu">
            <a id="linkOne" href="/" class="navbar-item" class:is-active={segment === undefined}>LinkOne</a>
            <a id="linkTwo" href="/linkTwo" class="navbar-item" class:is-active={segment === "linktwo"}>LinkTwo</a>
            <a id="linkThree" href="/linkThree" class="navbar-item" class:is-active={segment === "linkthree"}>LinkThree</a>
            <a id="linkFour" href="/linkFour" class="navbar-item" class:is-active={segment === "linkfour"}>LinkFour</a>
            <a id="linkFive" href="/linkFive" class="navbar-item" class:is-active={segment === "linkfive"}> LinkFive</a>
        </div>
    </div>
</nav>

On Firefox(81.0), this results in a link becoming bold onFocus but when switching to another link and back, the same link doesn't become bold unless clicked twice. Also, I am not certain that this is the best way to set the style for these components. Can someone suggest a better way to do this?

2

There are 2 answers

3
Stephane Vanraes On

You can replace all that JavaScript with one simple CSS rule instead:

a:focus {
  font-weight: bold;
}
0
Mohammad Reza Karimi On

You can achieve it easily in Svelte:

<script>
  let current = 0;
</script>

<a
  on:click="{() => current = 1}"
  class:active="{current === 1}"
>Number 1</a>

<a
  on:click="{() => current = 2}"
  class:active="{current === 2}"
>Number 2</a>

<a
  on:click="{() => current = 3}"
  class:active="{current === 3}"
>Number 3</a>

<style>
  a {
    display: block;
  }

  .active {
    color: rgb(255, 133, 34);
    font-weight: bolder;
  }
</style>

Also you can learn more on: https://svelte.dev/tutorial/classes