Please check what i did yet http://jsfiddle.net/dUVmh/1/ .
About the animation i want to achieve is that:
When you first scroll down the page then window scroll to #green DIV. After that if you again scroll down window scroll to #yellow DIV & same at the time of scrollup (fom #yellow to #green).
About the issue:
You can see the animation it's stuck on #green DIV.
$(window).scroll(function(){
if($(this).scrollTop() > 0) {
$("html, body").animate({ scrollTop: $('#green').offset().top }, 1000);
}
else if($(this).scrollTop() > 1000) {
$("html, body").animate({ scrollTop: $('#yellow').offset().top }, 1000);
}
else{
$("html, body").animate({ scrollTop: $('#red').offset().top }, 1000);
}
});
I didn't have much experience in JS.
Thanks i advance :)
This was a fun problem to work on.
This solution places the divs into an array, and remembers the array index of the element that was last scrolled to. Once a scroll event is triggered it checks to see if the new scrollTop is above or below the current divs top offset and moves to the next or previous div in the array accordingly.
This solution allows you to have many divs. I tried to remove the flickering you get when you scroll to fast, but the only way to do that I believe would be to disable the scrollbars during animation.
http://jsfiddle.net/dUVmh/35/
$(function() {
var divs = [],
body = $('body, html'),
currentDiv = 0,
timeout;
$('div').each(function() {
divs.push($(this));
});
// we only need to capture the first scroll event triggered and then
// add another listener once we have done our animation
var scrollListen = function() {
$(window).one('scroll', function() {
doScroll($(this).scrollTop());
});
};
// Without the timeout, the scroll event would be triggered again too soon
var scrollEnd = function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
scrollListen();
}, 10);
};
// checks if the scroll direction was up and down and animates
// the body scrollTop to the next or previous div
var doScroll = function(scrollTop) {
var direction = scrollTop - divs[currentDiv].offset().top;
if (direction > 0 && currentDiv + 1 < divs.length) {
nextDiv = currentDiv + 1;
} else if (currentDiv - 1 > -1) {
nextDiv = currentDiv - 1;
}
if (currentDiv === nextDiv) {
scrollEnd();
}
body.animate({
scrollTop: divs[nextDiv].offset().top
}, 1000, function() {
currentDiv = nextDiv;
scrollEnd();
});
};
scrollListen();
});
Edit: Firefox scrollTop required to be changed on html and not body. Also fixed a problem with firefox calling scrollListen more than once at a time.
The problem is that the $(window).scroll(function()) gets called over and over again when scrolling through the ScrollTop animation with jQuery.
Here is a possible solution that checks if it is currently scrolling or not and only executes the ScrollTop animation once.
http://jsfiddle.net/dUVmh/29/
Side note: It might be a good idea to check which direction the user is scrolling (up or down) and depending on that scroll to the next div to the top or to the down.
You can check that be saving the last scrollTop position and comparing it with the current one.
UPDATE: Here's a solution that takes the scroll direction into account: http://jsfiddle.net/dUVmh/36/
Related
I've got two functions for two different things.
For one, I'm getting smooth scroll for the anchor links on the page.
$(window).on("load",function () {
// bind click event to all internal page anchors
$('a[href*="#"]').on('click', function (e) {
// prevent default action and bubbling
e.preventDefault();
e.stopPropagation();
// set target to anchor's "href" attribute
var target = $(this).attr('href');
// scroll to each target
$(target).velocity('scroll', {
duration: 700,
offset: -50,
easing: 'ease',
});
});
});
The other is for fading in the content when you scroll to it.
// fade all the sections
$(window).on("load",function() {
$(window).scroll(function() {
var currentPos = $(this).scrollTop()
$(".section").each(function() {
var topPos = $(this).offset().top - 500,
bottomPos = topPos + $(this).outerHeight();
/* If the element is completely within bounds of the window, fade it in */
if (currentPos >= topPos && currentPos <= bottomPos) { //object comes into view (scrolling down)
$(this).fadeTo(700,1);
}
});
}) //invoke scroll-handler on page-load
});
If I remove either one of these functions the entire thing will work fine. With both of them, they cause the page to have a huge delay in link clicks only after you've clicked down the page.
Solution:
Use css for the fade in instead of Jquery
Here is my Code: Demo
The demo is working fine on manual scrolling for each div to scrolltop.
What I need is: If I click the Auto Start button I want to Auto scroll 1, Auto scroll 2, ... Auto scroll n each div to scrolltop.
$(".jumper").on("click", function() {
var links = $(this).attr('href');
var type = links.substring(links.indexOf('#')+1);
$("body, html").animate({
scrollTop: $('#'+type).offset().top
}, 1500);
});
Each div should reach scrolltop and stop, then go to next div scrolltop with same time interval.
This is how I did it:
$(".autostart").on("click", function() {
scrollToElem($("#auto-scroll"));
var scrollList = $("#auto-scroll").nextAll();
var current = 0;
time = setInterval(function() {
scrollToElem($(scrollList.get(current)));
current++;
if (scrollList.length == current) {
clearInterval(time);
}
}, 2000);
});
Here is the JSFiddle demo
You have error in your code. .top of undefined. You can use links as selector as it contains both idselector + id :
$(".jumper").on("click", function() {
var links = $(this).attr('href');
$("body, html").animate({
scrollTop: $(links).offset().top
}, 1500);
});
I am trying to automate a scroll of 750px once the user has scroll 1px
, but reached 750 that I would scroll back to normal and the effect start again only if I am at the top of the page .
jQuery.noConflict()(function ($){
$(window).scroll(function (event) {
var body = $("html, body");
var scroll = $(window).scrollTop();
body.stop().animate({scrollTop:750}, '1500');
});
});
This is my code , but continues to scroll automatically to 750px how can I stop the event and start it again only if im ot the top of the body ?
you just need to add an if around the animate call.
if(scroll == 0){
body.stop().animate({scrollTop:750}, '1500');
}
otherwise everytime you scroll it will call the animate and return to 750px position
As i understand it, you want the scroll event to be fired only when the top of page has been reached. So you could toggle a class on the body element:
$(window).on('scroll', function(event) {
var scroll = $(window).scrollTop();
var $body = $('body');
if ($body.hasClass('onTop')) {
$("html, body").animate({
scrollTop: 750
}, '1500');
}
$body.toggleClass('onTop', scroll === 0);
}).scroll(); // trigger it on load or set it directly in HTML markup: <body class="onTop">
At my page, i have a few booleans in my script, to check if the first screen is activated, and the same thing for the second screen. Screen 1 fills up the whole screen.
It looks something like this:
var headerLoaded = true,
contentLoaded = false;
When i scroll, i want the page to scroll automaticly to the 'content' area of my webpage. And i had this code for it:
$(window).scroll(function() {
if (($(window).scrollTop() > 0) && (!contentLoaded && headerLoaded)) {
$('html, body').animate({
scrollTop: $('#content').offset().top
}, 500, function() {
contentLoaded = true;
headerLoaded = false;
});
}
});
It checks if im not at the top of the page, and for the 2 booleans.
The function works great, but it's still calling the
$('html, body').animate({
scrollTop: $('#content').offset().top
}, 500, function() {
contentLoaded = true;
headerLoaded = false;
});
part when i'm scrolled down to the 'content' div.
So everytime i scroll when im at the 'content' div, its scrolling back to the top of that.
Btw, both of the div's are absolute.
So, the animate is calling your original $(window).scroll(...) over and over.
Try telling your main scroll listener not to start animating if its already animating.
var animating = false;
$(window).scroll(function() {
if (!animating && $(window).scrollTop() > 0 && !contentLoaded && headerLoaded) {
animating = true;
$('html, body').animate({
scrollTop: $('#content').offset().top
}, 500, function() {
animating = false;
contentLoaded = true;
headerLoaded = false;
});
}
});
wait.. i just read it..
You're just locking the screen at the content... why animate at all?
The answer I was giving was saying the animating the scroll will also trigger the main scroll, resulting in an endless loop... but what are you trying to do in the first place?
I'm extremely new to JavaScript so I apologize in advance. I'm trying to create a one page html document for a school project using a list of links for navigation that change when the anchor is scrolled to. I've tried various different methods found on Jfiddle and through stackoverflow. This is the method I am trying now: http://jsfiddle.net/m2zQE/
var topRange = 200, // measure from the top of the viewport to X pixels down
edgeMargin = 20, // margin above the top or margin from the end of the page
animationTime = 1200, // time in milliseconds
contentTop = [];
$(document).ready(function () {
// Stop animated scroll if the user does something
$('html,body').bind('scroll mousedown DOMMouseScroll mousewheel keyup', function (e) {
if (e.which > 0 || e.type == 'mousedown' || e.type == 'mousewheel') {
$('html,body').stop();
}
});
// Set up content an array of locations
$('#nav').find('a').each(function () {
contentTop.push($($(this).attr('href')).offset().top);
});
// Animate menu scroll to content
$('#nav').find('a').click(function () {
var sel = this,
newTop = Math.min(contentTop[$('#nav a').index($(this))], $(document).height() - $(window).height()); // get content top or top position if at the document bottom
$('html,body').stop().animate({
'scrollTop': newTop
}, animationTime, function () {
window.location.hash = $(sel).attr('href');
});
return false;
});
// adjust side menu
$(window).scroll(function () {
var winTop = $(window).scrollTop(),
bodyHt = $(document).height(),
vpHt = $(window).height() + edgeMargin; // viewport height + margin
$.each(contentTop, function (i, loc) {
if ((loc > winTop - edgeMargin && (loc < winTop + topRange || (winTop + vpHt) >= bodyHt))) {
$('#nav li')
.removeClass('selected')
.eq(i).addClass('selected');
}
});
});
});
I'm still not having any luck. I've already searched to see if I could debug the problem and have tried changing the order of the code as well as the order of calling jquery.
Here is a link to the site: https://googledrive.com/host/0BwvPQbnPrz_LMlZDeGlFY2Yydmc/index.html
I used html5boilerplate as a starting point.Thank you in advance.
Don't have much time to look into your code, but when I input the line
Math.min(contentTop[$('#nav a').index($(this))], $(document).height() - $(window).height())
into the console of developer tools, it return NaN.
So I guess the problem is you don't have your scrollTop correctly set.
I suggest you give each element an id and try:
$('html, body').animate({
scrollTop: $("#elementID").offset().top
}, 2000);
or if you insist not giving id,
$('html, body').animate({
scrollTop: $("#container-fulid:nth-child(2)").offset().top
}, 2000);
but notice that this is not working on all browser as the nth-child selector is a CSS3 selector.
Or, if you know how to correctly use other's work, you may try to use bootstrap 3.0, where there is already a function named scrollspy included, which do exactly the thing you are doing.
http://getbootstrap.com/javascript/#scrollspy