Stop scrolling down after scrolling to top - javascript

My problem is, that after fast scrolling down with the touchpad, the window is correctly jumping to the top after 300px, but after that, the browser is stil scrolling down.
Here is a example of my problem
https://codepen.io/anon/pen/XoMExW
I´ve tried this, but it didn´t work
How to disable scrolling temporarily?
$(window).scroll(function(){
if( $(window).scrollTop() >= 300 ){
$(window).scrollTop(0);
}
});

What you could do is after each scroll event, add a setTimeout. For every scroll event, you will first clear the one you created in the previous event and recreate a new one right after. This will keep running until you reach the last scroll event, then during this last scroll event, the callback of the setTimeout will be triggered and it will run your code:
var isScrolling;
$(window).scroll(function() {
window.clearTimeout(isScrolling);
isScrolling = setTimeout(function() {
if ($(window).scrollTop() >= 300) {
$(window).scrollTop(0);
}
}, 100);
});

Related

Animate in div with image when scroll down to the bottom of where the image using jQuery

I have static images that I want to animate in when the user scrolls to the bottom of where they would be (the bottom of their rectangle). I've tried using the code:
$(window).on("scroll", function(){
if($("body").scrollTop() === 500){
$(window).off("scroll");
//Do stuff here
$('.context_right').fadein(4000);
}
});
With .context_right being the that contains the image I want to slide in from off the right side of the screen. I have tested this in Chrome debugger but there is not animation at all and I can't see why it's not being fired when scrolling down.
You're checking if the scroll position of the window is exactly equal to 500px. This is likely incorrect. You probably only want to check and see if the user has scrolled past 500px.
Consider changing:
if($("body").scrollTop() === 500)
to:
if($("body").scrollTop() >= 500)
Also, be careful with this:
$(window).off("scroll");
If you use any libraries that rely on the scroll event on the window, you would be unbinding all of those events in addition to your own.
Consider refactoring to something like the following:
var scrollAnimateIn = function(){
if($("body").scrollTop() >= 500){
$(window).off("scroll", scrollAnimateIn);
//Do stuff here
$('.context_right').fadein(4000);
}
};
$(window).on("scroll", scrollAnimateIn);

How to enable normal scroll behavior, at certain DIV element

I'm having a bit of trouble getting a one-page scroll to behave the way I want it to. I would like the first to be full page and when they scroll down, it will full page scroll to the next element. But when they reach the 2nd section element - it will revert to regular scrolling behavior. This is because the rest of the page is not full page or one page.
I basically want the intro to be a full page, and then do a full page scroll into the next section where they can freely scroll down normally. When they scroll back up to the first section it should full page scroll again to the intro.
I'm using the below code. This is working for the full page transition into section 2, but I can't figure out how to revert to normal scrolling behavior after they reach section 2.
$('section').height($(window).height());
/*set the class 'active' to the first element
this will serve as our indicator*/
$('section').first().addClass('active');
/* handle the mousewheel event together with
DOMMouseScroll to work on cross browser */
$(document).on('mousewheel DOMMouseScroll', function (e) {
e.preventDefault();//prevent the default mousewheel scrolling
var active = $('section.active');
//get the delta to determine the mousewheel scrol UP and DOWN
var delta = e.originalEvent.detail < 0 || e.originalEvent.wheelDelta > 0 ? 1 : -1;
//if the delta value is negative, the user is scrolling down
if (delta < 0) {
//mousewheel down handler
next = active.next();
//check if the next section exist and animate the anchoring
if (next.length) {
/*setTimeout is here to prevent the scrolling animation
to jump to the topmost or bottom when
the user scrolled very fast.*/
var timer = setTimeout(function () {
/* animate the scrollTop by passing
the elements offset top value */
$('body, html').animate({
scrollTop: next.offset().top
}, 'slow');
// move the indicator 'active' class
next.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 800);
}
} else {
//mousewheel up handler
/*similar logic to the mousewheel down handler
except that we are animate the anchoring
to the previous sibling element*/
prev = active.prev();
if (prev.length) {
var timer = setTimeout(function () {
$('body, html').animate({
scrollTop: prev.offset().top
}, 'slow');
prev.addClass('active')
.siblings().removeClass('active');
clearTimeout(timer);
}, 800);
}
}
});
To hide scrollbars of the browser (and thus to have the look of full page) apply overflow:hidden css-property to body like
$(document.body).css('overflow', 'hidden');
When you scrolled down via javascript to a section where the user should be able to scroll with standard scrolls just let scrollbar-handling be done automatically again by
$(document.body).css('overflow', 'auto');
So apply the first javascript-snippet whenever you scrolled via javascript to a fullpage view apply the latter everytime you scrolled to a normal scrollable section again.

Fix delayed jquery fade on scroll

vol7ron showed me how to achieve an effect where an element fades in on scroll down, and fades out on scroll up here: Why does "($(this).css('opacity')==.3)" not work?
jsfiddle: http://jsfiddle.net/b7qnrsrz/16/
$(window).on("load", function () {
function fade() {
$('.fade').each(function () {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the object is completely visible in the window, fade it in */
if (objectBottom < windowBottom) { //object comes into view (scrolling down)
if ($(this).css('opacity') != 1) {
$(this).stop(true,false).fadeTo(500, 1);
}
} else { //object goes out of view (scrolling up)
if ($(this).css('opacity') == 1) {
$(this).stop(true,false).fadeTo(500, .3);
}
}
});
}
fade(); //Fade in completely visible elements during page-load
$(window).scroll(function () {
fade();
}); //Fade in elements during scroll
});
This works almost perfectly. As is, the boxes wait to fade until I've stopped scrolling. So if I smoothly scroll past three of them, rather than fading one-by-one as I scroll past each one, they all wait to fade in until after I stop scrolling. How can I remedy this so that fade triggers even while scrolling, not waiting until after stopping?
That's because there is a bug in the script.
Every time you scroll it executes the fade function. Because the animation is prefixed with a stop() the animation never really gets any time to run if you scroll slowly.
You can either remove the .stop() or find a way to only apply the fade-in to elements that are not already fading in.
There seems to be another bug. Sometimes items are not detected as being in the viewport and they will not fade in. I'm not sure why that happens. It might have something to do with scrolling really fast.

jQuery - Scroll Function Keeps Triggering: Only Once Please

I have the following jQuery function which triggers aTestEvent() when the user scrolls horizontally past 500 pixels:
jQuery(document).scroll(function(){
if(jQuery(this).scrollLeft() >= 500){
aTestEvent();
}});
Here's the issue: I only want aTestEvent() to be triggered once! However, every time the user scrolls back to the beginning of the page and then again past 500 pixels, aTestEvent() is triggered again.
How can we adjust the above code so that the trigger only occurs for the first time the user scrolls past 500 pixels?
You can use on and off methods:
$(document).on('scroll', function() {
if( $(this).scrollLeft() >= 500 ) {
$(document).off('scroll');
aTestEvent();
}
});
http://jsfiddle.net/3kacd/
Please Note: This code snippet could "off" all the scroll event available on a particular page but to scroll off only intended scroll handler without disturbing other scroll handlers, we can use a namespace. Namespaces are similar to CSS classes in that they are not hierarchical; only one name needs to match.
$(document).on('name1.scroll', function() {
if( $(this).scrollLeft() >= 500 ) {
$(document).off('name1.scroll');
aTestEvent();
}
});
http://jsfiddle.net/shekhardtu/3kacd/57/

How to check each new scroll and avoid Apple mouses issue (multiple-scroll effect)

I try to make a mousewheel event script, but getting some issues since I'm using an Apple Magic Mouse and its continue-on-scroll function.
I want to do this http://jsfiddle.net/Sg8JQ/ (from jQuery Tools Scrollable with Mousewheel - scroll ONE position and stop, using http://brandonaaron.net/code/mousewheel/demos), but I want a short animation (like 250ms) when scrolling to boxes, AND ability to go throught multiple boxes when scrolling multiple times during one animation. (If I scroll, animation start scrolling to second box, but if I scroll again, I want to go to the third one, and if I scroll two times, to the forth, etc.)
I first thought stopPropagation / preventDefault / return false; could "stop" the mousewheel velocity (and the var delta) – so I can count the number of new scroll events (maybe with a timer) –, but none of them does.
Ideas?
EDIT : If you try to scroll in Google Calendars with these mouses, several calendars are switched, not only one. It seems they can't fix that neither.
EDIT 2 : I thought unbind mousewheel and bind it again after could stop the mousewheel listener (and don't listen to the end of inertia). It did not.
EDIT 3 : tried to work out with Dates (thanks to this post), not optimal but better than nothing http://jsfiddle.net/eZ6KE/
Best way is to use a timeout and check inside the listener if the timeout is still active:
var timeout = null;
var speed = 100; //ms
var canScroll = true;
$(element).on('DOMMouseScroll mousewheel wheel', function(event) {
// Timeout active? do nothing
if (timeout !== null) {
event.preventDefault();
return false;
}
// Get scroll delta, check for the different kind of event indexes regarding delta/scrolls
var delta = event.originalEvent.detail ? event.originalEvent.detail * (-120) : (
event.originalEvent.wheelDelta ? event.originalEvent.wheelDelta : (
event.originalEvent.deltaY ? (event.originalEvent.deltaY * 1) * (-120) : 0
));
// Get direction
var scrollDown = delta < 0;
// This is where you do something with scrolling and reset the timeout
// If the container can be scrolling, be sure to prevent the default mouse action
// otherwise the parent container can scroll too
if (canScroll) {
timeout = setTimeout(function(){timeout = null;}, speed);
event.preventDefault();
return false;
}
// Container couldn't scroll, so let the parent scroll
return true;
});
You can apply this to any scrollable element and in my case, I used the jQuery tools scrollable library but ended up heavily customizing it to improve browser support as well as adding in custom functionality specific to my use case.
One thing you want to be careful of is ensuring that the timeout is sufficiently long enough to prevent multiple events from triggering seamlessly. My solution is effective only if you want to control the scrolling speed of elements and how many should be scrolled at once. If you add console.log(event) to the top of the listener function and scroll using a continuous scrolling peripheral, you will see many mousewheel events being triggered.
Annoyingly the Firefox scroll DOMMouseScroll does not trigger on magic mouse or continuous scroll devices, but for normal scroll devices that have a scroll and stop through the clicking cycle of the mouse wheel.
I had a similar problem on my website and after many failed attempts, I wrote a function, which calculated total offset of selected box and started the animation over. It looked like this:
function getOffset() {
var offset = 0;
$("#bio-content").children(".active").prevAll().each(function (i) {
offset += $(this)[0].scrollHeight;
});
offset += $("#bio-content").children(".active")[0].scrollHeight;
return offset;
}
var offset = getOffset();
$('#bio-content').stop().animate( {
scrollTop: offset
}, animationTime);
I hope it gives you an idea of how to achieve what you want.
you can try detecting when wheel stops moving, but it would add a delay to your response time
$(document).mousewheel(function() {
clearTimeout($.data(this, 'timer'));
$.data(this, 'timer', setTimeout(function() {
alert("Haven't scrolled in 250ms!");
//do something
}, 250));
});
source:
jquery mousewheel: detecting when the wheel stops?
or implement flags avoiding the start of a new animation
var isAnimating=false;
$(document).bind("mousewheel DOMMouseScroll MozMousePixelScroll", function(event, delta) {
event.preventDefault();
if (isAnimating) return;
navigateTo(destination);
});
function navigateTo(destination){
isAnimating = true;
$('html,body').stop().animate({scrollTop: destination},{complete:function(){isAnimating=false;}});
}

Categories

Resources