I have the following code which applies class which shows/hide a div.
$(document).ready(function($) {
function reusuableUpAnimFunc(elementName, offset, hideClass, showClass) {
$(window).scroll(function() {
$animation = $(elementName);
($(this).scrollTop() > offset) ? $animation.removeClass(hideClass).addClass(showClass):
$animation.addClass(hideClass).removeClass(showClass);
});
}
reusuableUpAnimFunc('#top-btn', 400, 'element-hide', 'element-show');
});
css
.element-hide {
opacity: 0;
visibility: hidden;
}
.element-show {
opacity: 1;
visibility: visible;
}
Problem is when the page first loads the div is visible, then as soon as user scrolls it disappears, then reappears as it's supposed to. I want it to be opacity 0 until the offset distance is reached
You could trigger the scroll callback function on page load with triggerHandler('scroll'). I would write it as follows:
$(document).ready(function($) {
function swapClass(selector, class1, class2, setClass2) {
$(selector).toggleClass(class1, !setClass2).toggleClass(class2, setClass2);
}
function reusuableUpAnimFunc(selector, offset, hideClass, showClass) {
$(window).scroll(function () {
swapClass(selector, hideClass, showClass, $(this).scrollTop() > offset);
}).triggerHandler('scroll');
}
reusuableUpAnimFunc('#top-btn', 50, 'element-hide', 'element-show');
});
.element-hide {
opacity: 0;
visibility: hidden;
}
.element-show {
opacity: 1;
visibility: visible;
}
p { height: 50px };
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>scroll down...<p>
<div id="top-btn">This will appear on scrolling</div>
<p></p><p></p><p></p><p></p><p></p>
Or, you could just call the function explicitly:
// ...
$(window).scroll(function () {
swapClass(selector, hideClass, showClass, $(this).scrollTop() > offset);
});
// Call it now:
swapClass(selector, hideClass, showClass, $(this).scrollTop() > offset);
// ...
Related
I don't know if I'm doing it right but I want to scroll to the next div when the user scroll down and scroll to the previous div in the page when the user scroll up.
First of all I do this to test the scroll event and the animation of scrolling :
$(document).ready(function() {
$(window).scroll(function(){
$("html, body").animate({
scrollTop: 1000
}, 1000);
});
});
That's just a test but it work well.
Now, I want to differentiate the scroll down and the scroll up event to scroll to the next or the previous div so I search and I found some solutions like this :
$(document).ready(function() {
var lastPosition = $(window).scrollTop();
$(window).scroll(function(){
var newPosition = $(window).scrollTop();
if(lastPosition - newPosition > 0){
$("html, body").animate({
scrollTop: 1000
}, 1000);
}
else {
$("html, body").animate({
scrollTop: 0
}, 1000);
}
});
});
But it doesn't work...
I think the method to get the scroll down or the scroll up doesn't work in my case.
Do you have any solution to do this or maybe an alternative ?
Thank you.
In your case, the height of the body or your container should be set to the window height and the overflow of that should be set to hidden, because you want to scroll to the target Div by javascript.
by setting the overflow: hidden on the body or your container, you prevent
the window from scrolling on the page.
body {
background: #eee;
height: 100%;
overflow: hidden;
}
The next step is detecting the scrolling direction (Up/Down). You can
check it by the deltaY property of the scroll event.
Finally, get the next or previous Div and scroll to it.
The complete example is here
$(window).on('mousewheel DOMMouseScroll', function(event) {
var deltaY = event.originalEvent.deltaY || event.deltaY;
if (deltaY > 0) {
// Scrolled to Down: Next Div
} else if (deltaY < 0) {
// Scrolled to Up: Previous Div
}
});
You can see the completed code here:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" type="text/javascript"></script>
<style type="text/css">
body {
background: #eee;
height: 100%;
overflow: hidden;
}
.section {
height: 600px;
}
.section.active {
background: #ccc;
}
</style>
</head>
<body>
<div class="active section">Section 1</div>
<div class="section">Section 2</div>
<div class="section">Section 3</div>
<script type="text/javascript">
$(window).on('mousewheel DOMMouseScroll',function(event) {
var deltaY = event.originalEvent.deltaY || event.deltaY,
$activeSection = $('.section.active'),
$container = $('body'),
containerOffset = $container[0].offsetTop,
$targetSection = null,
mustBeScroll = false;
if(deltaY > 0) { // Scrolled to Down: Next Div
if($activeSection.next('.section').length > 0) {
$targetSection = $activeSection.next('.section');
mustBeScroll = true;
}
} else if (deltaY < 0) { // Scrolled to Up: Previous Div
if ($activeSection.prev('.section').length > 0) {
$targetSection = $activeSection.prev('.section');
mustBeScroll = true;
}
}
if(mustBeScroll == true) {
$container.stop(false, true).animate({ scrollTop : $targetSection[0].offsetTop - containerOffset }, 500);
// Change background color
$activeSection.removeClass('active');
$targetSection.addClass('active');
}
});
</script>
</body>
</html>
I am trying to implement a left/right sliding animation inside of a JavaScript switch statement and the animation (sliding left and right without a bounce effect and no whitespace in between images) is not consistently activating. Also, the slide animation still activates when the previous button is clicked on the first slide and when the next button is clicked on the last slide. This should not be happening. Does anyone have any thoughts? Please see the code example.
$(function() {
// USER EDITABLE CONTROLS
var content = 'img'; // accepts any DOM element - div, img, table, etc...
var showControls = true; // true/false shows/hides the slider's navigational controls
var transition = 'slide'; // supports default, fade, slide
var transitionDuration = .5; // adjust the time of the transition measured in seconds
// VARIABLE DECLARATIONS
var contentType = $(content);
var $el = $('#showcase');
var $leftArrow = '#left_arrow';
var $rightArrow = '#right_arrow';
var $load = $el.find(contentType)[0];
var slideCount = $el.children().length;
var slideNum = 1;
// PRELOADS SLIDE WITH CORRECT SETTINGS
$load.className = 'active';
// ADD SLIDER CONTROLS TO PAGE
if (showControls === true) {
$('<div id="controls">« Previous Next »</div>').insertAfter('#showcase');
$('#controls').find('#left_arrow').addClass('disabled');
}
// LOGIC FOR SLIDE TRANSITIONS
function transitions() {
switch (transition) {
// FADE TRANSITION
case 'fade':
$('.slide').stop().animate({opacity : 0}, transitionDuration*300, function(){
$('.active').stop().animate({opacity : 1}, transitionDuration*1000);
});
break;
// SLIDE TRANSITION
case 'slide':
if (slideNum > 1) {
$('.slide').stop().animate({left : -160}, transitionDuration*800, function(){
$('.active').stop().animate({left : 0}, transitionDuration*1000);
});
}
if (slideNum < slideCount) {
$('.slide').stop().animate({left : 160}, transitionDuration*800, function(){
$('.active').stop().animate({left : 0}, transitionDuration*1000);
});
}
break;
// DEFAULT TRANSITION
case 'default':
break;
}
}
// CHECKS FOR FIRST AND LAST INDEX IN THE SLIDER
function checkSlide() {
if (slideNum == 1) {
$($leftArrow).addClass('disabled');
} else {
$($leftArrow).removeClass('disabled');
}
if (slideNum == slideCount) {
$($rightArrow).addClass('disabled');
} else {
$($rightArrow).removeClass('disabled');
}
}
// NAVIGATIONAL LOGIC FOR PREVIOUS/NEXT BUTTONS
$(document).on('click', $leftArrow, function() {
if (slideNum > 1) {
var counter = $('.active').index();
counter--;
$('.active').addClass('slide');
$('.active').removeClass('active');
transitions();
$el.find(contentType).eq(counter).addClass('active');
slideNum--;
checkSlide();
}
})
$(document).on('click', $rightArrow, function() {
if (slideNum < slideCount) {
var counter = $('.active').index();
counter++;
$('.active').addClass('slide');
$('.active').removeClass('active');
transitions();
$el.find(contentType).eq(counter).addClass('active');
slideNum++;
checkSlide();
}
})
});
#showcase {
width: 160px;
overflow: hidden;
}
img {
width: 160px;
}
a {
color: blue;
}
.disabled {
color: red !important;
}
.slide {
display: none;
opacity: 0;
position: relative;
left: 0px;
right: 0px;
}
.active {
display: block;
opacity: 1;
position: relative;
left: 0px;
right: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="showcase">
<img class="slide" src="https://picsum.photos/458/354" />
<img class="slide" src="https://picsum.photos/458/354/?image=306" />
<img class="slide" src="https://picsum.photos/458/354/?image=626" />
</div>
As said in the comments you need to fix your conditional statements. Awhile ago you had set two click handlers - one of which is binded (and is triggered regardless of any condition) when the other handler is triggered, this caused the slide animation still activates when the previous button is clicked on the first slide and when the next button is clicked on the last slide issue.
As for the animations, see my code below. I hacked your conditions a litte. When previous is clicked, the slide is to move from left to right. When next is clicked the slide is to move from right to left. I used a flag to determine the movement it will make - see the new paramter for transition function
$(function() {
// USER EDITABLE CONTROLS
var content = 'img'; // accepts any DOM element - div, img, table, etc...
var showControls = true; // true/false shows/hides the slider's navigational controls
var transition = 'slide'; // supports default, fade, slide
var transitionDuration = .5; // adjust the time of the transition measured in seconds
// VARIABLE DECLARATIONS
var contentType = $(content);
var $el = $('#showcase');
var $leftArrow = '#left_arrow';
var $rightArrow = '#right_arrow';
var $load = $el.find(contentType)[0];
var slideCount = $el.children().length;
var slideNum = 1;
// PRELOADS SLIDE WITH CORRECT SETTINGS
$load.className = 'active';
// ADD SLIDER CONTROLS TO PAGE
if (showControls === true) {
$('<div id="controls">« Previous Next »</div>').insertAfter('#showcase');
$('#controls').find('#left_arrow').addClass('disabled');
}
// LOGIC FOR SLIDE TRANSITIONS
function transitions(impl = null) {
switch (transition) {
// FADE TRANSITION
case 'fade':
$('.slide').stop().animate({
opacity: 0
}, transitionDuration * 300, function() {
$('.active').stop().animate({
opacity: 1
}, transitionDuration * 1000);
});
break;
// SLIDE TRANSITION
case 'slide':
if (impl == "next") {
$('.slide').css("left", '160px');
$('.slide').stop().animate({
left: 160
}, transitionDuration * 800, function() {
$('.active').stop().animate({
left: 0
}, transitionDuration * 1000);
});
} else if (impl == "prev") {
$('.slide').css("left", '-160px');
$('.slide').stop().animate({
left: -160
}, transitionDuration * 800, function() {
$('.active').stop().animate({
left: 0
}, transitionDuration * 1000);
});
}
break;
// DEFAULT TRANSITION
case 'default':
break;
}
}
// CHECKS FOR FIRST AND LAST INDEX IN THE SLIDER
function checkSlide() {
if (slideNum == 1) {
$($leftArrow).addClass('disabled');
} else {
$($leftArrow).removeClass('disabled');
}
if (slideNum == slideCount) {
$($rightArrow).addClass('disabled');
} else {
$($rightArrow).removeClass('disabled');
}
}
// NAVIGATIONAL LOGIC FOR PREVIOUS/NEXT BUTTONS
$(document).on('click', $leftArrow, function() {
if (slideNum > 1) {
var counter = $('.active').index();
counter--;
$('.active').addClass('slide');
$('.active').removeClass('active');
transitions('prev');
$el.find(contentType).eq(counter).addClass('active');
slideNum--;
checkSlide();
}
})
$(document).on('click', $rightArrow, function() {
if (slideNum < slideCount) {
var counter = $('.active').index();
counter++;
$('.active').addClass('slide');
$('.active').removeClass('active');
transitions('next');
$el.find(contentType).eq(counter).addClass('active');
slideNum++;
checkSlide();
}
})
});
#showcase {
width: 160px;
overflow: hidden;
}
img {
width: 160px;
}
a {
color: blue;
}
.disabled {
color: red !important;
}
.slide {
display: none;
opacity: 0;
position: relative;
left: 0px;
right: 0px;
}
.active {
display: block;
opacity: 1;
position: relative;
left: 0px;
right: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="showcase">
<img class="slide" src="https://picsum.photos/458/354" />
<img class="slide" style="left: 160px;" src="https://picsum.photos/458/354/?image=306" />
<img class="slide" style="left: 160px;" src="https://picsum.photos/458/354/?image=626" />
</div>
I have a series of images I want to transition from 0 opacity to 1 opacity when they come into the view port. I have the viewport check part done and the adding classes, however I would like them to be on an interval, so once the first 3 images come into the view port they appear 1, 2, 3 every .5seconds or so. Instead of all 3 at the same time.
here's a JS fiddle of how it works currently
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
reveal[i].classList.add("fade");
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
https://jsfiddle.net/u04sy7jb/
I've modified your code to add a transition-delay of an additional .5 seconds for each element after the first one, in each "group" that is revealed as you scroll. I left comments in the JavaScript so you can understand the changes.
Let me know if you have any questions!
Live demo:
reveal();
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
// start a new count each time user scrolls
count = 0;
for (var i = 0; i < reveal.length; i++) {
// also check here if the element has already been faded in
if (checkVisible(reveal[i]) && !reveal[i].classList.contains("fade")) {
// add .5 seconds to the transition for each
// additional element currently being revealed
reveal[i].style.transitionDelay = count * 500 + "ms";
reveal[i].classList.add("fade");
// increment count
count++;
}
}
}
};
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= -200);
}
.container {
width: 100%;
height: 1200px;
background-color: orange;
}
.reveal {
display: inline-block;
width: 32%;
margin: 0 auto;
height: 400px;
background-color: pink;
border: 1px solid black;
opacity: 0;
}
.fade {
opacity: 1;
transition: 1s;
}
<div class="container">
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
<div class="reveal"></div>
</div>
You could be able to stick your reveal[i].classList.add("fade"); inside of a setTimeout that executes as a function of your ith element so they show up how you're describing. Here is an example of adding short function to add the class and using it in a setTimeout to make this happen, although you could change it up to meet any additional needs.
function reveal() {
var reveal = document.querySelectorAll(".reveal");
window.onscroll = function() {
for(var i = 0; i < reveal.length; i++) {
if(checkVisible(reveal[i]) === true) {
addMyFadeClass(reveal[i], i)
}
}
}
};
function addMyFadeClass(element, i) {
setTimeout(function() {
element.classList.add("fade");
}, i * 500)
}
You can also use :nth-child CSS selectors without the need to change the JS:
.reveal:nth-child(3n+1).fade {
opacity: 1;
transition: 1s;
}
.reveal:nth-child(3n+2).fade {
opacity: 1;
transition: 1.5s;
}
.reveal:nth-child(3n).fade {
opacity: 1;
transition: 2s;
}
JSFiddle: https://jsfiddle.net/u04sy7jb/8/
I have a lot of objects in the dom tree, on which i'm adding new class, when they appeat in the viewport. But my code is very slow - it causes page to slow down...
I have such dom:
...
<span class="animation"></span>
...
and such jquery:
$.each($('.animation'), function() {
$(this).data('offset-top', Math.round($(this).offset().top));
});
var wH = $(window).height();
$(window).on('scroll resize load touchmove', function () {
var windowScroll = $(this).scrollTop();
$.each($('.animation'), function() {
if (windowScroll > (($(this).data('offset-top') + 200) - wH)){
$(this).addClass('isShownClass');
}
});
});
maybe i can somehow speed up my scroll checking and class applying?
You can use the Intersection Observer API to detect when an element appears in the viewport. Here is an example that adds a class to an element that is scrolled into the viewport and animates the background color from red to blue:
var targetElement = document.querySelector('.block');
var observer = new IntersectionObserver(onChange);
observer.observe(targetElement);
function onChange(entries) {
entries.forEach(function (entry) {
entry.target.classList.add('in-viewport');
observer.unobserve(entry.target);
});
}
body {
margin: 0;
height: 9000px;
}
.block {
width: 100%;
height: 200px;
margin-top: 2000px;
background-color: red;
transition: background 1s linear;
}
.block.in-viewport {
background-color: blue;
}
<div class="block">
</div>
The Intersection Observer API method works on chrome only, but the performance faster by 100%. The code below loads in 3/1000 second
$(document).ready(function () {
'use strict';
var startTime, endTime, sum;
startTime = Date.now();
var anim = $('.animation');
anim.each(function (index, elem) {
var animoffset = $(elem).offset().top;
$(window).on('scroll resize touchmove', function() {
var winScTop = $(this).scrollTop();
var windowHeight = $(window).height();
var winBottom = winScTop + windowHeight;
if ( winBottom >= animoffset ) {
$(elem).addClass('showed');
}
});
});
endTime = Date.now();
sum = endTime - startTime;
console.log('loaded in: '+sum);
});
html {
height: 100%;
}
body {
margin: 0;
height: 9000px;
}
.animation {
display: block;
width: 400px;
height: 400px;
background-color: blue;
margin-top: 1000px;
}
.animation:not(:first-of-type) {
margin-top: 10px;
}
.animation.showed {
background-color: yellow;
transition: all 3s ease
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<span class="animation"></span>
<span class="animation"></span>
<span class="animation"></span>
<span class="animation"></span>
IntersectionObserver has a limited support in browsers, but it's improving.
I'm basically lazy loading the polyfill only if the browser user is loading my website in doesn't support IntersectionObserver API with the code bellow.
loadPolyfills()
.then(() => /* Render React application now that your Polyfills are
ready */)
/**
* Do feature detection, to figure out which polyfills needs to be imported.
**/
function loadPolyfills() {
const polyfills = []
if (!supportsIntersectionObserver()) {
polyfills.push(import('intersection-observer'))
}
return Promise.all(polyfills)
}
function supportsIntersectionObserver() {
return (
'IntersectionObserver' in global &&
'IntersectionObserverEntry' in global &&
'intersectionRatio' in IntersectionObserverEntry.prototype
)
}
So basically I'd like to remove the class from 'header' after the user scrolls down a little and add another class to change it's look.
Trying to figure out the simplest way of doing this but I can't make it work.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll <= 500) {
$(".clearheader").removeClass("clearHeader").addClass("darkHeader");
}
}
CSS
.clearHeader{
height: 200px;
background-color: rgba(107,107,107,0.66);
position: fixed;
top:200;
width: 100%;
}
.darkHeader { height: 100px; }
.wrapper {
height:2000px;
}
HTML
<header class="clearHeader"> </header>
<div class="wrapper"> </div>
I'm sure I'm doing something very elementary wrong.
$(window).scroll(function() {
var scroll = $(window).scrollTop();
//>=, not <=
if (scroll >= 500) {
//clearHeader, not clearheader - caps H
$(".clearHeader").addClass("darkHeader");
}
}); //missing );
Fiddle
Also, by removing the clearHeader class, you're removing the position:fixed; from the element as well as the ability of re-selecting it through the $(".clearHeader") selector. I'd suggest not removing that class and adding a new CSS class on top of it for styling purposes.
And if you want to "reset" the class addition when the users scrolls back up:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$(".clearHeader").addClass("darkHeader");
} else {
$(".clearHeader").removeClass("darkHeader");
}
});
Fiddle
edit: Here's version caching the header selector - better performance as it won't query the DOM every time you scroll and you can safely remove/add any class to the header element without losing the reference:
$(function() {
//caches a jQuery object containing the header element
var header = $(".clearHeader");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
header.removeClass('clearHeader').addClass("darkHeader");
} else {
header.removeClass("darkHeader").addClass('clearHeader');
}
});
});
Fiddle
Pure javascript
Here's javascript-only example of handling classes during scrolling.
const navbar = document.getElementById('navbar')
// OnScroll event handler
const onScroll = () => {
// Get scroll value
const scroll = document.documentElement.scrollTop
// If scroll value is more than 0 - add class
if (scroll > 0) {
navbar.classList.add("scrolled");
} else {
navbar.classList.remove("scrolled")
}
}
// Use the function
window.addEventListener('scroll', onScroll)
#navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 60px;
background-color: #89d0f7;
box-shadow: 0px 5px 0px rgba(0, 0, 0, 0);
transition: box-shadow 500ms;
}
#navbar.scrolled {
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.25);
}
#content {
height: 3000px;
margin-top: 60px;
}
<!-- Optional - lodash library, used for throttlin onScroll handler-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<header id="navbar"></header>
<div id="content"></div>
Some improvements
You'd probably want to throttle handling scroll events, more so as handler logic gets more complex, in that case throttle from lodash lib comes in handy.
And if you're doing spa, keep in mind that you need to clear event listeners with removeEventListener once they're not needed (eg during onDestroy lifecycle hook of your component, like destroyed() for Vue, or maybe return function of useEffect hook for React).
Example throttling with lodash:
// Throttling onScroll handler at 100ms with lodash
const throttledOnScroll = _.throttle(onScroll, 100, {})
// Use
window.addEventListener('scroll', throttledOnScroll)
Add some transition effect to it if you like:
http://jsbin.com/boreme/17/edit?html,css,js
.clearHeader {
height:50px;
background:lightblue;
position:fixed;
top:0;
left:0;
width:100%;
-webkit-transition: background 2s; /* For Safari 3.1 to 6.0 */
transition: background 2s;
}
.clearHeader.darkHeader {
background:#000;
}
Its my code
jQuery(document).ready(function(e) {
var WindowHeight = jQuery(window).height();
var load_element = 0;
//position of element
var scroll_position = jQuery('.product-bottom').offset().top;
var screen_height = jQuery(window).height();
var activation_offset = 0;
var max_scroll_height = jQuery('body').height() + screen_height;
var scroll_activation_point = scroll_position - (screen_height * activation_offset);
jQuery(window).on('scroll', function(e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = y_scroll_pos > scroll_activation_point;
var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;
if (element_in_view || has_reached_bottom_of_page) {
jQuery('.product-bottom').addClass("change");
} else {
jQuery('.product-bottom').removeClass("change");
}
});
});
Its working Fine
Is this value intended? if (scroll <= 500) { ... This means it's happening from 0 to 500, and not 500 and greater. In the original post you said "after the user scrolls down a little"
In a similar case, I wanted to avoid always calling addClass or removeClass due to performance issues. I've split the scroll handler function into two individual functions, used according to the current state. I also added a debounce functionality according to this article: https://developers.google.com/web/fundamentals/performance/rendering/debounce-your-input-handlers
var $header = jQuery( ".clearHeader" );
var appScroll = appScrollForward;
var appScrollPosition = 0;
var scheduledAnimationFrame = false;
function appScrollReverse() {
scheduledAnimationFrame = false;
if ( appScrollPosition > 500 )
return;
$header.removeClass( "darkHeader" );
appScroll = appScrollForward;
}
function appScrollForward() {
scheduledAnimationFrame = false;
if ( appScrollPosition < 500 )
return;
$header.addClass( "darkHeader" );
appScroll = appScrollReverse;
}
function appScrollHandler() {
appScrollPosition = window.pageYOffset;
if ( scheduledAnimationFrame )
return;
scheduledAnimationFrame = true;
requestAnimationFrame( appScroll );
}
jQuery( window ).scroll( appScrollHandler );
Maybe someone finds this helpful.
For Android mobile $(window).scroll(function() and $(document).scroll(function() may or may not work. So instead use the following.
jQuery(document.body).scroll(function() {
var scroll = jQuery(document.body).scrollTop();
if (scroll >= 300) {
//alert();
header.addClass("sticky");
} else {
header.removeClass('sticky');
}
});
This code worked for me. Hope it will help you.
This is based of of #shahzad-yousuf's answer, but I only needed to compress a menu when the user scrolled down. I used the reference point of the top container rolling "off screen" to initiate the "squish"
<script type="text/javascript">
$(document).ready(function (e) {
//position of element
var scroll_position = $('div.mainContainer').offset().top;
var scroll_activation_point = scroll_position;
$(window).on('scroll', function (e) {
var y_scroll_pos = window.pageYOffset;
var element_in_view = scroll_activation_point < y_scroll_pos;
if (element_in_view) {
$('body').addClass("toolbar-compressed ");
$('div.toolbar').addClass("toolbar-compressed ");
} else {
$('body').removeClass("toolbar-compressed ");
$('div.toolbar').removeClass("toolbar-compressed ");
}
});
}); </script>