0

I have a function that looks at an array of objects and runs a for loop to iterate through and creates a couple jquery functions. Everything is working great, except when it finishes the DOM only sees the last iteration of the for loop. It's printing out buttons on a page and I want each button to display the tooltip that is associated with it so I'm needing each iteration of the for loop to be available. Any help or tips to clean this up would be great!

$(window).load(function () {
            var i;
            for (i = 1; i <= array.length; i++) {
                (function(){
                var invbuttons = "#invbuttons" + i;
                var tooltip = "#tooltip" + i;
                $(invbuttons).on("mouseover", function () {
                    $(tooltip).css({
                        visibility: "visible",
                        width: "500px"
                    });
                });
                $(invbuttons).on("mouseout", function () {
                    $(tooltip).css({
                        visibility: "hidden",
                        width: "0px"
                    });
                });

            })}
        });
mgarcia
  • 5,669
  • 3
  • 16
  • 35
MattP
  • 3
  • 1
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Shilly Sep 20 '19 at 13:13
  • Also keep in mind that JQuery allows you to delegate the event, so you won't need the number: `$(invbuttonsParent).on( "mouseover", ".invbuttons", function() { ... })`. – Shilly Sep 20 '19 at 13:15
  • Also keep in mind that CSS has the `:hover` rule, to accomplish style changes between hovering an element. – Shilly Sep 20 '19 at 13:16

1 Answers1

1

I think there's an easier, more elegant solution.

You can set up a generic class for all those buttons, like .invbuttons.

Then it's easy to get a list of them with the querySelectorAll javascript method:

document.querySelectorAll('.invbuttons').forEach(btn => {
    btn.addEventListener('mouseover', onMouseOver)
    btn.addEventListener('mouseout', onMouseOut)
})

Lastly you only have to declare the appropriate methods for each case:

function onMouseOver() {
    ...
}

function onMouseOut() {
    ...
}

Good luck!

eledgaar
  • 758
  • 1
  • 9
  • 16
  • THANKS so much for the advice here. I think I'm close but I'm not able to get my tooltip to display. I replaced the numbers with just generic tooltip class. $(window).load(function(){ document.querySelectorAll('.invbuttons').forEach(btn => { btn.addEventListener('mouseover', onMouseOver) btn.addEventListener('mouseout', onMouseOut) }) function onMouseOver(){ $(".tooltip", this).css({ visibility: "visible", width: "500px" }); var tooltip = $('.tooltip'); } function onMouseOut(){ $(".tooltip", this).css({ visibility: "hidden", width: "500px" }); } }); – MattP Sep 20 '19 at 14:39
  • Do you have a generic tooltip for all the buttons or one for each? – eledgaar Sep 23 '19 at 07:59
  • one for each tooltip. I'm making some progress and finally got it to work... in Chrome not IE..Pasting my function below for any help. $(window).load(function (){document.querySelectorAll('.invbuttons').forEach(btn => {btn.addEventListener('mouseover', onMouseOver)btn.addEventListener('mouseout', onMouseOut) }) function onMouseOver() {$(this).find('.tooltip').css({visibility: "visible",width: "500px"}); }function onMouseOut() {$(this).find('.tooltip').css({ visibility: "hidden",width: "500px"});} }); – MattP Sep 23 '19 at 12:32