1

Currently doing some exercise for CSS/Javascript animation. I'm attempting to make a Carousel slider from scratch.. I have 4 divs with 550px in width nested in a wrapper of 2200px, which is then nested in a 550px wrapper with overflow hidden.

I then created 4 LI's that I want to make clickable so that it'll translate the wrapper -550*I degrees for every LI.

I performed a queryselectorall to get all the li's, looped through it with a for loop, and created a function that should apply onclick functionality for each LI button.

The issue that I'm running into is that the first calculation of this transform property is applied to all LI's (the 550 * i for [1] [2] and [3] aren't applied).

Here's the HTML that I'm currently using.

<div id="container">
    <div id="wrapper">
        <div id="itemOne" > 
        </div>

        <div id="itemTwo">
        </div>

        <div id="itemThree">
        </div>

        <div id="itemFour"> 
        </div>
    </div>

</div>

<ul>
    <li class="button"></li>
    <li class="button"></li>
    <li class="button"></li>
    <li class="button"></li>
</ul>

The Javascript

        var wrapper = document.querySelector("#wrapper");
        var buttons = document.querySelectorAll(".button");

        for(var i = 0; i < buttons.length; i++){
            var curBut = buttons[i];

            curBut.addEventListener("click", function(){
                wrapper.style[transformProperty] = 'translate3d(-'+((0-i) * 550) +'px,0,0'
            })

            console.log(((0-i) * 550));
        }
        console.log(buttons);


        var transforms = ["transform",
                        "msTransform",
                        "webkitTransform",
                        "mozTransform",
                        "oTransform"];

        var transformProperty = getSupportedPropertyName(transforms);

        function getSupportedPropertyName(properties) {
            for (var i = 0; i < properties.length; i++){
                if(typeof document.body.style[properties[i]] != "undefined") {
                    return properties[i];
                }
            }
            return null;
        }

If anyone could explain why the function isn't applying the different changes for the wrapper for each LI, that'd be great! Thanks!!

  • 1
    Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Teemu Nov 25 '17 at 08:58

1 Answers1

0

The global variable i is not copied into each listener, it's shared between the listeners. When you click a button, i is already set to its final value which is 4. As a possible workaround you could override the global variable with a local variable, and get the index on click using indexOf :

var wrapper = document.querySelector("#wrapper");
var buttons = document.querySelectorAll("button");

for (var i = 0; i < buttons.length; i++) {
  var curBut = buttons[i];
  curBut.addEventListener("click", function() {
    var i = Array.prototype.indexOf.call(buttons, this);
    wrapper.style[transformProperty] = 'translate3d(-' + (i * 260) + 'px,0,0)';
  });
}

var transforms = ["transform",
                  "msTransform",
                  "webkitTransform",
                  "mozTransform",
                  "oTransform"];

var transformProperty = getSupportedPropertyName(transforms);

function getSupportedPropertyName(properties) {
  for (var i = 0; i < properties.length; i++) {
    if (typeof document.body.style[properties[i]] != "undefined") {
      return properties[i];
    }
  }
  return null;
}
#container {
  overflow: hidden;
  background: gray;
  margin-bottom: 1em;
  width: 260px;
  height: 100px;
}
#wrapper {
  width: calc(4 * 260px);
  height: 100px;
}
#wrapper div {
  padding: 0 1em;
  width: calc(260px - 2em);
  line-height: 100px;
  height: 100px;
  float: left;
  color: white;
  font-size: 3em;
  font-weight: bold;
  text-align: center;
}
<div id="container">
  <div id="wrapper">
    <div id="itemOne">1</div>
    <div id="itemTwo">2</div>
    <div id="itemThree">3</div>
    <div id="itemFour">4</div>
  </div>
</div>
<div>
  <button type="button">button 1</button>
  <button type="button">button 2</button>
  <button type="button">button 3</button>
  <button type="button">button 4</button>
</div>
  • Hey! Thanks for the thorough explanation! Really appreciate it! – optic_elation Nov 25 '17 at 23:01
  • @optic_elation Did it help to solve your problem ? Is there any remaining detail to clarify ? –  Nov 26 '17 at 07:00
  • Hey, they definitely did. Checked out some of your other javascript explanations, super helpful!! It clarifies some of the major JS concepts in a short and concise summary. love it! – optic_elation Nov 30 '17 at 09:36
  • @optic_elation So sweet, thanks ! Don't forget to vote if possible, this is how Stackoverflow works after all :-) –  Nov 30 '17 at 19:34