the difference between calling object and function in javascript
Asked Answered
B

3

5

I'm writing in two files - one is html and one is JavaScript. So to call an object I do

 document.getElementById("nameObj").onmouseover = changeMe;

and in the JavaScript file I do

changeMe = function()
{
 //and here i write the function
}

but now I'm trying to optimize my code and to call a function with objects in it. I created sections (4 of them) and I'm trying to change the color with onmouseover and onmouseout. Here is the code of the html:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="style.css">
        <script src="script.js"> </script>
        <title> test 2</title>
    </head>
    <body>
        <header> </header>
        <div id="wrapper">
        <main>
        <section class="mysection" id="section1"> </section>
        <section class="mysection" id="section2"> </section>
        <section class="mysection" id="section3"> </section>
        <section class="mysection" id="section4"> </section>
        </main>
        <div class="clear"> </div>
        </div>
        <footer> </footer>
                <script>
            (function(){
                var sec = document.getElementsByClassName("mysection");
                for(var i=0; i<3; i++)
                {
                    sec[i].onmouseover=changeMe(sec[i], i);
                    sec[i].onmouseout=changeBack(sec[i]);
                }
            })();   
        </script>
    </body>
</html>

and here is JS:

function changeMe(t_section, count)
{
    if(count==0)
    {
        t_section.style.background="yellow";
    }
    if(count==1)
    {
        t_section.style.background="blue";
    }
    if(count==2)
    {
        t_section.style.background="green";
    }
    if(count==3)
    {
        t_section.style.background="red";
    }
};

function changeBack(t_section)
{
    t_section.style.background="gray";
};

But it's not working. What did I do wrong?

Brendonbrenk answered 25/12, 2015 at 14:36 Comment(1)
Possible duplicate of JavaScript closure inside loops – simple practical exampleWastrel
B
4

Change your script tag to this code:

(function(){
  var sec = document.getElementsByClassName("mysection");
  for(var i = 0; i < 4; i++)
  {
    sec[i].addEventListener('mouseover', function() {
      var index = i;
      return function() {
        changeMe(sec[index], index);
      };
    }());
    sec[i].addEventListener('mouseout', function() {
      var index = i;
      return function() {
        changeBack(sec[index]);
      };
    }());
  }
})();

Check here about event listeners.
Please check this fiddle for the complete working example.

Beside answered 25/12, 2015 at 14:41 Comment(3)
i is from the outer scope, all event handler will call changeBack on sec[2]Disunity
@hege_hegedus Nice catch! Didn't see this :)Beside
@hege_hegedus Yep, still thinking.. :)Beside
B
2

This:

sec[i].onmouseover=changeMe(sec[i], i);
sec[i].onmouseout=changeBack(sec[i]);

You're assigning a function return value to the onmouseover method, yet it expects a function body. Since your functions don't return anything, it's equal to:

changeMe(sec[i], i);
sec[i].onmouseover=undefined;
changeBack(sec[i]);
sec[i].onmouseout=undefined;

Basically, you execute your function instantly, and assign undefined to the onmouse callbacks.

To fix it, assign the function body to the callbacks.

Optimization note, both your functions have themselves as the first parameter and that's not really needed because you can always refer to the event element using this.

Blackford answered 25/12, 2015 at 14:42 Comment(0)
S
1

The () operator (invocation operator) calls a function. So you are basically calling the handlers instead of setting them. One option for adding the handlers is:

// Create a basic array
var sections = [].slice.call(document.querySelectorAll(".mysection"));
// using an array for setting the background colors 
var colors = ['yellow', 'blue', 'green', 'red'];

function hover(event) {
   var color = 'gray';

   if ( event.type === 'mouseover' ) {
      // get the index of the mouseovered element
      // and use it for getting the corresponding color 
      color = colors[ sections.indexOf(this) ];
   }

   this.style.background = color;
}

sections.forEach(function(el) {
    el.addEventListener('mouseover', hover);
    el.addEventListener('mouseout', hover);
});
Skerrick answered 25/12, 2015 at 14:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.