skip to Main Content

I am trying to create a really simple slider using 2 buttons the will increase the margin when hovered over. I would like the buttons to increase or decrease the margins continuously.

At the minute I can only get them to move in set chunks. Could anyone point me in the right direction?

var left = document.querySelector(".left");
var right = document.querySelector(".right");
var slide = document.querySelector(".slider");

left.onmouseover = function() {
  var currentLeftMargin = getComputedStyle(slide).marginLeft;
  console.log(currentLeftMargin);

  // Element's style = number portion of current style, then do math, then add back on the unit
  slide.style.marginLeft = (parseInt(currentLeftMargin, 10) - 900) + "px";
}

right.onmouseover = function() {
  var currentLeftMargin = getComputedStyle(slide).marginLeft;
  console.log(currentLeftMargin);

  // Element's style = number portion of current style, then do math, then add back on the unit
  slide.style.marginLeft = (parseInt(currentLeftMargin, 10) + 900) + "px";
}
``` .slide-container {
  height: 300px;
  width: 100%;
  background-color: blue;
  position: relative;
  overflow: hidden;
}

.left {
  position: absolute;
  height: 20px;
  width: 20px;
  background-color: red;
  top: 50%;
  left: 0;
}

.right {
  position: absolute;
  height: 20px;
  width: 20px;
  background-color: red;
  top: 50%;
  right: 0;
}

.slider {
  height: 300px;
  width: 100%;
  display: flex;
  left: 0;
  transition: all ease 1s;
}

.slider:hover {}

.item {
  display: block;
  height: 300px;
  width: 300px;
  min-width: 300px;
  background-color: green;
  margin-left: 10px;
}
<div class="slide-container">
  <div class="left"></div>
  <div class="right"></div>
  <div class="slider">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
  </div>
  <div class="fade"></div>
</div>

3

Answers


  1. You would need an interval which sets the margin at consequent steps, by creating an Interval with setInterval(function(), milliseconds);
    To be able to terminate the interval and preventing of creating endless amounts of intervals, we need to store the ID of the Interval in a variable.

    iId = setInterval(function(), milliseconds);

    We then would terminate the interval if the mouse leaves the element by clearInterval(IntervalID);

    As you used a css-transition to smoothen the animation, i had to fiddle abit with the steps of margin increase and decrease and the interval, so there aren’t any "jumps".

    var left = document.querySelector(".left");
    var right = document.querySelector(".right");
    var slide = document.querySelector(".slider");
    
    // Amount of Pixels the margin gets increased and decreased
    let steps = 50;
    // Amount of milliseconds after the margin will be adjusted again
    let interval = 100;
    // Variable to store IntervalID to be able to terminate it onmouseout
    let iId;
    
    left.onmouseover = function(){
      iId = setInterval(() => {
        var currentLeftMargin = getComputedStyle(slide).marginLeft;
        // Element's style = number portion of current style, then do math, then add back on the unit
        slide.style.marginLeft = (parseInt(currentLeftMargin, 10) + steps) + "px";
      }, interval)
    }
    left.onmouseout = () => {
      clearInterval(iId);
    }
    
    right.onmouseover = function(){
      iId = setInterval(() => {
        var currentLeftMargin = getComputedStyle(slide).marginLeft;
      
        // Element's style = number portion of current style, then do math, then add back on the unit
        slide.style.marginLeft = (parseInt(currentLeftMargin, 10) - steps) + "px";
      }, interval)
    }
    right.onmouseout = () => {
      clearInterval(iId);
    }
    .slide-container {
      height: 300px;
      width: 100%;
      background-color: blue;
      position: relative;
      overflow: hidden;
    }
    
    .left {
      position: absolute;
      height: 20px;
      width: 20px;
      background-color: red;
      top: 50%;
      left: 0;
    }
    
    .right {
      position: absolute;
      height: 20px;
      width: 20px;
      background-color: red;
      top: 50%;
      right: 0;
    }
    
    .slider{
      height: 300px;
      width: 100%;
      display:flex;
      left:0;
      
      transition: all ease 0.25s;
    }
    .slider:hover{
      
    }
    
    .item{
      display:block;
      height: 300px;
      width: 300px;
      min-width: 300px;
      background-color: green;
      margin-left:10px;
    }
    <div class="slide-container">
      <div class="left"></div>
      <div class="right"></div>
      <div class="slider">
        <div class="item">
          1
        </div>
        <div class="item">
          2
        </div>
        <div class="item">
          3
        </div>
        <div class="item">
          4
        </div>
        <div class="item">
          5
        </div>
        <div class="item">
          6
        </div>
      </div>
      <div class="fade"></div>
    </div>
    Login or Signup to reply.
  2. You can use setInterval to repeat the movement you’re currently doing in onmouseover for it to keep advancing.
    Remember to clearInterval in onmouseout
    Here’s an example

    var left = document.querySelector(".left");
    var right = document.querySelector(".right");
    var slide = document.querySelector(".slider");
    
    var moveLeftInterval;
    var moveRightInterval;
    var moveLeft = () => {
      var currentLeftMargin = getComputedStyle(slide).marginLeft;
      console.log(currentLeftMargin);
    
      // Element's style = number portion of current style, then do math, then add back on the unit
      slide.style.marginLeft = (parseInt(currentLeftMargin, 10) - 900) + "px";
    }
    
    var moveRight = () => {
      var currentLeftMargin = getComputedStyle(slide).marginLeft;
      console.log(currentLeftMargin);
    
      // Element's style = number portion of current style, then do math, then add back on the unit
      slide.style.marginLeft = (parseInt(currentLeftMargin, 10) + 900) + "px";
    }
    
    left.onmouseover = function() {
      moveLeftInterval = setInterval(moveLeft, 200);
    }
    
    left.onmouseout = function() {
      clearInterval(moveLeftInterval);
    }
    
    right.onmouseover = function() {
      moveRightInterval = setInterval(moveRight, 200);
    }
    
    
    right.onmouseout = function() {
      clearInterval(moveRightInterval);
    }
    .slide-container {
      height: 300px;
      width: 100%;
      background-color: blue;
      position: relative;
      overflow: hidden;
    }
    
    .left {
      position: absolute;
      height: 20px;
      width: 20px;
      background-color: red;
      top: 50%;
      left: 0;
    }
    
    .right {
      position: absolute;
      height: 20px;
      width: 20px;
      background-color: red;
      top: 50%;
      right: 0;
    }
    
    .slider {
      height: 300px;
      width: 100%;
      display: flex;
      left: 0;
      transition: all ease 1s;
    }
    
    .slider:hover {}
    
    .item {
      display: block;
      height: 300px;
      width: 300px;
      min-width: 300px;
      background-color: green;
      margin-left: 10px;
    }
    <div class="slide-container">
      <div class="left"></div>
      <div class="right"></div>
      <div class="slider">
        <div class="item">
          1
        </div>
        <div class="item">
          2
        </div>
        <div class="item">
          3
        </div>
        <div class="item">
          4
        </div>
        <div class="item">
          5
        </div>
        <div class="item">
          6
        </div>
      </div>
      <div class="fade"></div>
    </div>
    Login or Signup to reply.
  3. To do what you require you can use an interval which you set to update each frame of movement of the .slide element.

    You can also use Math.min() and Math.max() to limit the movement of the slider to its contents.

    let left = document.querySelector(".left");
    let right = document.querySelector(".right");
    let slide = document.querySelector(".slider");
    let interval;
    let frameDelta = 40;
    
    let updateSlidePosition = delta => {
      var currentLeftMargin = getComputedStyle(slide).marginLeft;
      slide.style.marginLeft = Math.max(slide.offsetWidth * -1, Math.min(0, parseInt(currentLeftMargin, 10) + delta)) + "px";
    }
    
    left.addEventListener('mouseenter', e => {
      interval = setInterval(() => updateSlidePosition(frameDelta * -1), 40);
    })
    left.addEventListener('mouseleave', () => clearInterval(interval));
    
    right.addEventListener('mouseenter', e => {
      interval = setInterval(() => updateSlidePosition(frameDelta), 40);
    })
    right.addEventListener('mouseleave', () => clearInterval(interval));
    .slide-container {
      height: 300px;
      width: 100%;
      background-color: blue;
      position: relative;
      overflow: hidden;
    }
    
    .left {
      position: absolute;
      height: 20px;
      width: 20px;
      background-color: red;
      top: 50%;
      left: 0;
    }
    
    .right {
      position: absolute;
      height: 20px;
      width: 20px;
      background-color: red;
      top: 50%;
      right: 0;
    }
    
    .slider {
      height: 300px;
      width: 100%;
      display: flex;
      left: 0;
      transition: margin-left 0.1s;
    }
    
    .slider:hover {}
    
    .item {
      display: block;
      height: 300px;
      width: 300px;
      min-width: 300px;
      background-color: green;
      margin-left: 10px;
    }
    <div class="slide-container">
      <div class="left"></div>
      <div class="right"></div>
      <div class="slider">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
      </div>
      <div class="fade"></div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search