I've implemented a scroll left for navigating to sections that works perfectly.
Now I want to add anchors within a section so if you click on them they scroll down on a page to other anchors, smoothly. I'm trying to add the functionality within my existing function but to no avail.
I'm using "jquery.easing.pack.js".
In the original one I have the HTML and JS looks like this:
<!-- scroll left to sections -->
<section id="1" class="section"></section>
<section id="2" class="section"></section>
<section id="3" class="section"></section>
<script type="text/javascript">
$(function() {
var $sections = $('section.section');
$sections.each(function() {
var $section = $(this);
var hash = '#' + this.id;
$('a[href="' + hash + '"]').click(function(event) {
$scrollElement.stop().animate({
scrollLeft: $section.offset().left
}, 1200, 'easeOutCubic', function() {
window.location.hash = hash;
});
event.preventDefault();
});
});
});
</script>
Now I have:
<!-- scroll left to sections -->
<section id="1" class="section">
<a class="scroll-down" href="#bottom-div">scroll down</a><!-- scroll down to div -->
<div id="bottom-div>here we go</div>
</section>
<section id="2" class="section"></section>
<section id="3" class="section"></section>
At the moment if I click on the "scroll down" anchor it will go to the bottom-div but not smoothly. So I've tried adding another function like this but it's not working.. any ideas how to make it work and if possible with my existing function?
$(function() {
var $bottomdivs = $('.scroll-down');
$bottomdivs.each(function() {
var $bottomdiv = $(this);
var hash = '#' + this.id;
$('a[href="' + hash + '"]').click(function(event) {
$scrollElement.stop().animate({
scrollTop: $bottomdiv.offset().top-100
}, 1200, 'easeOutCubic', function() {
window.location.hash = hash;
});
event.preventDefault();
});
});
});
By setting the hash I think you are invoking the standard anchor link functionality to jump to the section. Try handling the scroll yourself like this:
var $sections = $('section.section');
$sections.each(function() {
var $section = $(this);
var hash = '#' + this.id;
$('a[href="' + hash + '"]').click(function(event) {
$('body, html').animate({
scrollLeft: $section.offset().left
}, {queue:false, duration: 1200, easing: 'swing'});
$('body, html').animate({
scrollTop: $section.offset().top
}, {queue:false, duration: 1200, easing: 'swing', done: function () {
window.location.hash = hash;
}
});
});
event.preventDefault();
});
I have put together a fiddle for you here: http://jsfiddle.net/rjE4s/
I am not sure what $scrollElement was so I have removed that from my example. Also I have changed your custom easing as I didn't have the easing pack installed. You can just change that back. Finally, I queued the animations so the left and top scroll at the same time, but you just set:
queue: true
in the animation options and it will animate the left and then the top like in your original function. Not sure if you wanted this or not.
Related
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
});
});
});
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 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)
So, I'm quite new to javascript and building a site where I'm trying to have animated scrolls on the page.
To enable animated scroll to a link I'm using this code:
jQuery(document).ready(function ($) {
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing', function () {
window.location.hash = target;
});
});
})();
To scroll to the top of the page I am using this code.
//<-- scroll top -->
var $top = jQuery.noConflict();
$top("#scroll-top").hide();
// fade in #scroll-top
$top(window).scroll(function () {
if ($top(this).scrollTop() > 150) {
$top('#scroll-top').fadeIn();
} else {
$top('#scroll-top').fadeOut();
}
});
// scroll body to 0px on click
$top('#scroll-top a').click(function () {
$top('body,html').animate({
scrollTop: 0
}, 800);
return false;
});
They both work fine independently, but not together.
Can anybody help me find out why they conflict, and how to solve the conflict?
So, this is how I fixed my issue:
I removed the conflicting code " // scroll body to 0px on click " and instead use the animated scroll to anchor link to animate both functions, with a placed on top of the page as well.
jQuery(document).ready(function ($) {
$('a[href^="#"]').on('click',function (e) {
e.preventDefault();
var target = this.hash,
$target = $(target);
$('html, body').stop().animate({
'scrollTop': $target.offset().top
}, 900, 'swing', function () {
window.location.hash = target;
});
});
})();
I works fine, but I am missing only one feature, that the javascript recognises internal links that start with anything else than #. Right now it doesn't recognise for example this link http://julebord.bedriftsdesign.no/julebord.html#julemeny. It only works if I use this: #julemeny
When a user clicks on the "Contact Me" button, i want the screen to slide to the #contact element, however cannot figure out how to do it. I've tried various different snippets of code and tried to tailor it to my needs, but nothing seems to work.
The site is here; http://dombracher.com/
Simply want the screen to slide to the div mentioned above, rather than quickly snap to it.
Thanks in advance.
$(document).ready(function() {
$("a[href^='#']").anchorAnimate()
});
jQuery.fn.anchorAnimate = function(settings) {
settings = jQuery.extend({
speed : 1100
}, settings);
return this.each(function(){
var caller = this
$(caller).click(function (event) {
event.preventDefault()
var locationHref = window.location.href
var elementClick = $(caller).attr("href")
var destination = $(elementClick).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, settings.speed, function() {
window.location.hash = elementClick
});
return false;
})
})
}
You can animate window scroll by yourself
$(".menu2").click(function(){
$(document.body).animate({
"scrollTop": $("#contact").offset().top
}, 2000, "swing"); // animation time and easing
return false; // preventing default jump
});
Fiddle: http://jsfiddle.net/M8JE2/
Or use jquery plugin like http://flesler.blogspot.com/2007/10/jquerylocalscroll-10.html to make any/all local links work with animation.
Here it is , scrolls to the bottom of the page since your contact form is there:
jQuery(function () {
jQuery('#nav1 li.menu2').click(function (e) {
jQuery("html, body").stop().animate({
scrollTop: jQuery(document).height()
}, 1000);
e.preventDefault();
return false;
});
});