javascript – Passing Function Arguments in an Event Handler

Question:

What are the ways, and most importantly, how to correctly pass arguments to a function in an event handler
For instance:

var menu = document.querySelector('.nav');
var ul = menu.querySelector('ul');
function handler(event, bool) {
    event = event || window.event;
    if(event.target.tagName == 'LI') {
        if(bool) {
            ul.style.backgroundColor = 'red';
        } else {
            ul.style.backgroundColor = '';
        }

    }
}
menu.addEventListener('mouseout',handler.bind(null, event, false), false);
menu.addEventListener('mouseover',handler.bind(this, event, true), false);   

It seems to work, but there is no difference what context I pass to bind , even this , even null , even вася …. Next. The function code was originally:

function handler(event, bool) {
    if(event.target.tagName == 'LI') {
        var ul = menu.querySelector('ul');
        if(bool) {
            ul.style.backgroundColor = 'red';
        } else {
            ul.style.backgroundColor = '';
        }

    }
}

In this case, event == undefined , ul == undefined .
Added a line to the beginning of the function: event = event || window.event;event appeared, rendered var ul = menu.querySelector('ul'); from the function began to work.
So what is the correct way to pass arguments?

Answer:

Use handler.bind(null, false)

With signature function handler(bool, event)

handler.bind(null, false) will just return a function with one argument for the event.

function handler(bool, event) {
  console.log(bool, event);
}

let handleFalse = handler.bind(null, false);
let handleTrue = handler.bind(null, true);

handleFalse('Event 1');
handleTrue('Event 2');

Or you can use a closure (if you don't need the this context):

function getHandler(bool) {
  return function handler(event) {
    console.log(bool, event);
  }  
}

let handleFalse = getHandler(false);
let handleTrue = getHandler(true);

handleFalse('Event 1');
handleTrue('Event 2');

Well, let's put it together:

var menu = document.querySelector('.nav');
var ul = menu.querySelector('ul');
function handler(bool) {
  return function (event) {
    event = event || window.event;
    if(event.target.tagName == 'LI') {
      event.target.style.backgroundColor = bool ? 'red' : '';
    }
  }
}

menu.addEventListener('mouseout',handler(false), false);
menu.addEventListener('mouseover',handler(true), false);
<div class="nav">
  <ul>
    <li>Item 1
    <li>Item 2
    <li>Item 3
    <li>Item 4
  </ul>
</div>

Although, in my opinion, .nav li:hover{} is much better

Scroll to Top