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 >
<div ></div>
<div ></div>
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
<div >5</div>
<div >6</div>
</div>
<div ></div>
</div>
CodePudding user response:
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 onm ouseout
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 >
<div ></div>
<div ></div>
<div >
<div >
1
</div>
<div >
2
</div>
<div >
3
</div>
<div >
4
</div>
<div >
5
</div>
<div >
6
</div>
</div>
<div ></div>
</div>
CodePudding user response:
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 >
<div ></div>
<div ></div>
<div >
<div >
1
</div>
<div >
2
</div>
<div >
3
</div>
<div >
4
</div>
<div >
5
</div>
<div >
6
</div>
</div>
<div ></div>
</div>
CodePudding user response:
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 >
<div ></div>
<div ></div>
<div >
<div >1</div>
<div >2</div>
<div >3</div>
<div >4</div>
<div >5</div>
<div >6</div>
</div>
<div ></div>
</div>