Anyone know how can I set auto-scroll (with loop) in div with overflow:hidden; ?
Example
<div class="container" style="width:500px; max-width:500px; height:100px; max-height:100px; background:#F00; overflow:hidden;">
<div class="element_01" style="width:500px; height:100px; float:left;"></div>
<div class="element_02" style="width:500px; height:100px; float:left;"></div>
</div>
final effect?
Show element_01 -> wait 5 sec -> smooth scroll to element_02 -> wait 5 sec // and repeat
This example uses positioning instead of scrolling.
Scrolling with an overflow hidden element works, but can be buggy.
http://codepen.io/anon/pen/tqgyA
$(document).ready(function() {
var numSlides = $('ul.scroller').children().length,
counter = 0;
windowHeight = $('.window').height();
setInterval(function() {
counter++;
if (counter == numSlides) {
counter = 0;
$('.scroller').css('top', '0');
} else {
var toMove = (counter * windowHeight);
$('.scroller').css('top', '-'+toMove.toString()+'px');
}
}, 2000)
});
html { font-family: Helvetica, Arial }
.window {
width: 300px;
height: 200px;
overflow: hidden;
position: relative;
border: 2px solid skyblue;
}
ul.scroller {
width: 100%;
position: absolute;
top: 0;
left: 0;
list-style-type: none;
padding: 0;
margin: 0;
-webkit-transition: top .5s ease;
transition: top .5s ease;
}
ul.scroller li {
width: 100%;
height: 200px;
box-sizing: border-box;
padding: 80px 0;
text-align: center;
font-size: 28px;
}
ul.scroller li:nth-child(2n+2) { background: #F5F5F5 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="window">
<ul class="scroller">
<li>
First Item
</li>
<li>
Second Item
</li>
<li>
Third Item
</li>
<li>
Fourth Item
</li>
</ul>
</div>
You can use scrollTo jQuery plugin:
http://demos.flesler.com/jquery/scrollTo/
and repeat a function using setTimeout(function(){ $.scrollTo('#element'); }, 5000);
With core javascript:
<div class="container" style="width:500px; max-width:500px; height:100px; max-height:100px; background:#F00; overflow:hidden;">
<div class="element_01" style="width:500px; height:100px; float:left;">aaa</div>
<div class="element_02" style="width:500px; height:100px; float:left;">bbb</div>
</div>
<script>
var container=document.getElementsByClassName('container')[0];
var start = 0;
var smoothVal = 20;
var waitVal = 5000;
function smooth(){
var interval=setInterval(function(){
start++;
container.scrollTop = start;
if(start>100) {
clearInterval(interval);
wait();
}
},smoothVal)
}
function wait(){
start = 0;
container.scrollTop = start;
setTimeout(function(){
smooth();
},waitVal)
}
smooth();
</script>
Related
I'm working with an image fader program, but I'm not understanding absolute positioning. I have the images fading nicely and resizing the way I want if the screen resizes. but I have 2 problems. Div#2 gets covered up by the images. I want div2 to always appear below the image div. Also, I have control buttons on the images. I want them in the middle. I thought using top:50% would do that, but it's not. Here's an example...
var slides = document.querySelectorAll('#slides .slide');
var currentSlide = 0;
var slideInterval = setInterval(nextSlide,5000);
function nextSlide(){goToSlide(currentSlide+1);}
function previousSlide(){goToSlide(currentSlide-1);}
function goToSlide(n){
slides[currentSlide].className = 'slide';
currentSlide = (n+slides.length)%slides.length;
slides[currentSlide].className = 'slide showing';}
var next = document.getElementById('next');
var previous = document.getElementById('previous');
next.onclick = function(){nextSlide();};
previous.onclick = function(){previousSlide();};
#slides {position: relative}
.slide{
position: absolute;
left: 0px;
top: 0px;
width:100%;
height:auto;
min-height:300px;
object-fit:cover;
opacity: 0;
box-sizing:border-box;
transition: opacity 2s;}
.showing{opacity: 1;}
.controls{
background: transparent;
color: #fff;
font-size: 30px;
cursor: pointer;
border: 1px solid #555;
width: 30px;
position: absolute;
}
.controls:hover{ opacity:.5}
.fadenext{right: 10px; top: 50%;}
.fadeprev{left: 10px; top: 50%;}
<br><br>
<div id="slides">
<img src='https://www.panotools.org/dersch/Monp.JPG' class="slide showing">
<img src='https://www.panotools.org/dersch/StBp.JPG' class="slide">
<button class="controls fadeprev" id="previous"><</button>
<button class="controls fadenext" id="next">></button>
</div>
<div style='margin-top:40px;border:1px solid red;width:200px;height:100px'>
This is Div # 2</div>
I've amended your snippet to fix your issues.
Adding margin-top instead of top will fix your issue with the
controls.
Div 2 will now always remain below your slider.
P.S. I moved your div2 inline styles to keep it neat.
var slides = document.querySelectorAll('#slides .slide');
var currentSlide = 0;
var slideInterval = setInterval(nextSlide, 5000);
function nextSlide() {
goToSlide(currentSlide + 1);
}
function previousSlide() {
goToSlide(currentSlide - 1);
}
function goToSlide(n) {
slides[currentSlide].className = 'slide';
currentSlide = (n + slides.length) % slides.length;
slides[currentSlide].className = 'slide showing';
}
var next = document.getElementById('next');
var previous = document.getElementById('previous');
next.onclick = function() {
nextSlide();
};
previous.onclick = function() {
previousSlide();
};
* {
margin: 0;
padding: 0;
}
#slides {
position: relative
}
.slide {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: auto;
min-height: 300px;
object-fit: cover;
opacity: 0;
box-sizing: border-box;
transition: opacity 2s;
}
.showing {
opacity: 1;
}
.controls {
background: transparent;
color: #fff;
font-size: 30px;
cursor: pointer;
border: 1px solid #555;
width: 30px;
position: absolute;
}
.controls:hover {
opacity: .5
}
.fadenext {
right: 10px;
margin-top: 25%;
}
.fadeprev {
left: 10px;
margin-top: 25%;
}
.div2 {
margin-top: 50%;
border: 1px solid red;
width: 200px;
height: 100px;
}
<br><br>
<div id="slides">
<img src='https://www.panotools.org/dersch/Monp.JPG' class="slide showing">
<img src='https://www.panotools.org/dersch/StBp.JPG' class="slide">
<button class="controls fadeprev" id="previous"><</button>
<button class="controls fadenext" id="next">></button>
</div>
<div class="div2">This is Div # 2</div>
It's not feasible to use % based positions when you use "top" style. So to achieve what you want to do, use margin-top instead. As shown below:
.fadenext{right: 10px; margin-top: 25%;}
.fadeprev{left: 10px; margin-top: 25%;}
And for your div2, just change it's style to:
margin-top: 50%
I have built a really simple carousel but there is one issue. In my carousel i have three slides, a previous button and a next button. What I want is when I click the next button and is on the last slide to go to the first slide. Moreover, when i click the previous button and is on the first slide to go to the last slide. How can i achieve it?
Thanks
//Main Container
var carouseContainer = document.querySelector("#carousel-container");
//Carousel Container
var carousel = document.querySelector("#carousel");
//Carousel Children
var carouselChildren = document.querySelector("#carousel").children;
//Carousel Slides
var carouselOne = document.querySelector("#carousel-one")
var carouseTwo = document.querySelector("#carousel-two")
var carouselThree = document.querySelector("#carousel-three")
//Buttons
var buttonPrev = document.querySelector("#button-left");
var buttonNext = document.querySelector("#button-right");
buttonNext.addEventListener("click", function(){
for ( i = 0; i < carouselChildren.length; i++) {
carouselChildren[i].style.transform +="translateX(-300px)";
carouselChildren[i].style.transition +="all 2s ease";
}
});
buttonPrev.addEventListener("click", function(){
for ( i = 0; i < carouselChildren.length; i++) {
carouselChildren[i].style.transform +="translateX(300px)";
carouselChildren[i].style.transition +="all 2s ease";
}
});
* {
margin:0px;
padding:0px;
box-sizing: border-box;
list-style: none;
text-decoration: none;
}
#carousel-container {
width:300px;
height:300px;
overflow: hidden;
margin: 0 auto;
border:1px solid black;
}
#carousel {
width:900px;
height:300px;
}
#carousel-one, #carousel-two,#carousel-three {
width:300px;
height:300px;
float:left;
}
#carousel-one {
background:red;
}
#carousel-two {
background:green;
}
#carousel-three {
background:blue;
}
#buttons {
text-align: center;
margin-top:20px;
}
button {
border:none;
color:#fff;
padding:10px 20px;
display: inline-block;
margin-right:20px;
cursor: pointer;
}
<div id="carousel-container">
<div id="carousel">
<div id="carousel-one">
<h1>Carousel One Main Heading</h1>
<h2>Carousel One Sub Heading</h2>
</div>
<div id="carousel-two"></div>
<div id="carousel-three"></div>
</div>
</div>
<div id="buttons">
<button id="button-left">Previous</button>
<button id="button-right">Next</button>
</div>
Here's a working example from your code:
//Main Container
var carouseContainer = document.querySelector("#carousel-container");
//Carousel Container
var carousel = document.querySelector("#carousel");
//Carousel Children
var carouselChildren = document.querySelector("#carousel").children;
//Carousel Slides
var carouselOne = document.querySelector("#carousel-one")
var carouseTwo = document.querySelector("#carousel-two")
var carouselThree = document.querySelector("#carousel-three")
//Buttons
var buttonPrev = document.querySelector("#button-left");
var buttonNext = document.querySelector("#button-right");
var current = 0,
total = 3;
function moveTo(count) {
var translate = 'translateX(' + (-300 * current) + 'px)';
for (i = 0; i < carouselChildren.length; i++) {
carouselChildren[i].style.transform = translate;
}
}
buttonNext.addEventListener("click", function() {
current++;
if (current > total - 1) {
current = 0;
}
moveTo(current);
});
buttonPrev.addEventListener("click", function() {
current--;
if (current < 0) {
current = total - 1;
}
moveTo(current);
});
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
list-style: none;
text-decoration: none;
}
#carousel-container {
width: 300px;
height: 300px;
overflow: hidden;
margin: 0 auto;
border: 1px solid black;
}
#carousel {
width: 900px;
height: 300px;
}
#carousel-one,
#carousel-two,
#carousel-three {
width: 300px;
height: 300px;
float: left;
transition: all 2s ease;
}
#carousel-one {
background: red;
}
#carousel-two {
background: green;
}
#carousel-three {
background: blue;
}
#buttons {
text-align: center;
margin-top: 20px;
}
button {
border: none;
color: #fff;
padding: 10px 20px;
display: inline-block;
margin-right: 20px;
cursor: pointer;
}
<div id="carousel-container">
<div id="carousel">
<div id="carousel-one" class="slide">
<h1>Carousel One Main Heading</h1>
<h2>Carousel One Sub Heading</h2>
</div>
<div id="carousel-two" class="slide"></div>
<div id="carousel-three" class="slide"></div>
</div>
</div>
<div id="buttons">
<button id="button-left">Previous</button>
<button id="button-right">Next</button>
</div>
This is an example, however, I think you can improve a lot your code :-) . Once I did a carousel and the magic was with the active class and the animation, I mean if you can apply the translate to the active class and identify the direction according to the prev or next button, you will achieve it.
//Main Container
var carouseContainer = document.querySelector("#carousel-container");
//Carousel Container
var carousel = document.querySelector("#carousel");
//Carousel Children
var carouselChildren = document.querySelector("#carousel").children;
//Carousel Slides
var carouselOne = document.querySelector("#carousel-one")
var carouseTwo = document.querySelector("#carousel-two")
var carouselThree = document.querySelector("#carousel-three")
//Buttons
var buttonPrev = document.querySelector("#button-left");
var buttonNext = document.querySelector("#button-right");
buttonNext.addEventListener("click", function(){
var activeSlide = 0,
translate = 'translateX(-300px)';
for ( i = 0; i < carouselChildren.length; i++) {
if (carouselChildren[i].className) {
activeSlide = i;
}
carouselChildren[i].style.transform += translate;
carouselChildren[i].style.transition +="all 2s ease";
}
// remove the active class for the current slide
carouselChildren[activeSlide].className = '';
if(activeSlide + 1 >= carouselChildren.length){
carouselChildren[0].className = 'active';
for ( i = 0; i < carouselChildren.length; i++) {
carouselChildren[i].style.transform = 'translateX(0px)';
}
} else{
carouselChildren[++activeSlide].className = 'active';
}
});
buttonPrev.addEventListener("click", function(){
console.log(carouselChildren.length);
for ( i = 0; i < carouselChildren.length; i++) {
carouselChildren[i].style.transform +="translateX(300px)";
carouselChildren[i].style.transition +="all 2s ease";
}
});
* {
margin:0px;
padding:0px;
box-sizing: border-box;
list-style: none;
text-decoration: none;
}
#carousel-container {
width:300px;
height:300px;
overflow: hidden;
margin: 0 auto;
border:1px solid black;
}
#carousel {
width:900px;
height:300px;
}
#carousel-one, #carousel-two,#carousel-three {
width:300px;
height:300px;
float:left;
}
#carousel-one {
background:red;
}
#carousel-two {
background:green;
}
#carousel-three {
background:blue;
}
#buttons {
text-align: center;
margin-top:20px;
}
button {
border:none;
color:#fff;
padding:10px 20px;
display: inline-block;
margin-right:20px;
cursor: pointer;
}
<div id="carousel-container">
<div id="carousel">
<div id="carousel-one" class="active">
<h1>Carousel One Main Heading</h1>
<h2>Carousel One Sub Heading</h2>
</div>
<div id="carousel-two"></div>
<div id="carousel-three"></div>
</div>
</div>
<div id="buttons">
<button id="button-left">Previous</button>
<button id="button-right">Next</button>
</div>
Use a variable to keep track of the current slide and change the transform property based on it. I have made the function for the next button and you can use the same concept for the previous button as well.
var currentSlide = 1; // is in first slide
buttonNext.addEventListener("click", function(){
if(currentSlide == 3){
currentSlide = 0;
}
for ( i = 0; i < carouselChildren.length; i++) {
carouselChildren[i].style.transform="translateX("+(currentSlide*-300)+"px)";
carouselChildren[i].style.transition ="all 2s ease"; // you don't need to do this as well if you define it in css file once
}
currentSlide++;
});
P.S. It's a bad practice to add transform property to existing css transform property like you did in your code as you are adding further calculations that needs to happen in order to animate (translate) the divs. Always replace them.
I am trying to make an animation, you can see my efforts at jsfiddle. And here is the code I've used:
/* JavaScript: */
var app = function () {
var self = this;
var allBoxes = $('.box');
var shadow = $('#shadow');
var busy = false;
self.init = function () {
self.events();
};
self.getBoxLeftPosition = function(id)
{
var left = 100;
if (id == 'box2')
{
left = 300;
} else if (id == 'box3')
{
left = 500;
} else if (id == 'box4')
{
left = 700;
}
return left;
};
self.events = function () {
allBoxes.on('hover mousemove', function(event) {
event.stopPropagation();
var currentBox = $(this);
if (currentBox.hasClass('inactive') && !busy)
{
busy = true;
currentBox.removeClass('inactive').addClass('active').animate({
left: '-=30',
width: 260
}, 400, function () {
busy = false;
});
shadow.fadeIn(400);
}
});
$('body').mousemove(function(event) {
var currentBox = $('.active');
var leftValue = self.getBoxLeftPosition(currentBox.attr('id'));
if (currentBox.length > 0)
{
currentBox.stop();
currentBox.animate({
left: leftValue,
width: 200
}, 300, 'swing', function () {
currentBox.removeClass('active').addClass('inactive');
}, 300);
shadow.fadeOut(300);
}
});
};
return self;
};
var main = new app();
main.init();
/* CSS: */
html, body {
margin: 0;
}
.box {
position: absolute;
top: 120px;
width: 200px;
height: 420px;
}
.box div {
text-align: center;
color: white;
position: absolute;
top: 200px;
left: 0;
right: 0;
font-size: 25px;
font-weight: bold;
}
#box1 {
left: 100px;
background: pink;
}
#box2 {
left: 300px;
background: skyblue;
}
#box3 {
left: 500px;
background: orange;
}
#box4 {
left: 700px;
background: lightgreen;
}
#shadow {
display: none;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url('https://lh6.googleusercontent.com/Vz0GTzpQVaxmlIvvGgg64CSxcYBbHzu7gMQERduJ4qjU5HAg8KfisFFQvIqvKL5Vn7LIy6HZ=w1920-h916');
z-index: 10;
}
.inactive {
z-index: 5;
}
.active {
z-index: 20;
}
<!-- HTML: -->
<div id="box1" class="box inactive">
<div id="copy1">Copy 1</div>
</div>
<div id="box2" class="box inactive">
<div id="copy2">Copy 2</div>
</div>
<div id="box3" class="box inactive">
<div id="copy3">Copy 3</div>
</div>
<div id="box4" class="box inactive">
<div id="copy4">Copy 4</div>
</div>
<div id="shadow"></div>
Here is what I am trying to achieve in words: I have 4 boxes and whenever a user hovers over one of them that box needs to expand a little and everything else needs to be grayed out and whenever the mouse leaves the box it needs to go back to it's original state.
In my jsfiddle I got it working to a point but it's buggy.
take a look at this JSFiddle
$('.box').hover(function(){
$(this).siblings().addClass('inactive');
}, function(){
$(this).siblings().removeClass('inactive');
});
tried to do it with pure css but sadly there's no such thing as prev sibling selector in css. Its kinda jumpy because of z-index getting immediately change on hover.
You can achieve the same effect even with CSS
$(document).on('mouseenter', '.item', function(e){
var me = $(this);
$('.item').not(this).addClass('greyed');
});
$(document).on('mouseleave', '.item', function(e){
$('.item').removeClass('greyed');
});
ul,li{
list-style:none;padding:0;margin:0;
}
ul{
width:400px;
}
li, .item {
width:100px;
height:100px;
}
li {
float:left;
position:relative;
}
.item {
background-color: #eee;
border:1px solid #ccc;
position:absolute;
z-index:1;
-webkit-transition:all 0.3s ease-in-out;
}
.item:hover {
width:110px;
z-index:2;
}
.red{
background: red;
}
.pink{
background: pink;
}
.blue{
background: blue;
}
.yellow{
background: yellow;
}
.greyed{
-webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
filter: grayscale(100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<ul>
<li>
<div class="item red"></div>
</li>
<li>
<div class="item blue"></div>
</li>
<li>
<div class="item yellow"></div>
</li>
<li>
<div class="item pink"></div>
</li>
</ul>
Here is what I did.
First, I found that the background image in your css is not a valid resource, so I replaced it with regular background color (it's transparent black, you may want to adjust it).
Second, I changed allBoxes.on('hover mousemove' to allBoxes.on('mouseover', and $('body').mousemove to allBoxes.on('mouseout'.
Third, I removed the $busy flag tracking.
Fourth, I changed var currentBox = $('.active'); to var currentBox = $(event.target);.
var app = function () {
var self = this;
var allBoxes = $('.box');
var shadow = $('#shadow');
var busy = false;
self.init = function () {
self.events();
};
self.getBoxLeftPosition = function(id)
{
var left = 100;
if (id == 'box2')
{
left = 300;
} else if (id == 'box3')
{
left = 500;
} else if (id == 'box4')
{
left = 700;
}
return left;
};
self.events = function () {
allBoxes.on('mouseover', function(event) {
event.stopPropagation();
var currentBox = $(this);
if (currentBox.hasClass('inactive') && !busy)
{
//busy = true;
currentBox.removeClass('inactive').addClass('active').animate({
left: '-=30',
width: 260
}, 400, function () {
//busy = false;
});
shadow.fadeIn(400);
}
});
allBoxes.on('mouseout', function(event) {
var currentBox = $(event.target);
var leftValue = self.getBoxLeftPosition(currentBox.attr('id'));
if (currentBox.length > 0)
{
currentBox.stop();
currentBox.animate({
left: leftValue,
width: 200
}, 300, 'swing', function () {
currentBox.removeClass('active').addClass('inactive');
}, 300);
shadow.fadeOut(300);
}
});
};
return self;
};
var main = new app();
main.init();
html, body {
margin: 0;
}
.box {
position: absolute;
top: 120px;
width: 200px;
height: 420px;
}
.box div {
text-align: center;
color: white;
position: absolute;
top: 200px;
left: 0;
right: 0;
font-size: 25px;
font-weight: bold;
}
#box1 {
left: 100px;
background: pink;
}
#box2 {
left: 300px;
background: skyblue;
}
#box3 {
left: 500px;
background: orange;
}
#box4 {
left: 700px;
background: lightgreen;
}
#shadow {
display: none;
position: absolute;
left: 0;
top: 0;
width: 1000px;
height: 600px;
/*background: url('https://lh6.googleusercontent.com/Vz0GTzpQVaxmlIvvGgg64CSxcYBbHzu7gMQERduJ4qjU5HAg8KfisFFQvIqvKL5Vn7LIy6HZ=w1920-h916');*/
background-color: rgba(0,0,0,0.5); /* transparent black */
z-index: 10;
}
.inactive {
z-index: 5;
}
.active {
z-index: 20;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="box1" class="box inactive">
<div id="copy1">Copy 1</div>
</div>
<div id="box2" class="box inactive">
<div id="copy2">Copy 2</div>
</div>
<div id="box3" class="box inactive">
<div id="copy3">Copy 3</div>
</div>
<div id="box4" class="box inactive">
<div id="copy4">Copy 4</div>
</div>
<div id="shadow"></div>
Against all reason, I'm trying to create a vanilla JavaScript carousel.
I am having two problems:
1. The images move left at widths of -680px as they should but when I tried to create the same function for the right button, the left value goes to 1370px making the picture off the screen.
2. I would like for it to slide left rather jump left (same for right), I managed to get it to do this but it doesn't work on the first slide, only from the second slide.
Here is the HTML code just for the carousel:
<div id = "container">
<div id = "carousel">
<div class = "slide"><img class = "slideImage" class = "active" src = "sithCover.png"></div>
<div class = "slide"><img class = "slideImage" src = "darthVader.png"></div>
<div class = "slide"><img class = "slideImage" src = "darthSidious.png"></div>
<div class = "slide"><img class = "slideImage" src = "kyloRen.png"></div>
</div>
</div>
<div id = "left" class = "button"></div>
<div id = "right" class = "button"></div>
Here is the CSS code:
#container {
position: absolute;
top: 200px;
left: 100px;
width: 680px;
height: 360px;
white-space: nowrap;
overflow:hidden;
}
#carousel {
position: absolute;
width: 2740px;
height: 360px;
white-space: nowrap;
overflow: hidden;
transition: left 300ms linear;
}
.slide {
display: inline-block;
height: 360px;
width: 680px;
padding: 0;
margin: 0;
transition: left 300ms linear;
}
.slideImage {
position:relative;
height: 360px;
width: 680px;
float: left;
}
.button {
position: absolute;
top: 340px;
height: 60px;
width: 60px;
border-bottom: 12px solid red;
}
#left {
left: 115px;
border-left: 12px solid red;
transform: rotate(45deg);
}
#right {
left: 693px;
border-right: 12px solid red;
transform: rotate(-45deg);
}
Here is the JavaScript:
var carousel = document.querySelector('#carousel');
var firstVal = 0;
document.querySelector('#left').addEventListener("click", moveLeft);
function moveLeft (){
firstVal +=685;
carousel.style.left = "-"+firstVal+"px";
};
document.querySelector('#right').addEventListener("click", moveRight);
function moveRight() {
firstVal +=685;
carousel.style.left = "+"+firstVal+"px";
};
Here is a JSFiddle so that you can see what I mean:
"https://jsfiddle.net/way81/8to1kkyj/"
I appreciate your time in reading my question and any help would be much appreciated.
Ofcourse it goes from -685px on left click and then to +1370pxthe next right click; You are always adding 685 to your firstVal variable.
firstVal = 0
//firstVal is worth 0
moveLeft()
//firstVal is now worth 685
moveRight()
//firstVal is now worth 1370.
The problem is that when you apply the firstVal to your CSS thing in the javascript, you create a string to get your negative value (where you apply the "-" sign infront of firstVal)
Instead, write them like this
function moveLeft (){
firstVal -=685; //note we now subtract, the "-" should appear when the number becomes negative
carousel.style.left = firstVal + "px";
};
function moveRight() {
firstVal +=685;
carousel.style.left = firstVal + "px";
};
var left = document.getElementById("left");
left.addEventListener("click", moveLeft, false);
var right = document.getElementById("right");
right.addEventListener("click", moveRight, false);
var carousel = document.getElementById("carousel");
var images = document.getElementsByTagName("img");
var position = 0;
var interval = 685;
var minPos = ("-" + interval) * images.length;
var maxPos = interval * images.length;
//slide image to the left side <--
function moveRight() {
if (position > (minPos + interval)) {
position -= interval;
carousel.style.left = position + "px";
}
if (position === (minPos + interval)) {
right.style.display = "none";
}
left.style.display = "block";
}
//slide image to the right side -->
function moveLeft() {
if (position < (maxPos - interval) && position < 0) {
position += interval;
carousel.style.left = position + "px";
}
if (position === 0) {
left.style.display = "none";
}
right.style.display = "block";
}
#container {
position: absolute;
top: 200px;
left: 100px;
width: 680px;
height: 360px;
white-space: nowrap;
overflow: hidden;
}
#carousel {
position: absolute;
width: 2740px;
height: 360px;
white-space: nowrap;
overflow: hidden;
transition: left 300ms linear;
}
.slide {
display: inline-block;
height: 360px;
width: 680px;
padding: 0;
margin: 0;
transition: left 300ms linear;
}
.slideImage {
position: relative;
height: 360px;
width: 680px;
float: left;
}
.button {
position: absolute;
top: 340px;
height: 60px;
width: 60px;
border-bottom: 12px solid red;
}
#left {
left: 115px;
border-left: 12px solid red;
transform: rotate(45deg);
display: none;
}
#right {
left: 693px;
border-right: 12px solid red;
transform: rotate(-45deg);
}
<div id="container">
<div id="carousel">
<div class="slide">
<img class="slideImage" class="active" src="sithCover.png" alt="slide1">
</div>
<div class="slide">
<img class="slideImage" src="darthVader.png" alt="slide2">
</div>
<div class="slide">
<img class="slideImage" src="darthSidious.png" alt="slide3">
</div>
<div class="slide">
<img class="slideImage" src="kyloRen.png" alt="slide4">
</div>
</div>
</div>
<div id="left" class="button"></div>
<div id="right" class="button"></div>
Basically I am working on a one-page website and I would like to include the menu in this website. When the user clicks the link, the page will scroll to the anchor. But it seems that every time the page just doesn't scroll to the right position. The value it returns from offset().top is smaller than the real position. I checked many online tutorials but still can't figure it out.
<!DOCTYPE html>
<html>
<head>
<title>Letsport</title>
<meta charset = "UTF-8">
<link rel="stylesheet" type="text/css" href="style/normalize.css">
<link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600,700' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src = "script/script.js"></script>
</head>
<body>
<nav id = "side_nav">
<div id = "nav_content">
<div id = "cross_btn">
<a href="#">
<img src="img/cross.png">
</a>
</div>
<ul>
<li>HOME</li>
<li>DOWNLOAD</li>
<li>CONTACT</li>
</ul>
</div>
</nav>
<div id = "overlay">
</div>
<section id = "home_section">
<ul>
<li id = "logo">
<img src="img/logo.png">
</li>
<li id = "stripes">
<div id = "stripe_background">
<a href="#">
<div>
<div class = "stripe"></div>
<div class = "stripe"></div>
<div class = "stripe"></div>
</div>
</a>
</div>
</li>
</ul>
<div id = "title">
<div id = "bar_up"></div>
<h1>
Letsport
</h1>
<div id = "bar_down"></div>
<div id = "slider_wrapper">
<div id = "text_slider">
<div><h2>TEAMMATES NOT SHOWING UP?</h2></div>
<div><h2>HARD TO BOOK ONLINE?</h2></div>
<div><h2>WANNA SEEK A COMPETITOR IN THE SAME LEVEL?</h2></div>
<div><h2>COME AND DOWNLOAD LETSPORT!</h2></div>
</div>
</div>
</div>
<video id = "home_video" autoplay loop>
<source src = "media/home_video.mp4">
</video>
</section>
<section id = "video_section">
<div class = "section_content">
<h1>DO YOU HAVE SAME TROUBLES?</h1>>
<div id = "interview_video">
<ul>
<li>
<video class = "each_video" class = "filter" id = "video1" loop>
<source src = "media/1.mp4">
</video>
</li>
<li>
<video class = "each_video" class = "filter" id = "video2" loop>
<source src = "media/2.mp4">
</video>
</li>
</ul>
<ul>
<li>
<video class = "each_video" class = "filter" id = "video3" loop>
<source src = "media/3.mp4">
</video>
</li>
<li>
<video class = "each_video" class = "filter" id = "video4" loop>
<source src = "media/4.mp4">
</video>
</li>
</ul>
</div>
</div>
</section>
<section id = "about_section">
<div class = "section_content">
<ul>
<li id = "about_desc" class = "about hidden">
<h1>TIRED</h1>
<h2>OF THESE PROBLEMS?</h2>
<h3>DOWNLOAD "LETSPORT" TO HELP YOU!</h3>
<p>"Letsport" is a mobile application which helps you to find your sportmates. Besides, you can even book online! Download "Letsport" and enjoy!</p>
</li>
<li id = "mock_up">
<img src="img/mockup.png">
</li>
</ul>
</div>
</section>
</body>
</html>
body {
margin: 0;
font-family: 'Open Sans', sans-serif;
color: white;
height: 100%;
width: 100%;
position: relative;
}
a {
text-decoration: none;
}
h1 {
padding: 30px 0 0 0;
margin: 0;
font-weight: 700;
font-size: 2.5em;
}
h2 {
margin: 0px;
font-weight: 600;
font-size: 1.3em;
}
ul {
list-style: none;
}
.section_content {
width: 95%;
margin: 0 auto;
padding: 100px 0;
text-align: center;
}
#side_nav {
position: fixed;
top: 0;
right: -500px;
width: 500px;
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
z-index: 100;
}
#side_nav li {
padding: 5px 0;
}
#side_nav li a {
color: white;
font-size: 1.5em;
letter-spacing: 0.3em;
}
#side_nav li a:hover {
color: yellow;
text-decoration: underline;
}
#side_nav #nav_content {
margin: 15px;
}
#side_nav #nav_content #cross_btn {
padding: 10px;
}
#overlay {
display: none;
top: 0;
left: 0;
position: fixed;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.3);
}
/******************************************
HOME SECTION
******************************************/
#home_section {
width: 100%;
height: 720px;
}
#home_section ul {
width: 100%;
padding: 0;
}
#home_section ul li {
display: inline-block;
}
#logo {
margin: 15px;
}
#stripes {
position: fixed;
right: 0;
top: 0;
margin: 15px;
float: right;
}
#stripe_background {
padding: 10px;
}
.active_stripe {
background-color: rgba(0, 0, 0, 0.5);
}
.stripe {
width: 30px;
height: 3px;
margin: 5px 0;
background-color: white;
}
#home_section #home_video {
position: fixed;
top: 0;
left: 0;
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
z-index: -100;
background-size: cover;
filter: brightness(35%);
-webkit-filter: brightness(35%);
-moz-filter: brightness(35%);
-ms-filter: brightness(35%);
-o-filter: brightness(35%);
}
#home_section #title {
margin: 150px auto;
text-align: center;
}
#home_section #title h1 {
padding: 15px 0 30px 0;
margin: 0;
font-family: 'Lobster', cursive;
font-size: 6em;
}
#home_section #title #bar_up {
position: fixed;
left: 50%;
width: 50%;
height: 2px;
margin: 0 0 0 -25%;
background-color: white;
}
#home_section #title #bar_down {
position: fixed;
left: 50%;
width: 50%;
height: 2px;
margin: 0 0 0 -25%;
background-color: white;
}
#home_section #title h2 {
margin-top: 30px;
font-weight: 400;
font-size: 1.3em;
letter-spacing: 0.5em;
color: #cecece;
}
#slider_wrapper {
width: 60%;
position: relative;
margin: 0 auto;
}
#text_slider div {
width: 100%;
position: absolute;
text-align: center;
}
/******************************************
VIDEO SECTION
******************************************/
#video_section {
background-color: white;
}
#video_section h1 {
color: #333333;
}
#video_section h2 {
color: #505050;
}
.each_video {
width: 200px;
filter: brightness(35%);
-webkit-filter: brightness(35%);
-moz-filter: brightness(35%);
-ms-filter: brightness(35%);
-o-filter: brightness(35%);
}
.filter {
filter: brightness(100%);
-webkit-filter: brightness(100%);
-moz-filter: brightness(100%);
-ms-filter: brightness(100%);
-o-filter: brightness(100%);
-webkit-transition: 1s -webkit-filter linear;
-moz-transition: 1s -moz-filter linear;
-moz-transition: 1s filter linear;
-ms-transition: 1s -ms-filter linear;
-o-transition: 1s -o-filter linear;
transition: 1s filter linear;
}
#video_section ul {
margin: 0;
}
#video_section ul li {
display: inline-block;
padding: 0;
}
/******************************************
ABOUT SECTION
******************************************/
#about_section {
background-color: #5489dd;
margin-top: 0;
position: relative;
}
#about_section ul {
margin: 0;
}
#about_section ul li {
width: 500px;
display: inline-block;
vertical-align: top;
}
#about_section ul #about_desc {
text-align: right;
}
#about_section ul #about_desc h1 {
margin: 0;
padding-bottom: 0;
font-size: 8em;
}
#about_section ul #about_desc h2 {
font-size: 2em;
}
.about {
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-ms-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
transform: perspective(1000px);
-webkit-transform: perspective(1000px);
-moz-transform: perspective(1000px);
-ms-transform: perspective(1000px);
-o-transform: perspective(1000px);
}
.about h1, .about h2, .about h3, .about p {
transition: all 0.8s ease;
-webkit-transition: all 0.8s ease;
-moz-transition: all 0.8s ease;
-ms-transition: all 0.8s ease;
-o-transition: all 0.8s ease;
}
.about.hidden h1, .about.hidden h2, .about.hidden h3, .about.hidden p {
opacity: 1;
transform: translate3d(0, 0, 400px) rotateY(40deg);
-webkit-transform: translate3d(0, 0, 400px) rotateY(40deg);
-moz-transform: translate3d(0, 0, 400px) rotateY(40deg);
-ms-transform: translate3d(0, 0, 400px) rotateY(40deg);
-o-transform: translate3d(0, 0, 400px) rotateY(40deg);
}
$(document).ready(function(){
var homeSectionTopPosY = $('#home_section').offset().top,
videoSectionTopPosY = $('#video_section').offset().top,
chooseSectionTopPosY = $('#choose_section').offset().top,
joinSectionTopPosY = $('#join_section').offset().top,
makeUpSectionTopPosY = $('#make_up_section').offset().top,
downloadSectionTopPosY = $('#download_section .section_content h1').offset().top,
contactSectionTopPosY = $('#contact_section').offset().top,
aboutSectionTopPosY = $('#about_section').offset().top;
// Anchor to the position
$('#home_link').on('click', function(){
$('html, body').animate({scrollTop: 0});
});
$('#download_link').on('click', function(){
$('html, body').animate({scrollTop: chooseSectionTopPosY});
});
$('#contact_link').on('click', function(){
$('html, body').animate({scrollTop: contactSectionTopPosY});
});
I've worked on a few single-page sites recently and have changed my approach to it a few times. Currently I use this method:
// Scroll smoothly to an element
function smooth_scroll_to(elem)
{
var offset = 0;
offset = $(elem).offset().top;
$('html, body').animate({
scrollTop: offset
}, 550);
}
// Initiate smooth scroll to area based on navigation item title attr
$('#side_nav li a').click(function(e){
e.preventDefault();
var elem = $(this).attr('title');
smooth_scroll_to(elem);
});
// Add title="#IDOFELEMENT" to each nav item
<ul>
<li><a title="#home_section" href="#" id = "home_link">HOME</a></li>
<li><a title="#download_section" href="#" id = "download_link">DOWNLOAD</a></li>
<li><a title="#contact_section" href="#" id = "contact_link">CONTACT</a></li>
</ul>
Using HREF seems more user friendly and cleaner. (Credit to #KarelG)
// Always use ID's and only place the text portion in the title
<li>HOME</li>
var elem = $(this).attr('href');
This will also allow for navigation in the event of a JS error or similar preventing the animation.
I've run into the same problem, trying to implement a current menu item highlight for a one page site when being at a section which has an ID which is part of the menu. In this case instead of offset = $(elem).offset().top; I had secPosition = $(theID).offset().top;
Here is the original snippet: Source
<script type="text/javascript">
(function($) {
$(document).ready(function() {
var navChildren = $("#top-menu li").children();
var aArray = [];
for (var i = 0; i < navChildren.length; i++) {
var aChild = navChildren[i];
var ahref = $(aChild).attr('href');
aArray.push(ahref);
}
$(window).scroll(function() {
var windowPos = $(window).scrollTop();
var windowHeight = $(window).height();
var docHeight = $(document).height();
for (var i = 0; i < aArray.length; i++) {
var theID = aArray[i];
var secPosition = $(theID).offset().top;
secPosition = secPosition - 135;
var divHeight = $(theID).height();
divHeight = divHeight + 90;
if (windowPos >= secPosition && windowPos < (secPosition + divHeight)) {
$("a[href='" + theID + "']").parent().addClass("active");
} else {
$("a[href='" + theID + "']").parent().removeClass("active");
}
}
});
});
})(jQuery);
</script>
The secPosition value was calculated completely wrong all the time, I've checked in the chrome debugger. Then what helped me was also to initialise the secPosition variable with 0 as the value, as described above by JohnDevelops. I don't quite understand why it makes a difference but it does work!
So this is the final working version:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("button.et_pb_contact_submit").text('Senden');
});
</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
<script type="text/javascript">
(function($) {
$(document).ready(function() {
var navChildren = $("#top-menu li").children();
var aArray = [];
for (var i = 0; i < navChildren.length; i++) {
var aChild = navChildren[i];
var ahref = $(aChild).attr('href');
aArray.push(ahref);
}
$(window).scroll(function() {
var secPosition = 0;
var windowPos = $(window).scrollTop();
var windowHeight = $(window).height();
var docHeight = $(document).height();
for (var i = 0; i < aArray.length; i++) {
var theID = aArray[i];
secPosition = $(theID).offset().top;
secPosition = secPosition - 135;
var divHeight = $(theID).height();
divHeight = divHeight + 90;
if (windowPos >= secPosition && windowPos < (secPosition + divHeight)) {
$("a[href='" + theID + "']").parent().addClass("active");
} else {
$("a[href='" + theID + "']").parent().removeClass("active");
}
}
I hope this saves others time, I've spent hours on figuring this out!
You could use one of several jQuery plugins which enables you to smoothly scroll to target element instead of measuring offset of target element and doing some calculations.
Try https://github.com/flesler/jquery.scrollTo