Hovering true your navbar:

Hey Guys

I have a problem using eventlistners on my navbar of the header. I want the links to switch color when I hover on them. The problem I have is that, although I specify ID per link, only 1 link switches color. Can someone help me with my code to alter this so only the link I hover switches (it switches back on mouseout). Here below my relevant code:

HTML header:

<!DOCTYPE html>
<html>
    <head>
        <title>The Merksem City Running Club</title>
        <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
        <link rel="stylesheet" href="style.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="The Merksem City Running Club" content="">
        <link rel="preconnect" href="https://fonts.gstatic.com">
        <link href="https://fonts.googleapis.com/css2?family=Montserrat+Subrayada:wght@700&family=Tauri&display=swap" rel="stylesheet">    
    </head>
    <body>
        <header>
                <nav class="navbar">
                        <a id='navlink1'>Upcoming Events</a>
                        <a id='navlink2'>Close Running tracks</a>
                        <a id='navlink3'>To visit run Area</a>
                        <a id='navlink4'>Team Results</a>
                        <a id='navlink5' href='signup.php' >Sign up</a>
                        <a id='navlink6' href='login.php' >Login</a>
                </nav>
            <h1 class="pageheader">The Merksem City Running Club</h1>
        </header>

Relevant CSS:

/* General + header */

body{
    background-color: turquoise;
    font-family: 'Tauri', sans-serif;
    margin: 0;
}

article{
    text-align: center;
}

.navbar{
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
    position: sticky;
    background-color: darkslategray;
    color: turquoise;
    position: fixed;
    top: 0;
    width: 100%;
}


a#navlink1, a#navlink2, a#navlink3, a#navlink4, a#navlink5, a#navlink6{
    text-transform: uppercase;
    font-size: 20px;
    color: turquoise;
    text-decoration: none;
}

.pageheader{
    text-align: center;
    background-image: url("Images/dreef.png"); 
    background-repeat: no-repeat;
    background-size: cover;
    background-position: bottom;
    padding: 15% 0;
    margin-top: 40%;
}

h1{
    font-family: 'Montserrat Subrayada', sans-serif;
    color: whitesmoke;
}
.turquoisezone{
    height: 25px;
    background-color: turquoise;
}

The Javascript I am building so far. As said before, the hovering works but only for 1 link when you hover, and this is the last one always that i added in the JS file.

//JS on the header-links

  //navhover1
let link1 = document.getElementById('navlink1');

function colorHover () {
  link1.style.color = "red";
}

function colorHoverBack () {
  link1.style.color = "turquoise";
}

link1.onmouseover = colorHover;
link1.onmouseout = colorHoverBack;

  //navhover2
let link2 = document.getElementById('navlink2');

function colorHover () {
  link2.style.color = "red";
}

function colorHoverBack () {
  link2.style.color = "turquoise";
}

link2.onmouseover = colorHover;
link2.onmouseout = colorHoverBack;

  //navhover3
let link3 = document.getElementById('navlink3');

function colorHover () {
  link3.style.color = "red";
}

function colorHoverBack () {
  link3.style.color = "turquoise";
}

link3.onmouseover = colorHover;
link3.onmouseout = colorHoverBack;

  //navhover4-6
let link4 = document.getElementById('navlink4');

let link5 = document.getElementById('navlink5');

let link6 = document.getElementById('navlink6');

Thanks for your help on this topic. Eventlistners seemed so easy in the beginning :smiley:

Kind regards,

Yannick

Hey guys

I solved the issue by renaming the functions, but this seems a bit of a long code to this, can i do it shorter? :slight_smile:


//JS on the header-links

  //navhover1
let link1 = document.getElementById('navlink1');

function colorHover1 () {
  link1.style.color = "red";
}

function colorHoverBack1 () {
  link1.style.color = "turquoise";
}

link1.onmouseover = colorHover1;
link1.onmouseout = colorHoverBack1;

  //navhover2
let link2 = document.getElementById('navlink2');

function colorHover2 () {
  link2.style.color = "red";
}

function colorHoverBack2 () {
  link2.style.color = "turquoise";
}

link2.onmouseover = colorHover2;
link2.onmouseout = colorHoverBack2;

  //navhover3
let link3 = document.getElementById('navlink3');

function colorHover3 () {
  link3.style.color = "red";
}

function colorHoverBack3 () {
  link3.style.color = "turquoise";
}

link3.onmouseover = colorHover3;
link3.onmouseout = colorHoverBack3;

  //navhover4
let link4 = document.getElementById('navlink4');

function colorHover4 () {
  link4.style.color = "red";
}

function colorHoverBack4 () {
  link4.style.color = "turquoise";
}

link4.onmouseover = colorHover4;
link4.onmouseout = colorHoverBack4;

 //navhover5
let link5 = document.getElementById('navlink5');

function colorHover5 () {
  link5.style.color = "red";
}

function colorHoverBack5 () {
  link5.style.color = "turquoise";
}

link5.onmouseover = colorHover5;
link5.onmouseout = colorHoverBack5;

 //navhover6
let link6 = document.getElementById('navlink6');

function colorHover6 () {
  link6.style.color = "red";
}

function colorHoverBack6 () {
  link6.style.color = "turquoise";
}

link6.onmouseover = colorHover6;
link6.onmouseout = colorHoverBack6;

//end navigationhovers



Also it doesn’t work on phone screen xs → is this because you don’t have a mouse on your phone?

1 Like

Hi net,
Is there any reason you didn’t just use :hover in the css?

2 Likes

I would give the <nav> an id, given you will very likely only have one navbar:

                <nav id="navbar">
                        <a id='navlink1'>Upcoming Events</a>
                        <a id='navlink2'>Close Running tracks</a>
                        <a id='navlink3'>To visit run Area</a>
                        <a id='navlink4'>Team Results</a>
                        <a id='navlink5' href='signup.php' >Sign up</a>
                        <a id='navlink6' href='login.php' >Login</a>
                </nav>

then you can select all anchor elements:

const links = document.querySelectorAll('#navbar a')

and utilize a loop to attach event listener to each anchor element.

we can’t do mouseout with css? You could make the nav links/anchor elements turquoise by default (using css) and then we could use hover. But that would depend on the requirements/desired outcome.

I have changed my name a lot already but the net135163153453 doesn’t alter with it :slight_smile:

1 Like

So a for loop on the navbar would scroll true the different link tags?

I am going to try this :smiley:

Kr,

Yannick

Hey

I’ve tried doing this using a loop:
I am probably looping wrong, is the solution close to where I get or not?

const links = document.querySelectorAll('#navbar a')


for (var i = 0; i < links.length; i++) {
  function colorHover () {
    link[i].style.color = "red";
  }
  function colorHoverBack () {
    link[i].style.color = "turquoise";
  }
  link[i].onmouseover = colorHover;
  link[i].onmouseout = colorHoverBack;
 }

Seems you need to use addEventListener:

Element: mouseover event - Web APIs | MDN

this will allow you to pass the event to the (callback) function, from which we can get the target element (event.target)

1 Like

I don’t really understand that documentation in combination with the for loop.

The way I use eventhandlers doesn’t make it to work.

const links = document.querySelectorAll('#navbar a')

for (var i = 0; i < links.length; i++) {
  function colorHover (event) {
    event.link[i].style.color = "red";
  }
  function colorHoverBack (event) {
    event.link[i].style.color = "turquoise";
  }
  link[i].addEventListener('onmouseover',colorHover);
  link[i].addEventListener('onmouseout', colorHoverBack);
 }


Why do we need to re-declare/re-define the callback function (colorHover and colorHoverBack ) every iterations of the loop? They don’t change, so move them outside the loop

here:

 link[i].addEventListener('onmouseover',colorHover);

what is link? is undefined variable, to get the link you are currently looping over use the index (i) on the array:

links[i]

as you can see from the MDN documentation:

  // highlight the mouseenter target
  event.target.style.color = "purple";

the event also contains information on the target (the element you want to style, or do whatever)

I can understand its a lot, given the abstraction and the amount of information you have to filter through, but I hope this somewhat helps

1 Like

Hey Stetim

Yes that helped a lot! I got there and understood how it worked!

thank you! For other people following this topic, this is the correct formula:

const links = document.querySelectorAll('#navbar a')

  function colorHover(event) {
    event.links.style.color = "red";
  }
  function colorHoverBack(event) {
    event.links.style.color = "turquoise";
  }

for (var i = 0; i < links.length; i++) {
  links[i].addEventListener('onmouseover', colorHover);
  links[i].addEventListener('onmouseout', colorHoverBack);
 }

No sorry, incorrect, my browser cached the previous code I deleted.

kr,

Yannick

Hi Yannick,
Try logging out and logging back in again in the forums, it should update your name :slight_smile:

Also, you can use .forEach() instead of a for loop, if you want (I just tried it…!).

here:

 event.links.style.color = "red";

shouldn’t it be event.target.style.color? There is a lot of abstraction here, who-ever wrote the addEventListener function/method, also constructed the event object. You can always use .log() to see the entire object (which is no doubt very large)

I let the user/learner choice whatever loop he was comfortable with, there is a lot of abstraction already

Hey Ronsok, Stetim

I also tried with for each, probably I’m not building right:

const links = document.querySelectorAll('#navbar a');

  function colorHover(event){
    event.target.style.color = "red";
  }
    function colorHoverBack(event){
    event.target.style.color = "turquoise";
  }

links.forEach((item) => {
  item.addEventListener('onmouseover', colorHover)});

links.forEach((item) => {
  item.addEventListener('onmouseout', colorHoverBack)});

I don’t think it is possible with the for loop. That just doesn’t work.

const links = document.querySelectorAll('#navbar a');

  function colorHover(event){
    event.target.style.color = "red";
  }
    function colorHoverBack(event){
    event.target.style.color = "turquoise";
  }

for (let i = 0; i < links.length; i++){
  links[i].addEventListener('onmouseover', colorHover);
  links[i].addEventListener('onmouseout', colorHoverBack);
}

Btw, I have logged in and out already a dozen times since I changed my name to a profile name, it just keeps sayin Net1354684643486 above instead of Muski :smiley:

I also tried it like this:

document.querySelectorAll('#navbar a').forEach(item => {
  item.addEventListener('onmouseover', event => {
    style.color = "red";
  })
})

document.querySelectorAll('#navbar a').forEach(item => {
  item.addEventListener('onmouseout', event => {
    style.color = "turquoise";
  })
})

again doesn’t work. I’m gonna give up now. You would be very kind to show me your for each code because I cannot find it myself. I have never understood the MDN documentation so reading that doesn’t help.

thanks for advices!

kr,

Yannick

Actually, I had it working. So it does work. You are really close, if you inspect the html with the debug tools, you can see the events attached.

but the problem is that the event is mouseenter as you can see in the MDN documentation:

test.addEventListener("mouseenter", function( event ) {

so without on.

Is there a reason that you’re attempting to do this with event handlers, and not just natively in the CSS?

You could quite easily do as @stetim94 suggested, and give the navbar an ID

                <nav id="navbar">
                        <a id='navlink1'>Upcoming Events</a>
                        <a id='navlink2'>Close Running tracks</a>
                        <a id='navlink3'>To visit run Area</a>
                        <a id='navlink4'>Team Results</a>
                        <a id='navlink5' href='signup.php' >Sign up</a>
                        <a id='navlink6' href='login.php' >Login</a>
                </nav>

and then do the following in the CSS

#navbar a {
    color: turquoise;
}
#navbar a:hover {
    color: red;
}

Using JS, unless you’re doing it specifically to comply with the requirements of an assignment or something, is overkill for switching the colours of an anchor element on hover…

We mentioned this, but no response from the user/learner. Reason: unknown. Could be be to do with JavaScript for learning purpose

The only difference between css hover and javascript, is that in JavaScript we have an initial state (default color), a hover color, and then turquoise after hover, not before. This can’t be done with CSS so far I know.

1 Like

Hey guys

sorry for the late respons.

Stetim is right. I didn’t know initial I could do it with CSS. So I tried it with JS.
After that I wanted to know how to get it as short as possible, all for learning courses.

Because this is when I still struggle with JS, when I have to combine things :slight_smile: . Just trying to get fluent with all aspects.

kr,

yannick