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));
});
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'm facing a very strange error, which is animation on body during mouse scroll. I think its happening because of the jQuery event window.scroll. I have tried a lot of things like unbinding of animation on mouse scroll, but nothing works. Below is my code.
$(document).on("scroll", function () {
var lastScrollTop = 0;
var windowHeight = $(window).scrollTop();
var seccion1 = $("#seccion1").height();
var seccion2 = $("#seccion2").offset().top;
var alturaseccion2 = $("#seccion2").height();
//this function returns in which section is the user with the scroll
var localizacion = comprobarSeccion(seccion1, seccion2);
if (windowHeight > lastScrollTop) {
// down scroll
console.log("scrollabajo");
if (localizacion == 1) {
$("html, body").animate({
scrollTop: $("#seccion2").offset().top
}, 2);
$(document).bind("scroll");
} else if (localizacion == 2) {
if (windowHeight >= ((alturaseccion2 * 0.80) + seccion2) && windowHeight <= (alturaseccion2 + seccion2)) {
} else {
}
}
} else {
// up scroll
console.log("scrollarriba");
}
lastScrollTop = windowHeight;
});
´´´
I'm not sure what you are trying to accomplish, but if your trying to trigger an event with a specific scroll value you can use the code below
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
alert("scroll is greater than 500 px)
} else if(scroll==500){
alert("scroll has hit 500px");
}
});
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);
});
I have infinity scroll and each time the top scroll reach to certain part of the div, it loads a new content until its over. But each time it loads, it get very slow. It happens when I put some code inside of .each function, and that my scroll becomes really slow, which is annoying. I don't know how to fix it
function scrollAnimationFrame(ticking, windowHeight, tabSelected){
if (!ticking) {
window.requestAnimationFrame(function() {
scrollEvent(tabSelected, windowHeight);
ticking = false;
});
}
ticking = true;
}
function scrollEvent(tabSelected, windowHeight) {
var activeTab = document.getElementsByName(tabSelected)[0]
var divResults = activeTab.getElementsByClassName('div-content');
var scrollY = window.scrollY || document.documentElement.scrollTop;
var pos = $(window).scrollTop();
var scrollY = window.scrollY || document.documentElement.scrollTop;
$(divResults).each(function(i, el){
var posOutsideDiv = $(el).offset().top + $(el).outerHeight();
var inside = (scrollY >= $(el).offset().top && scrollY <= posOutsideDiv - 150)
if(inside){
toggleThead(el, "visible");
} else if(scrollY >= $(el).offset().top && scrollY <= posOutsideDiv + $(document).height()){
toggleThead(el, "hidden");
} else {
toggleThead(el, "visible");
}
});
}
Okay, I thought it was javascript that the scroll is getting slower each time appending a new content. So I checked at AngularJs and I was reusing the directive template. So basically create two directives for each template and voilá(Hated doing this). No more slow scroll.
Is it possible to fire an alert after a user scrolls 100 pixels.
Here's what I have so far but I know I'm missing something;
$(window).scroll(function() {
if (document.documentElement.clientHeight +
$(document).scrollTop() == "100px")
{
alert("You've scrolled 100 pixels.");
}
});
Look at the window .scrollTop (returns an integer):
$(window).scroll(function() {
if ($(this).scrollTop() === 100) { // this refers to window
alert("You've scrolled 100 pixels.");
}
});
but if you have scrolled 102px it wont trigger the alert box.
if you just want to trigger the alert once have a global variable that sets to true if it has been trigged:
$(function(){
var hasBeenTrigged = false;
$(window).scroll(function() {
if ($(this).scrollTop() >= 100 && !hasBeenTrigged) { // if scroll is greater/equal then 100 and hasBeenTrigged is set to false.
alert("You've scrolled 100 pixels.");
hasBeenTrigged = true;
}
});
});
or just unbind the scroll event once the alert box has been trigged:
$(function(){
$(window).bind("scroll.alert", function() {
var $this = $(this);
if ($this.scrollTop() >= 100) {
alert("You've scrolled 100 pixels.");
$this.unbind("scroll.alert");
}
});
});
Try this:
$(document).scrollTop() >= 100) {
// ...
}
scrollTop() returns an integer. This version will evaluate to true once you have scrolled past 100px, which might be more appropriate.
try
document.documentElement.clientHeight + $(document).scrollTop() == 100