1

Here's what I mean, I have a function that sets the background and background position of various LI's to make a social media sprite, now I want to ad a hover event listener to it and when hovered move the background image up -29px from its original position.

so to do that I use a variable that was declared and set in different instances of the for loop (in this case its var "k") k starts as = and then each loop iteration it gets -28 added to it.

I want the function in the event listener in the for loop to use this variable to calculate its hover background position, when I add parameters it just ends up calling itself when the for loop runs (like if I make the function log something) I was able to get it to log var i from its previous loop but its not running when I want it to.

here I leave a snippet

function sprite() {

  var c = document.getElementById("social").children;
  var k = 0;
  var cnc = "";
  for (i = 0; i < c.length; i++) {
    c[i].style.backgroundImage = "url(../Imgs/social_icons.jpg)";
    cnc = String(k) + "px 0px";
    c[i].addEventListener("mouseenter", spriteHover);
    k = k - 28;
    c[i].style.backgroundPosition = cnc;
  }
}

function spriteHover() {
  var c = this.querySelector("li");
  var pnc = "0px -29px";
  c.style.backgroundPosition = pnc;
}
sprite();
alert("working");

/*this is how my function was originally (the way i want it to work but doesnt) notice line 32
function sprite() {

    var c = document.getElementById("social").children;
    var k = 0;
    var cnc = "";
    for (i = 0; i < c.length; i++) {
        c[i].style.backgroundImage = "url(../Imgs/social_icons.jpg)";
        cnc = String(k) + "px 0px";
        c[i].addEventListener("mouseenter", spriteHover(k));
        k = k - 28;
        c[i].style.backgroundPosition = cnc;
    }
}

function spriteHover(k) {
    var c = this.querySelector("li");
    var pnc = k +"px -29px";
c.style.backgroundPosition = pnc;
}
sprite();



*/
.smedia {
  background-color: ;
  height: 20px;
  position: absolute;
}
.smedia > ul {
  position: relative;
  display: inline-block;
  background-color: ;
  left: 836px;
  height: 28px;
  margin-right: 8px;
  margin-top: 8px;
}
.smedia > ul li {
  background-color: black;
  display: inline-block;
  height: 28px;
  width: 28px;
}
.smedia a {
  display: inline-block;
  color: black;
  text-decoration: none;
  height: 28px;
  width: 28px;
}
<nav class="smedia" id="smedia">
  <ul id="social">
    <li>
      <a href="https://www.facebook.com/" class="fb" target="_blank"></a>
    </li><!--

                        --><li>
      <a href="https://twitter.com/?lang=en" class="tt" target="_blank"></a>
    </li><!--

                        --><li>
      <a href="https://www.youtube.com/" class="yt" target="_blank"></a>
    </li><!--

  --><li>
      <a href="https://www.instagram.com/?hl=en" class="ig" target="_blank"></a>
    </li><!--

                        --><li>
      <a href="https://www.tumblr.com/" class="t" target="_blank"></a>
    </li><!--

                        --><li>
      <a href="https://www.google.com/" class="gg" target="_blank"></a>
    </li>
  </ul>
</nav>

, any ideas or corrections will be happily welcomed.

4
  • Can you share your social_icons.png please? Commented Dec 2, 2016 at 17:46
  • here they are, make sure you take off the black background (which i added just so you can see the li's) imgur.com/a/mX510 that's the only way i know how to share them for now. Commented Dec 2, 2016 at 18:08
  • Question. Why are you not using css :hover selector instead of using JS solution? Commented Dec 2, 2016 at 18:14
  • Not that this wouldn't be much better made in CSS but it was intended to be more of a challenge to myself, however I ran into the argument/parameter issue which knowing the answer to will probably be useful in the future. My original version is done all in css with transitions and looks pretty =) Commented Dec 2, 2016 at 18:17

1 Answer 1

1

Simple answer yes. You need a function that creates a whole function and returns that instead of evaluating function statements and return results of the evaluation.

So for example. if i set the line

c[i].addEventListener("mouseenter", spriteHover);

to

c[i].addEventListener("mouseenter", spriteHover(c[i],k));

This looks like its passing the arguments in correctly if you try to alert the parameters in the spriteHover function. But the reason its not working is because instead of assigning a function as the event listener, this statement is assigning the result of the spriteHover function that is being returned when called in the for loop (Putting the brackets after the function name actually makes javascript to call this function).

So in order to pass the parameters but return a whole function to the event listener statement we create another function that actually returns us the function as a whole. e.g.

// Handler that will return a function to the addeventlistener
  function createHoverHandler(param1, param2 ....) {
     return function() {
         spriteHover(param1, param2 ....);
     }
  }

Here is a sample using your code and the creator function. Note that i have changed the mouseenter to mouseover and also added in mouseout as to achieve hover effect we have to define both situation of when the mouse enters a element and when it exits.

Sample code: http://codepen.io/Nasir_T/pen/rWJNKX

Hope this helps understand how to achieve this.

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

3 Comments

Wow this is extremely useful, thank you for the answer and putting in the time to edit it.
Can you please vote and check the answer if this helped. Thanks.
sure, I attempted to vote it up a couple times but I need more rep to be able to do so (forgot the check, got it now).

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.