Script takes a few seconds to load on older iOS devices. I tested on my iPhone 7 and works fine.
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 300) {
$('#bottombadge').fadeIn;
}
else {
/* (y <= 300) */
$('#bottombadge').fadeOut();
}
});
It's mainly the fadeIn that is super slow. Any ideas please? Thank you
The issue is because scroll fires for every pixel that's scrolled. Therefore if you scroll 200px you're potentially calling fadeIn() 200 times. To fix this you need to 'debounce' the scroll event so that it only happens N ms after scrolling has stopped:
var timer;
$(document).scroll(function () {
var $doc = $(this);
clearTimeout(timer);
timer = setTimeout(function() {
var y = $doc.scrollTop();
$('#bottombadge')[y > 300 ? 'fadeIn' : 'fadeOut']();
}, 150);
});
Related
i wrote a script that basically gives the topper element a negative margin bottom,
so it makes the element below it go up and it kind of makes a parallax like scroll, my problem is i wrote the function as a scroll and i think the function runs so much that it makes the page kind of laggy, here`s my code, i hope you guys can help me out.
$(window).on('scroll', function () {
if (scrollY >= 100) {
$("#gallery").css("margin-bottom", -((scrollY - 100) / 4));
}
});
For one, you are re-querying the DOM every time the scroll event fires. I would start by caching the selector outside of the event handler.
var $gallery = $("#gallery");
$(window).on('scroll', function () {
if (scrollY >= 100) {
$gallery.css("margin-bottom", -((scrollY - 100) / 4));
}
});
You then might want to play around with wrapping your DOM manipulations in a setTimeout.
var $gallery = $("#gallery");
var delay;
$(window).on('scroll', function () {
delay = setTimeout(function() {
if (scrollY >= 100) {
$gallery.css("margin-bottom", -((scrollY - 100) / 4));
}
}, 50);
});
EDIT:
For detecting scroll direction, try something like:
var $gallery = $("#gallery");
var delay;
var lastScrollTop = 0;
$(window).scroll(function(event){
var scrollPos = $(this).scrollTop();
delay = setTimeout(function() {
if (scrollPos > lastScrollTop){
if (scrollY >= 100) {
$gallery.css("margin-bottom", -((scrollY - 100) / 4));
}
} else {
if (scrollY < 100) {
$gallery.css("margin-bottom", -((scrollY + 100) / 4));
}
}
}, 50);
lastScrollTop = st;
});
The lag you experience is due to two main factors.
There are a huge number of Scroll events fired when a page is
scrolled
Javascript implementations are primarily single
threaded.
What can we do two fix these problems?
To fix the first issue, you can either debounce or throttle the onscroll callback function. Here is a simple but good write up about these techniques.
To fix the second problem, is to give that single thread time to do other tasks as well. If you endup using debounce or throttle, it should help or you can rely on browsers eventloop.
Basically, the idea is to tell the browser that Hey, this is something I want you to do, but take your time. The simplest ways to do that is by using setTimeout webapi.
Rewriting your implementation,
var gallery = $("#gallery");
var scrollHandler = function() {
if (scrollY >= 100) {
gallery.css("margin-bottom", -((scrollY - 100) / 4));
}
}
$(window).on('scroll', function() {
setTimeout(scrollHandler, 4)
});
I have the following Javascript code:
$(window).scroll(function() {
if (window.innerWidth <= 768) {
let scrollStatus = $(this).scrollTop();
if (scrollStatus > lastScrollTop) {
//do some stuffs
else
//do some other stuffs
lastScrollTop = scrollStatus;
}
});
So it worked well with non-mobile devices and Android devices. However, when I ran that on iOS's Safari and scroll to the topmost, it drags down the viewport by a little bit before bouncing up back when I release my finger hold. That bounce back up is detected by the above Javascript code as scrolling up and causes the trigger on the else section, which is undesirable. How do I fix this?
Before bouncing back Safari overscrolls the Y-Position into negative land. You can use this to ignore position changes from the bounce animation.
The window scroll event fires very rapidly. For performance reasons you don't want to handle these events directly.
The example below shows how to check in 250ms intervals whether the user has scrolled, which is easy on performance.
var didScroll = false;
$(window).scroll(function() {
didScroll = true;
});
// interval scroll handler
setInterval(function() {
if ( didScroll ) {
didScroll = false;
scrolled();
}
}, 250);
var lastScrollTop = 0;
function scrolled() {
var scrollStatus = window.pageYOffset;
if (scrollStatus < lastScrollTop) {
//user scrolled up
} else if ( lastScrollTop >= 0) {
//user scrolled down
}
lastScrollTop = scrollStatus;
}
Alternatively you can alleviate performance issues by resetting a timeout that only calls the scrolled() function after scrolling has finished.
var timer;
$(window).scroll(function() {
if ( timer ) clearTimeout(timer);
timer = setTimeout(function(){
scrolled();
}, 100);
});
var lastScrollTop = 0;
function scrolled() {
var scrollStatus = window.pageYOffset;
if (scrollStatus < lastScrollTop) {
//user scrolled up
} else if ( lastScrollTop >= 0) {
//user scrolled down
}
lastScrollTop = scrollStatus;
}
i'd like to limit scrolling on my webpage to divs/sections whatever.
Like limiting the scroll step to the screen-height.
If a user scrolls whether it is with a mouse-wheel or a mac 2-finger-scroll.
He should scroll automatically to the next section or the previous one.
Example pages: Jenny Example FLPNY Example
I have already found a function here, to limit listening to the scroll event (debounce). I just can't figure out how no to get a random scroll behaviour.
function debounce(func, interval) {
var lastCall = -1;
return function () {
clearTimeout(lastCall);
var args = arguments;
lastCall = setTimeout(function () {
func.apply(this, args);
}, interval);
};
}
$(window).on('wheel', debounce(function (e) {
currentScrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
var delta = e.originalEvent.deltaY;
if (delta > 0) {
console.log("down");
$("html, body").animate({
scrollTop: nextSection
}, 500);
}
else {
console.log("up");
// this will search within the section
$("html, body").animate({
scrollTop: prevSection
}, 500);
}
Not quite sure what you mean by:
I just can't figure out how no to get a random scroll behaviour.
But the site you link is making use of fullPage.js.
This is what I use to make 2 divs "unwrap" while scrolling:
CSS
.entry {
height: 40px;
}
.entry.expanded {
height:600px;
}
JavaScript
$($('.entry').get(0)).addClass('expanded');
$(window).on('scroll', function (e) {
var x = $(window).scrollTop();
if (x > 820) {
$($('.entry').get(1)).addClass('expanded');
}
if (x > 1525) {
$($('.entry').get(2)).addClass('expanded');
}
});
It works perfectly fine on my 1920x1080p screen but it doesn't on a friend's 1920x1200px because there aren't 820px to scroll..
How can I solve this to work with every resolution? I tried with this, but unfortunately nothing happens:
$($('.entry').get(0)).addClass('expanded');
$(window).on('scroll', function (e) {
var availableScroll = $(document).height() - $window.height();
var x = $(window).scrollTop();
if (x > 820 || x == availableScroll) {
$($('.entry').get(1)).addClass('expanded');
}
if (x > 1525 || x == availableScroll) {
$($('.entry').get(2)).addClass('expanded');
}
});
Is there a fancy method, that maybe calculates the pixels from the bottom or some method relative to the vertical res?
Here's the webpage with the code live (you can see the 2 divs unwrapping when scrolling).
In general, avoid the == for scrolling because if the scroll is off by even .0001 it will resolve as false. Also replace $window with $(window).
$($('.entry').get(0)).addClass('expanded');
$(window).on('scroll', function (e) {
var availableScroll = $(document).height() - $(window).height();
var x = $(window).scrollTop();
if (x > 820 || Math.abs(x - availableScroll) < 10) {
$($('.entry').get(1)).addClass('expanded');
}
if (x > 1525 || Math.abs(x - availableScroll) < 10) {
$($('.entry').get(2)).addClass('expanded');
}
});
Also, if you want to execute code when the page first loads, use the $(document).ready(handler) pattern.
Your former functions seems to working fine. I am testing it as MacBook Pro. However, at sometime it seems it is not fired at JQuery. What you can do is you can wait for few milliseconds to check if the scroll is finished. If scroll is finished then you can simply check the value of scroll.
Option 1:
jQuery debounce is a nice one for problems like this. jsFidlle
So your modified code will be (you need to use debounce)
$(window).scroll($.debounce( 250, true, function(){
console.log("Still scrolling");
}));
$(window).scroll($.debounce( 250, function(){
var x = $(window).scrollTop();
console.log("Scrolling finished");
if (x > 820) {
$($('.entry').get(1)).addClass('expanded');
}
if (x > 1525) {
$($('.entry').get(2)).addClass('expanded');
}
}));
Option 2:
There may be a chance you don't like use JQuery Debounce then you can native approach with timer function. See the code below and you can adjust the timer duration as per your needs.
It is simply waiting for scroll event to be finished and wait for certain milliseconds before it scroll event recalled. If scroll refires then it simply clear the timer and start waiting again. If timer is finished then it executes the method you have stated.
$(window).scroll(function() {
var timerDuration = 250; // In milliseconds
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
// do something
var x = $(window).scrollTop();
console.log("Scrolling finished");
if (x > 820) {
$($('.entry').get(1)).addClass('expanded');
}
if (x > 1525) {
$($('.entry').get(2)).addClass('expanded');
}
}, timerDuration));
});
What is the equivalent of this:
$('html, body').animate({
scrollTop: 200
}, 400);
In MooTools or agnostic javascript?
Im going round in circles....
Cheers
This loop can animate the scrollTop property of the window in basic javascript:
window.onload = function() {
var offset = 0; //vertical offset
var interval = setInterval(function() {
window.scrollTo(0, offset);
offset += 4; // plus 4 pixels
if (offset >= 200) {
clearInterval(interval);
}
}, 8); // 200px/4px==50 cycles ; 400ms/50cycles == 8ms per cycle
};
fiddle
Because you asked for a version in mootools, it's just one line:
new Fx.Scroll(window).start(0, 200);
http://jsfiddle.net/ye3vX/
Note: It needs mootools more's Fx.Scroll.