I am trying to implement a position:fixed scroll-to-top button and another button that scrolls down the page section by section. I have seen a similar code that is working with IDs, but I would like to use the classes of the sections and .next() .closest() to get this done. Is this possible with jQuery?
The scroll to top and scroll to the second section work, but I cannot get past the second section with .next() and .closest()
This is my html:
<body>
Top
next
<div class="section">
<section class="x_section"> 1</section>
<section class="x_section"> 2</section>
<section class="x_section"> 3</section>
<section class="x_section"> 4</section>
</div>
</body>
and this is the javascript:
jQuery(document).ready(function($){
$next = $('.cd-next'),
$back_to_top = $('.cd-top');
//smooth scroll to top
$back_to_top.on('click', function(event){
event.preventDefault();
$('html,body').animate({ scrollTop: 0 }, 700 );
});
$next.on('click', function(event){
event.preventDefault();
if (typeof advance == 'undefined') {
var fuller = $('section').closest('.x_section').next(),
section = $('.x_section').closest('.x_section').next(),
top0 = section.scrollTop(),
advance = fuller.offset().top;
}
else { var advance = advance + fuller.offset().top; }
$('html,body').animate({ scrollTop: top0 + 408 }, 700);
}) ;
});
Here is my fiddle:
https://jsfiddle.net/pnemeth/uLrjdm7e/
I used a different approach than you are using, however it seems to get the job done.
$(document).ready(function(){
// declare section count, set to 0
var count = 0,
sections = $(".x_section"),
$next = $(".cd-next"),
$top = $(".cd-top");
$next.on('click', function(event){
event.preventDefault();
// increment section count
count++;
$("html, body").animate({
// scroll to section count
scrollTop: $(sections.get(count)).offset().top
});
});
$top.on('click', function(event) {
event.preventDefault();
// reset section count to 0
count = 0;
$("html, body").animate({
scrollTop: $(sections.get(0)).offset().top
});
});
});
Update: This solution technically fulfills your requirements of using .closest() and .next(), but uses a position marker which is appended to the next section div after each button click. When the user clicks the button to go back to top, the marker is appended to the first section div.
$(document).ready(function(){
var $next = $(".cd-next"),
$top = $(".cd-top");
$next.on('click', function(event){
event.preventDefault();
// get section closest to marker
var section = $('#marker').closest('.x_section'),
// get next section
nextSection = section.next();
// remove marker
section.find($('#marker')).remove();
// append new marker to next section
$(section.next()).append('<div id="marker"></div>');
$("html, body").animate({
scrollTop: $(nextSection).offset().top
});
});
$top.on('click', function(event) {
event.preventDefault();
// append marker to first section
$(document).find($('#marker')).appendTo($('.x_section').get(0));
$("html, body").animate({
// scroll to first section
scrollTop: $($('.x_section').get(0)).offset().top
});
});
});
Related
I have a jQuery code obtained from w3schools.com which ON CLICK (clicking an ) changes URL's #id and also allows smooth scrolling to a particular DIV section. But its not working on scroll. I want the same with an scrolling effect. When I scroll down or up to a particular section the URL's #id should change.
Current jQuery Code:
$(document).ready(function(){
$("#navlist a").on('click', function(event) {
if(this.hash !== ""){
var hash = this.hash;
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function(){
window.location.hash = hash;
});
}
});
});
I searched on stackoverflow and I got something like this:
$(document).bind('scroll',function(e){
$('div').each(function(){
if ($(this).offset().top < window.pageYOffset + 10 && $(this).offset().top + $(this).height() > window.pageYOffset + 10){
window.location.hash = $(this).attr('id');
}
});
});
This seems to work but when I place both the code either one of them is stopping the other one from executing. I thought of combining both the codes into one to achieve both onclick and scroll effect but I am not being able to do so (weak hands on jquery yet).
Example URL with ID: http://localhost/sites/fh/index.php#first
Please help me devs.
Instead of setting the location hash, you should change the history state. That way you will avoid forced page scrolling by browser. Check it below:
navlist = [];
$("#navlist a").each(function(i) {
var thisLink = $(this);
var thisId = thisLink.attr('href');
var thisTarget = $(thisId);
navlist.push({
'anchor': thisLink,
'id': thisId,
'target': thisTarget
});
thisLink.on('click', function(e) {
e.preventDefault();
$('html, body').animate({
scrollTop: thisTarget.offset().top
}, 800);
});
});
$(window).on('scroll resize', function(e) {
$.each(navlist, function(e, elem) {
var placement = elem.target[0].getBoundingClientRect();
if( placement.top<window.innerHeight && placement.bottom>0 ) {
history.pushState({}, '', elem.id);
console.log('Hash: ' + elem.id);
return false; /* Exit $.each loop */
};
});
});
nav a {
display: block;
}
section {
height: 600px;
border-top: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="navlist">
Go to Section 1
Go to Section 2
Go to Section 3
</nav>
<section id="s1">Section 1 Content</section>
<section id="s2">Section 2 Content</section>
<section id="s3">Section 3 Content</section>
Also on JSFiddle.
Please note, if you are using Foundation framework, than you already have Magellan.
For Bootstrap it is called ScrollSpy.
I have a auto scroll function, there is a static arrow which lets the user scroll to the next section of the page. When the user reaches the "contact" section (the last page), I would like the arrow to hide as there is no other page to scroll down to.
Update -
Currently the navigation arrow dissapears on the last page but it also dissapears on the about and intro sections too.. How can i fix
Jquery - Updated v3
$(function() {
$('a.page-scroll').bind('click', function(event) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1500, 'easeInOutExpo');
event.preventDefault();
});
});
function nextSection()
{
var scrollPos = $(document).scrollTop();
$('#section-navigator a').each(function () {
var currLink = $(this);
var refElement = $(currLink.attr("href"));
if (refElement.position().top > scrollPos) {
var $anchor = $(this);
$('html, body').stop().animate({
scrollTop: $($anchor.attr('href')).offset().top
}, 1500, 'easeInOutExpo');
event.preventDefault();
location.hash = "";
location.hash = currLink.attr("href");
if ($($anchor.attr('href')).attr('id') == "contact") {
$("div.page-scroll").hide();
}
return false;
}
});
}
HTML
<div class="page-scroll">
<img class="arrow-down page-scroll-btn" src="img/arrow_dark.png" onclick="nextSection()" />
</div>
Thanks!
By the looks of things you use the links as the id for the next selector so you should be using #contact in your if.
Also, you have closed the if bracket ) in the wrong place
if ($anchor.attr('href') == "#contact") {
}
If you want to compare it to the target divs id, then you need to do something like this:
if ($($anchor.attr('href')).attr('id') == "contact") {
$("div.page-scroll").hide();
}
But this would seem like extra processing to get the same result
Update
Given all your edits - none of them really helpful as they don't create an MCVE - and we seem to be moving further and further away from the original question. I would do the following:
Get rid of that jquery onclick binding function at the top of your jQuery as you are manually binding in the html, the change your next section function to:
function nextSection() {
var currentPos = $(document).scrollTop();
$('#section-navigator a').each(function() {
var currLinkHash = $(this).attr("href");
var refElement = $(currLinkHash);
if (refElement.offset().top > scrollPos) { // change this to offset
$('html, body').stop().animate({
scrollTop: refElement.offset().top // just use refElement
}, 1500, 'easeInOutExpo');
location.hash = "";
location.hash = currLinkHash;
if (refElement.attr('id') == "contact") { // hide the scroller if the id is contact
$("div.page-scroll").hide();
}
return false;
}
});
}
Can anyone explain to me how I can use the jquery scroll-to to make the buttons on the yellow menu scroll to their corresponding sections (i.e distribution to the pink block)
This is my code: http://jsfiddle.net/VXkW5/5/
I think its something like this:
$(".nav").click(function () {
$('html, body').animate({
scrollTop: $(".section").offset().top + $(".section").height()
}, 500);
});
But I dont know how to relate it to it's relevant section based on the link that was clicked.
Working Demo
First of all, ID need to be unique in the page. I see both as well as uses same ID
so i have made change & Just add the corresponding div id to the href tag, it will take to that particular div on click
posting
distribution
applicantions
In terms of jQuery:
$(".nav").click(function (e) {
e.preventDefault();
var divId = $(this).attr('href');
$('html, body').animate({
scrollTop: $(divId).offset().top;
}, 500);
});
You could have a link like
Click to jump to section 1
And a section like
<div id="section1">
<p>Section 1 content</p>
</div>
And handle the scroll to like so
<script type="text/javascript">
$(".nav").click(function (event) {
event.stopPropagation();
var theHref = $(this).attr('href');
$('html, body').animate({
scrollTop: $(theHref).offset().top + $(".section").height()
}, 500);
});
</script>
I have some problem with scrolltop in firefox and IE
I used scrolltop more than 2 time in my code in part one it works but in part two it doesnt
I have two arrows "next" and "prev" which when clicking on them page scroll to specific part,
I cant find how can I fix it?
jquery :
var lchiled=$("ul#portfolio li").last();
var fchiled=$("ul#portfolio li").first();
$('li.section').first();
$("ul#portfolio li:first-child").addClass("current");
$('a.display').on('click', function(e) {
e.preventDefault();
var t = $(this).attr('name');
that = $(this);
if (t === 'next') {
if($('.current').next('.section').length==0)
var $next = $('li.section').first();
else
var $next = $('.current').next('.section');
var top = $next.offset().top -65;
$('.current').removeClass('current');
$('body,html').animate({
scrollTop: top,
},
function () {
$next.addClass('current');
// alert(top);
});
}
else if (t === 'prev' && $('.current').prev('li.section').length > 0) {
var $prev = $('.current').prev('.section');
var top = $prev.offset().top -65;
$('.current').removeClass('current');
$('body').animate({
scrollTop: top,
}, function () {
$prev.addClass('current');
});
}
});
html :
<div id="container">
<ul id="portfolio" class="clearfix">
</ul>
</div>
lis are dynamically produce with jquery codes
It must be like this
$('body,html').animate({
scrollTop: top,
}, function () {
$prev.addClass('current');
});
insted of
$('body').animate({
scrollTop: top,
}, function () {
$prev.addClass('current');
});
I forget to update the prev part so this problem happened.
You use .animate on scrollTop in two places. In one, you (correctly) use html,body as the selector. In the other, you only use body. And you wonder why it doesn't work in some browsers ;)
try var offset = $(window).scrollTop(); this .
You can use window.scrollTo(x,y)
In Demo 01 You can see the Div is Scrolling top of the page with increase height. And I need the same animation with click Buttons, like in Demo 02.
$('.work-showcase').click(function(){
$('.work-showcase').animate({height:'135px'}, 500);
$(this).animate({height:'400px'}, 500,function() {
$("html, body").animate({ scrollTop: $(this).offset().top });
});
});
Not sure if I understand what you want, but see if this Javascript works for you:
var map = {
"slice1": "#post1",
"slice2": "#post2",
"slice3": "#post3",
}
$('.clickable').click(function(){
var postId = map[$(this).attr('id')];
$('.post').animate({height:'50px'}, 500);
$(postId).animate({height:'400px'}, 500,function() {
$("html, body").animate({ scrollTop: $(postId).offset().top });
});
});
See demo at http://jsfiddle.net/xCKPW/1/.
What I think you want to do is have the animation and size change that you currently have get triggered when a button is clicked.
I also suspect you want the action to occur when the image is clicked.
In this case, move the animations into a separate function, and call that function onclick.
Here's your jsfiddle updated with buttons.
http://jsfiddle.net/Jq4Vw/132/
$('.work-showcase, button').click(function(){
moveAndResize($(this).index());
});
function moveAndResize(index){
var item = $('.work-showcase:eq('+index+')');
$('.work-showcase').animate({height:'135px'}, 500);
$(item).animate({height:'400px'}, 500,function() {
$("html, body").animate({ scrollTop: $(item).offset().top });
});
}
This works as long as the indexes are the same. If you want the index of the buttons to be different, add an id tag or something else that you can then pass to the moveAndResize which maps to the index of the item you want to change.