0

Hello i am new to javascript

So i got a bunch of buttons inside my HTML and i am collecting them in JS file. I want to add all of them a mouseover and mouseout events and i want to change their styles inside with JS.

When i try to send HTMLButtonElement to function as a parameter,

for (const button of buttons){
    button.addEventListener('mouseover',buttonStyleChange(button))
}

function buttonStyleChange(btn){
    btn.style.backgroundColor = "green";
    btn.style.transform = "scale(1.2)";
}

function seems it already fired. Can somebody explain why and how to solve that issue?

Thanks

const buttons = document.querySelectorAll('button');

for (const button of buttons){
    button.addEventListener('mouseover',buttonStyleChange(button))
}


function buttonStyleChange(btn){
    btn.style.backgroundColor = "green";
    btn.style.transform = "scale(1.2)";
}
body{
  display: grid;
  place-content: center;
  background-color: bisque;
  min-height: 100vh;
  gap:20px;
}

button{
  font-family: Arial, Helvetica, sans-serif;
  color:black;
  font-size: 1.5rem;
  font-weight: 700;
  padding: 0.5rem;
  text-transform: uppercase;
  border-radius: 1rem;
  cursor: pointer;
}
<button>Change color</button>
<button>Change color</button>
<button>Change color</button>
<button>Change color</button>
<button>Change color</button>

1
  • If this is just for learning JS, I have nothing against this approach, but I recommend you using CSS transitions and animations if you will it use on a real webpage. It is usually easier to declare transitions and you do not have to handle some problematic situations like mouse going out of the window etc. Commented Apr 8, 2022 at 17:06

1 Answer 1

1

Use lambda functions (anonymous functions) here (described below):

const buttons = document.querySelectorAll('button');

for (const button of buttons){
    button.addEventListener('mouseover',(event) => buttonStyleChange(event.target))
}


function buttonStyleChange(btn){
    btn.style.backgroundColor = "green";
    btn.style.transform = "scale(1.2)";
}
body{
  display: grid;
  place-content: center;
  background-color: bisque;
  min-height: 100vh;
  gap:20px;
}

button{
  font-family: Arial, Helvetica, sans-serif;
  color:black;
  font-size: 1.5rem;
  font-weight: 700;
  padding: 0.5rem;
  text-transform: uppercase;
  border-radius: 1rem;
  cursor: pointer;
}
<button>Change color</button>
<button>Change color</button>
<button>Change color</button>
<button>Change color</button>
<button>Change color</button>

First, I'll describe what the addEventListener does:

It has three variants:

addEventListener(type, listener);
addEventListener(type, listener, options);
addEventListener(type, listener, useCapture);

You will probably never use the latter two.

It adds (not replaces) an event listener to the given event on the given node. When you call button.addEventListener('click', function), the function function will be called when the node represented by the variable button is clicked. You probably already know this.

But the interesting part is how the listener (your function) is called. It is called with one argument. And this value of the argument is a object of class Event. And the object gives you information about the event, like mouse position (for mouse events), pressed key (for key events), target element (which was clicked, or key was pressed in it etc.), etc.

You can create this function:

function handleClickEvent(event) {
    //                ↓↓↓↓↓↓↓↓↓↓↓↓ get the clicked button
    buttonStyleChange(event.target)
}

And when you use it as a listener, it will call the buttonStyleChange function with the button as a argument.

At the beginning of the answer, I wrote about lambda functions (a.k.a. anonymous functions). That is simply a way to declare unnamed function and use it in the same place.

You can create it like this:

let myFunction = function (arg1, arg2) {
    // …
}

As you can see, even the function is just a value and it can be passed to the addEventListener.

Another syntax for this is the arrow notation (a bit newer and slightly different):

let myFunction = (arg1, arg2) => onlyOneExpression
// or this
let myFunction = (arg1, arg2) => {
    // …
}

The second variant is nearly the same as the function (…) { … } syntax. And the first variant allows only one expression to be used (and the expression value is returned by the anonymous function).

You can learn more about anonymous functions on the MDN page about them.

There are some subtle differences between the two kinds of anonymous functions.

When you will be learning about the anonymous functions, you will probably hear also about closures. That is kind of (usually anonymous) function that uses variables from the function in which it was created.

Sign up to request clarification or add additional context in comments.

1 Comment

thank you for your explanations. So basically what i understood is when we add an event listener to any html element and run a function when that event fires, we can use some properties about that event inside the function we called.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.