one single scroll button that scrolls to multiple elements in jquery - javascript

I have the next problem: let's say that I have 6 divs with height 700px and one single fixed button.
< a class="button >< /a>
< div class="div1" >< /div >
...
< div class="div6 " > < /div >.
and every time the user clicks that single fixed button I want to be scrolled down to the next div and so on. Like a carousel (but on vertical).
E.g. the user only sees div1 then he presses the button and it's automatically scrolled to div2. Then he clicks the button again and it's scrolled down to div3, and so on with a little smooth effect.
Here is what I did, but it only works one time:
$(".button").click(function() {
$('html,body').animate({
scrollTop: $(".div1").offset().top},
'slow');
});
I know how to to this but with 6 different buttons and yeah, that's not the best idea.

Try this out
JS
var count = 0,
sections = $('.section'),
scrollTo = function(index){
$('html, body').animate({
scrollTop: sections.eq(index).offset().top
}, 'slow');
};
$(".next").click(function(){
count++;
scrollTo(count);
});
$(".prev").click(function(){
count--;
scrollTo(count);
});
CSS
.navigation {
position: fixed;
right: 20px;
top: 20px;
}
.button {
display: block;
margin-bottom: 10px;
}
.section {
border-bottom: 2px solid #000;
font-size: 100px;
height: 700px;
line-height: 700px;
text-align: center;
}
HTML
<div class="navigation">
<button class="next">Next</button>
<button class="prev">Prev</button>
</div>
<div class="sections">
<div class="section">1</div>
<div class="section">2</div>
<div class="section">3</div>
<div class="section">4</div>
<div class="section">5</div>
</div>
DEMO

Related

JQuery Hide/Show on Scroll down

I'm new to jquery. I'm trying to write a script that will hide the div "box" and all children. When the user scrolls to the bottom of the page, the div "box" and all children display. For time's sake, we'll say the children are "chamber1", "chamber2" and "chamber 3".
when I hide "box", it only removes that div.
$(document).ready(function() {
$("#box").hide();
});
Apologies for lack of code, but I'm having trouble understanding this lesson and I can't find an exact example of what I'm trying to do through my internet searches.
Thank you!
If you to hide the box when you reach the bottom of the page, you javascript should be as follows:
JAVASCRIPT:
$(document).ready(function() {
$(document).on("scroll", function(){
if ( window.scrollMaxY == window.scrollY ) {
$("#box").hide();
}
})
});
HTML:
<div id="box">
<div>Chamber 1</div>
<div>Chamber 2</div>
<div>Chamber 3</div>
</div>
You should make sure that the div has id "box". If you're working with a div of class "box" then you would use:
$(document).ready(function() {
$(".box").hide();
});
I think this might help you and would be better to understand. A good explantion is given below here with demo.
$(window).scroll(function() {
if ($(window).scrollTop() + $(window).outerHeight() == $(document).outerHeight()) {
//Script for activity on reaching bottom of document
$("#box").fadeOut();
} else // optional
{
$("#box").fadeIn();
}
});
body {
margin: 0px;
width: 100%;
}
.container {
position: relative;
height: 900px;
width: 100%;
background: #fee;
}
#box {
position: fixed;
top: 50px;
left: 0px;
background: lightblue;
height: auto;
padding: 15px;
overflow: hidden;
max-width: 250px;
width: 210px;
}
#box > div {
margin: 5px;
background: #F33636;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="container">
</div>
<div id="box">
Box
<hr>
<div class="chamber1">
Chamber 1
</div>
<div class="chamber2">
Chamber 2
</div>
</div>
JSFiddle
You can play around with Fiddle Link.

el.scrollIntoViewIfNeeded() scrolls too far up

el.scrollIntoViewIfNeeded() scrolls to el if it's not inside of the visible browser area. In general it works fine but I'm having problems with using it with a fixed header.
I made an example snippet: (The method doesn't work in Firefox, so neither does the demo) https://jsfiddle.net/ahugp8bq/1/
In the beginning all three colored divs are displayed below the fixed header. But if you click "second" and then "first", the beginning of #first will be behind the header, which I don't want.
The problem seems to be that the position of #otherContainer (its padding-top) is pretty much ignored when scrolling up.
Actually, this is quite simple if you use the consistent and supported getBoundingClientRect().top + body.scrollTop way - all you now have to do is reduce the header from it, so just get it and calculate its height.
var header = document.getElementById('container')
var clicks = document.querySelectorAll('#container li');
var content = document.querySelectorAll('#otherContainer > div');
// Turn the clicks HTML NodeList into an array so we can easily foreach
Array.prototype.slice.call(clicks).forEach(function(element, index){
element.addEventListener('click', function(e){
e.preventDefault();
// Set the scroll to the top of the element (top + scroll) minus the headers height
document.body.scrollTop = content[index].getBoundingClientRect().top + document.body.scrollTop - header.clientHeight;
});
});
#container {
position: fixed;
background: yellow;
width: 100%;
height: 50px;
}
ul li {
display: inline;
cursor: pointer;
}
#otherContainer {
padding-top: 60px
}
#first, #second, #third {
height: 500px
}
#first {
background: red
}
#second {
background: green
}
#third {
background: blue
}
<div id="container">
<ul>
<li id="jumpToFirst">first</li>
<li id="jumpToSecond">second</li>
<li id="jumpToThird">third</li>
</ul>
</div>
<div id="otherContainer">
<div id="first"></div>
<div id="second"></div>
<div id="third"></div>
</div>

jquery-ui slide left doesn't work first time

When I'm using show() and hide() methods from jquery-ui:
var current = 1;
function slide(buttonNum) {
if (current != buttonNum){
$("#page" + current).hide("slide", { direction: "left" }, 800, function() {
$("#page" + buttonNum).show("slide", { direction: "right" }, 800);
});
current = buttonNum;
}
}
My intention is that every time button is clicked for this function the page would scroll left to change to required page.
The problem is that it doesn't work first time I'm clicking page number with function above(the current div would slide to the left, but div which I change to just pops up without animation) but works normally other times.
my css is as follows:
.slider {
width: 400px;
height: 300px;
overflow: hidden;
}
.slider .content {
position: relative;
}
.slider .content .page {
float: left;
width: 400px;
height: 300px;
background-size: cover;
}
and HTML:
<div class="slider">
<div class="content">
<div id='page1' class="page">
<!-- stuff -->
</div>
<div id='page2' class="page">
<!-- stuff -->
</div>
<div id='page3' class="page">
<!-- stuff -->
</div>
</div>
</div>
<a onclick='slide(1)' href="#">1</a>
<a onclick='slide(2)' href='#'>2</a>
Try hiding the elements that you expect not to be visible at the beginning, so that the show animation will actually execute. E.g. add this at the top:
$("#page2").hide();
$("#page3").hide();
That way running .show() on them will have an effect.

jQuery scrollTop - Issue with wrong hash

I am trying to do scrollTop animation to an anchor that resides inside of a fullscreen <section>, but does not scroll to right anchor at first click. Here's my code.
<nav id="scroller"> Scroll me to sub 1
Scroll me to sub 2
Scroll me to sub 3
</nav>
<section id="boxTop"></section>
<section id="boxMaster">
<section id="subBox1">
<p>Hello. I am the Sub 1!</p>
</section>
<section id="subBox2">
<p>Hello. I am the Sub 2!</p>
</section>
<section id="subBox3">
<p>Hello. I am the Sub 3!</p>
</section>
</section>
$("#scroller a").click(function () {
$('#boxMaster').animate({
scrollTop: $(this.hash).offset().top
}, 700);
$("#scroller a").removeClass("active");
$(this).addClass("active");
});
fiddle
$("#scroller a").click(function() {
$('#boxMaster').animate({
scrollTop: $(this.hash).offset().top
}, 700);
$("#scroller a").removeClass("active");
$(this).addClass("active");
});
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#scroller {
position: fixed;
top: 0;
height: 30px;
text-align: center;
}
#scroller a {
color: #fff;
margin: 0 20px;
text-decoration: none;
}
#scroller a.active {
font-weight: bold;
text-decoration: underline;
}
#boxTop {
width: 100%;
height: 100%;
background: red;
}
#boxMaster {
width: 100%;
height: 100%;
background: blue;
overflow: hidden;
}
#boxMaster #subBox1,
#boxMaster #subBox2,
#boxMaster #subBox3 {
width: 100%;
height: 100%;
display: table;
}
p {
color: #fff;
text-align: center;
display: table-cell;
vertical-align: middle;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="scroller"> Scroll me to sub 1
Scroll me to sub 2
Scroll me to sub 3
</nav>
<section id="boxTop"></section>
<section id="boxMaster">
<section id="subBox1">
<p>Hello. I am the Sub 1!</p>
</section>
<section id="subBox2">
<p>Hello. I am the Sub 2!</p>
</section>
<section id="subBox3">
<p>Hello. I am the Sub 3!</p>
</section>
</section>
Add the current scroller value to the offset().top(), the latter beeing relative to the top of frame, and get rid of this.hash. Use this.href instead.
$("#scroller a").click(function () {
var y=$('#boxMaster').scrollTop()
$('#boxMaster').animate({
scrollTop: $(this.href).offset().top + y
}, 100);
});
You need to scroll the #boxMaster element relative to the link's position within the element and relative to the #boxMaster element's top position within the body element.
You can do this by adding the #boxMaster element's scrollTop() value with its top position, and then subtracting that from the link's offset top value:
$(this.hash).offset().top - $('#boxMaster').position().top + $('#boxMaster').scrollTop()
Updated Example
var $boxMaster = $('#boxMaster');
$boxMaster.animate({
scrollTop: $(this.hash).offset().top - $boxMaster.position().top + $boxMaster.scrollTop()
}, 700);
You may also need to prevent the link element's default behavior using e.preventDefault(), and then manually scroll the html/body element to the #boxMaster element:
Updated Example
$('html, body').animate({
scrollTop: $boxMaster.offset().top
}, 700);
I have a fixed header. I started with w3school's code. However, I've been struggling with this same problem for so long, finally found a workaround for the "first click incorrect" issue:
Just before (outside) of my click event, I simply created a variable "x", initialized:
var x=1;
Then I have a conditional statement inside the click event checking for x:
if (x==1) {
console.log("x is now: " + x);
x=0;
console.log("x is now: " + x);
jQuery("html, body").animate({
scrollTop: jQuery("div.class-of-element-i-am-scrolling-to" + hash).position().top - jQuery("div.header-container").outerHeight(true) - jQuery("h3.another-element-in-my-way").outerHeight(true)
}, 2000, function(){
return false;
});
} else {
jQuery("html, body").animate({
scrollTop: jQuery("div.class-of-element-i-am-scrolling-to" + hash).position().top
}, 2000, function(){
return false;
});
}
In other words, using "x" as a flag to check if it is the first time the code is run.
If it is, then I am kind of cheating by subtracting the fixed header and the other elements that are pulling my desired div up. Remember to make "x=0" to "drop" the flag.
If it isn't, then it works fine anyway.

Smooth scrolling to internal links within div acting strangely; possibly a CSS sizing/spacing issue

I have a div that uses overflow:hidden and is within several other div containers. I am trying to scroll to internal links within the div using smooth scrolling via jQuery. Here is my code, which I have used on other projects with good results:
$(function() {
$('a[href*=#]:not([href=#])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('#cardb').animate({
scrollTop: target.offset(
).top
}, 0500);
return false;
}
}
});
});
.slide {
position: relative;
padding: 2vh 3vw;
min-height: 80vh;
width: 100vw;
}
#slide4 {
background: #ddd;
width: 100vw;
z-index: 1;
padding: 2.5vw;
}
#carda, #cardb {
width: 40vw;
height: 60vh;
padding: 3vw;
background: #fff;
opacity: 0.8;
float: left;
}
#cardb {
float: right;
overflow: hidden;
}
#cardb-1, #cardb-2, #cardb-3, #cardb-4 {
position: relative;
height: 60vh;
}
#linkcontainer {
position: absolute;
bottom: 20vh;
}
.linkcircle {
height: 3vh;
width: 3vh;
margin: 1vh;
background: #999;
opacity: 0.5;
transition: 0.35s;
border-radius: 1.5vh;
}
.linkcircle:hover {
opacity: 0.9;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slide4" class="slide">
<div id="carda">
<p>CARD A</p>
</div>
<div id="cardb">
<div id="cardb-1">
<p>CARD B 1</p>
</div>
<div id="cardb-2">
<p>CARD B 2</p>
</div>
<div id="cardb-3">
<p>CARD B 3</p>
</div>
<div id="cardb-4">
<p>CARD B 4</p>
</div>
<div id="linkcontainer">
<div class="linkcircle"></div>
<div class="linkcircle"></div>
<div class="linkcircle"></div>
<div class="linkcircle"></div>
</div>
</div>
</div>
I am baffled by the results - the links almost never scroll to the correct target, and clicking the same link twice still scrolls (e.g. when you are at #cardb-1 and click the link for #cardb-1 again, the div scrolls somewhere else). I'm new to jQuery, but I've researched as much as I could figure out, with no improvement. I suspect it might actually be a CSS problem, but I'm not sure where I've gone wrong with that either. The links come up fine at the expected position when I deactivate the jQuery.
I am looking to solve this exact problem, I have taken your code as a start, so thanks.
In order to solve the scroll from happening again when clicking on the same link, I have include this code at the beginning of the function:
if( location.hash == this.hash){ return false;}
Although, it seems to take the process 1 or 2 seconds to settle in the new hash, so if you click twice on the same link withing that time lapse, the problem still persists, but if you click after that period nothing happens. I am still trying to figure out if I can eliminate the 1-2 seconds refreshing lapse, but at least it's a beginning.
Here is some working code that will scroll to the right place.
The trick is that the animated function takes an absolute y, and the original code only accounts for the top, which does not include the margins, and there is another 100px added (in my page) which I am not sure where it's coming from. So I just iterate through all divs until I reach the sought one, and calculate its position along the way. This also fixes the behavior when you click rapidly on two links.
$(function() {
$('a[href^="#"]').click(function() {
if( location.hash == this.hash){ return false;}
var target = $(this.hash);
var targetId = this.hash.substr(1);
var toGo = 0;
// class of each div that has an id for anchor link.
$('.info-box').each(function() {
var box = $(this);
if( this.id == targetId){
toGo += box.outerHeight(true)-box.outerHeight();
return false;
}
toGo += box.outerHeight(true)-box.outerHeight();
toGo += box.outerHeight();
});
if (target.length) {
// id of the container div
$('#page').animate({scrollTop: toGo}, 700);
return false;
}
});
});

Categories