Search code examples
javascriptfunctiononmouseoveronmouseout

Create onmouseover/onmouseout functions dynamically with javascript?


So here is an example of the function I need to replicate:

document.getElementById('img1').onmouseover = function() {
    document.getElementById('img1').style.width = expandTo + '%';

    expandCompensate(1);
}

document.getElementById('img1').onmouseout = function() {
    expandReset();
}

The situation is that I have a for loop creating some div elements, and the number of them is dynamic. As of right now, I have it creating 4 div elements, so I created 4 iterations of the above functions for img1, img2, img3 and img4. But what I would like to do is to have the onmouseover and onmouseout functions created dynamically based on how many div elements I've decided to create (based on a variable).

Is there any way to do this? Here is all the code for context (it's not much), there are comments in the JS with explanations for everything. The part I'm trying to automate is at the bottom:

https://jsfiddle.net/4w0714su/3/

And here is the working example for context of what I'm trying to achieve:

http://www.ericsartor.ca/imgwide

FYI: The image is I picked were random, I just needed high res images. Just doing this for practice! Thanks to anyone that can help me figure this out!


Solution

  • I can't understand your code very well, but I'll answer particularly what you're asking.

    You can achieve what you want by doing a loop:

    for (var i = 0; i < 4; i++) {
      document.getElementById('img' + i).onmouseover = function() {
        this.style.width = expandTo + '%';
        expandCompensate(Number(this.id.replace('img', '')));
      };
    
      document.getElementById('img' + i).onmouseout = function() {
        expandReset();
      }
    }
    

    Note: you can't use the i variable inside the event handlers' functions, because it will always be 4, since it will finish the loop, and will never be changed again.


    Another way of doing that is by using an IIFE (Immediately-invoked function expression), e.g:

    for (var i = 0; i < 4; i++) {
      (function(n) {
        document.getElementById('img' + n).onmouseover = function() {
          this.style.width = expandTo + '%';
          expandCompensate(n);
        };
    
        document.getElementById('img' + n).onmouseout = function() {
          expandReset();
        }
      })(i);
    }
    

    Doing that, you're passing to a function the current i value, so in that scope, the value of n will be a different one for each execution, e.g 0, 1, 2 and 3.

    An immediately-invoked function expression (or IIFE, pronounced "iffy") is a JavaScript design pattern which produces a lexical scope using JavaScript's function scoping.