I am using the following to add and remove CSS classes based on the current scroll position:
$(function() {
var header = $(".grid-bar");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 400) {
header.addClass("move");
} else {
header.removeClass("move");
}
});
});
But I want to disable the addition and removal of the CSS classes on a screen size smaller than 800px.
I have tried wrapping the code in a resize function but after I do so, it stops responding at all:
$(window).resize(function(){
if ($(window).width() => 800){
var header = $(".grid-bar");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 400) {
header.addClass("move");
} else {
header.removeClass("move");
}
});
}
});
As others have mentioned, you have an improper operator for "greater than or equal to". The following is incorrect:
if ($(window).width() => 800) {
// ^^ this operator is wrong
if ($(window).width() >= 800) {
// ^^ it should be like this
Also, you need to bind and unbind the scroll handler whenever the screen size changes. You will need to keep track of whether or not the scroll handler is bound or not. Here is what that looks like:
const $window = $(window);
const $header = $(".grid-bar");
let isBound = false;
const scrollHandler = function() {
const scroll = $window.scrollTop();
if (scroll >= 400) {
header.addClass("move");
} else {
header.removeClass("move");
}
}
$(window).resize(function(){
if ($window.width() >= 800) {
if (!isBound) {
$window.on('scroll', scrollHandler);
isBound = true;
}
} else if (isBound) {
$window.off('scroll', scrollHandler);
isBound = false;
}
});
$window.trigger('resize');
Here is a fiddle: https://jsfiddle.net/1mru359x/5/
I am trying to add a css class to my sticky navbar when I scroll down on an interior page. I cannot get the event listener to console.log anything when scrolling down. What am I missing/doing incorrectly?
jQuery(document).ready(function($) {
// call resizeHeader() onload if not home page
if (top.location.pathname !== '/') {
window.onload = resizeHeader()
}
//resize header func
function resizeHeader() {
window.addEventListener('scroll', function(){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 1
nav = document.querySelector(".navbar")
if (distanceY > shrinkOn) {
console.log('scrolled')
nav.classList.add("smallerNav")
} else {
if (nav.classList.contains("smallerNav")) {
console.log('back to top')
nav.classList.remove("smallerNav")
}
}
})
}
})
I want to make a sticky banner, which becomes fixed at top when it is scrolled and unsticks at the end of the page. The document height is dependent upon images, that's why I use window load event. I have the following code:
function saleBanner() {
$(window).bind("load", function() {
// Make sale banner fixed-at-top
var s = $('.sale-container');
var pos = s.offset();
var maxTop = $(document).outerHeight() - 828 - s.outerHeight(); // 828 is the total height of site footer and sign up form
function fixedBanner() {
var currentTop = $(window).scrollTop();
if (currentTop >= pos.top && currentTop < maxTop) {
s.attr("style", ""); //kill absolute positioning
s.addClass('fixed-at-top'); //stick it
} else if (currentTop >= maxTop) {
s.removeClass('fixed-at-top'); //un-stick
s.css({bottom: 0}); //set sticker right above the footer
} else {
s.removeClass('fixed-at-top'); //top of page
}
}
$(window).scroll(fixedBanner);
});
}
saleBanner();
I want to make this function work on window resize as well. So I added the following code:
function resizeBanner() {
var viewportWidth = $(window).width();
if (viewportWidth > 767) {
saleBanner();
}
}
I have one more function resizeWindow for mobile menu, which I also need to work on window resize. So when I put this two functions together, they don't work (although they work on window resize separately):
$(window).resize(function(e) {
resizeWindow(e);
resizeBanner(e);
});
Where is my mistake? How can I make both functions work on window resize?
Update: Here is the whole code for resizeWindow function. It's rather long, but may be it would be helpful for the answer.
// Mobile menu
var MQM = 768;
var viewportWidth = $(window).width();
function navSlide() {
var headerHeight = $('.cd-header').height();
$(window).on('scroll', {previousTop: 0}, function () {
var currentTop = $(window).scrollTop();
//check if user is scrolling up
if (currentTop < this.previousTop ) {
//if scrolling up...
if (currentTop > 0 && $('.cd-header').hasClass('is-fixed')) {
$('.cd-header').addClass('is-visible');
} else {
$('.cd-header').removeClass('is-visible is-fixed');
}
} else {
//if scrolling down...
if(!$('.cd-header').hasClass('menu-is-open')) {
$('.cd-header').removeClass('is-visible');
}
if( currentTop > headerHeight && !$('.cd-header').hasClass('is-fixed')) $('.cd-header').addClass('is-fixed');
}
this.previousTop = currentTop;
});
}
// Primary navigation slide-in effect on load
if(viewportWidth < MQM) {
navSlide();
}
function addOverflow() {
$('html').addClass('overflow-hidden');
$('body').addClass('overflow-hidden');
}
function removeOverflow() {
$('html').removeClass('overflow-hidden');
$('body').removeClass('overflow-hidden');
}
function hideHeader() {
$('.cd-header').removeClass('is-fixed is-visible');
}
function hideMenu() {
$('.cd-header').removeClass('menu-is-open is-fixed is-visible');
$('.cd-menu-icon').removeClass('is-clicked');
}
function resizeWindow() {
var viewportWidth = $(window).width();
$(window).off('scroll'); // unbind scroll event
if (viewportWidth > 767) {
if ($('.cd-primary-nav').hasClass('is-visible')) {
if ($('.algolia__search-content').hasClass('algolia__search-content--active')) {
hideMenu();
$('.search-trigger').addClass('is-clicked');
$('.search-header').addClass('is-fixed');
} else {
hideMenu();
if (!$('.js-algolia__input').is(':focus')) {
$('.cd-primary-nav').removeClass('is-visible').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend',function(){
removeOverflow();
});
$('.search-trigger').removeClass('is-clicked');
$('.search-header').removeClass('is-fixed');
} else {
$('.search-trigger').addClass('is-clicked');
$('.search-header').addClass('is-fixed');
}
}
} else {
hideHeader();
}
} else {
navSlide();
if ($('.cd-primary-nav').hasClass('is-visible')) {
$('.cd-header').addClass('menu-is-open');
$('.cd-menu-icon').addClass('is-clicked');
$('.search-trigger').removeClass('is-clicked');
$('.search-header').removeClass('is-fixed');
}
}
}
Let me start of by saying I am not much a coder and pretty much fumble my way through using javascript libraries and jquery etc. I discovered and have been using classie.js to add classes to divs and elements on in my html when they are appear at a certain scroll distance on the page. so in my header i have a LOT of scripts to add and remove classes... for example:
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 100,
feature = document.querySelector("#welcomediv");
if (distanceY > shrinkOn) {
classie.remove(feature,"welcomewish");
} else {
classie.add(feature,"welcomewish");
}
});
}
window.onload = init();
</script>
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 300,
feature = document.querySelector("#slidetext");
if (distanceY > shrinkOn) {
classie.remove(feature,"welcomewish");
} else {
classie.add(feature,"welcomewish");
}
});
}
window.onload = init();
</script>
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 50, <?php /*?>130<?php */?>
feature = document.querySelector("#roundfeatures-panel");
if (distanceY > shrinkOn) {
classie.add(feature,"appearnow");
} else {
if (classie.has(feature,"appearnow")) {
classie.remove(feature,"appearnow");
}
}
});
}
window.onload = init();
</script>
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 140,
feature = document.querySelector("#roundfeatures-panel");
if (distanceY > shrinkOn) {
classie.add(feature,"expandnow");
} else {
if (classie.has(feature,"expandnow")) {
classie.remove(feature,"expandnow");
}
}
});
}
window.onload = init();
</script>
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 1000,
feature = document.querySelector("#futureevents-panel");
if (distanceY > shrinkOn) {
classie.add(feature,"appearnow");
} else {
if (classie.has(feature,"appearnow")) {
classie.remove(feature,"appearnow");
}
}
});
}
window.onload = init();
</script>
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 1400,
feature = document.querySelector("#viewallworkshops");
if (distanceY > shrinkOn) {
classie.add(feature,"slideinnow");
} else {
if (classie.has(feature,"slideinnow")) {
classie.remove(feature,"slideinnow");
}
}
});
}
window.onload = init();
</script>
<script>
function init() {
window.addEventListener('scroll', function(e){
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
shrinkOn = 2250,
feature = document.querySelector("#subscribe-panel");
if (distanceY > shrinkOn) {
classie.add(feature,"appearnow");
} else {
if (classie.has(feature,"appearnow")) {
classie.remove(feature,"appearnow");
}
}
});
}
window.onload = init();
</script>
(...and there are even more! and if i had my way, i'd probably add more still, because i like what i can do with the elements by adding and removing classes in this way. but if feels clunky and messy and is very hard to maintain.)
and then obviously my html elements on the page.
The problems with this are:
1) ugly scripts in my header.. is there a way i can condense the scripts in some way and retain their purpose?
2) Whenever i add new elements or take them out of the page, i have to manually change the number (shrinkOn) associated with each instance. This becomes a nightmare to be honest. It would be better if i could in some way say "when this element appears on the page" or "100px after this element appears on the page" rather than stating a strict number of pixels the page has scrolled. IS this possible with classie, or do i need to look at another option?
thanks in advance and i hope this question is appropriate.
Yes, that code can readily be parameterized, as all the blocks are doing the same thing.
Have an array of updates to do:
var scrollUpdates = [];
A function to add each update (this is purely for convenience, you could directly add them above):
addScrollUpdate(featureSelector, shrinkOn, className) {
scrollUpdates.push({
featureSelector: featureSelector,
shrinkOn: shrinkOn,
className: className
});
}
One handler handles them:
window.addEventListener('scroll', function(e){
scrollUpdates.forEach(function(update) {
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
feature = document.querySelector(update.featureSelector);
if (distanceY > update.shrinkOn) {
classie.add(feature, update.className);
} else {
if (classie.has(feature, update.className)) {
classie.remove(feature, update.className);
}
}
});
});
And you add each one like this:
addScrollUpdate("#welcomediv", 100, "welcomewish");
Putting it all together in one window load handler:
window.onload = function() {
var scrollUpdates = [];
addScrollUpdate(featureSelector, shrinkOn, className) {
scrollUpdates.push({
featureSelector: featureSelector,
shrinkOn: shrinkOn,
className: className
});
}
window.addEventListener('scroll', function(e){
scrollUpdates.forEach(function(update) {
var distanceY = window.pageYOffset || document.documentElement.scrollTop,
feature = document.querySelector(update.featureSelector);
if (distanceY > update.shrinkOn) {
classie.add(feature, update.className);
} else {
if (classie.has(feature, update.className)) {
classie.remove(feature, update.className);
}
}
});
});
addScrollUpdate("#welcomediv", 100, "welcomewish");
addScrollUpdate("#slidetext", 300, "welcomewish");
// ...and so on...
};
However, I wouldn't use the window load event for this, that happens very late in the page load process. Instead, I'd put the script tag at the end of the HTML, just before the closing </body> tag, and run it immediately in an inline-invoked function expression:
(function() {
// the code here
})();
Side note: I don't know Classie, but you probably don't need the has test before calling remove.
The opacity of my nav bar changes as I scroll, and the rate at which it changes is based on the width of the window. Once the page is loaded, I tried changing the width but the opacity change rate is still the same. Is there a way for the opacity change rate parameters to change automatically without refreshing the page?
if ($(window).width() > 1060) {
fadenumber = 500;
}
else if ($(window).width() > 800){
fadenumber = 600;
}
else if ($(window).width() > 600){
fadenumber = 400;
}
else {
fadenumber = 200;
}
$(document).on('scroll', function () {
$('.navbar').css('opacity', ($(document).scrollTop() / fadenumber));
var fadeStart=0 ,fadeUntil=fadenumber;
var offset = $(document).scrollTop(),opacity=0
;
if( offset<=fadeStart ){
opacity=1;
}else if( offset<=fadeUntil ){
opacity=1-offset/fadeUntil;
}
$('.icon').css('opacity',opacity).html(opacity);
});
Thank you
There's an event for when the window or a DOM object gets resized.
So you can create an event listener that does this.
Here's how to get the size and add a listener. (Also here's a more in depth jsfiddle I wrote for this: http://jsfiddle.net/snlacks/65mL7btd/)
var outputDiv = $('#outputjq');
function callback(){
outputDiv.html(window.innerWidth);
}
$(window).on('resize', callback);
callback();
if you want to change the rate, you can augment the rate inside of the callback.
function callback2(){
if ($(window).width() > 1060) {
fadenumber = 500;
}
else if ($(window).width() > 800){
fadenumber = 600;
}
else if ($(window).width() > 600){
fadenumber = 400;
}
else {
fadenumber = 200;
}
}
var fadenumber;
$(window).on('resize', callback2);
callback2();
var onScroll;
$(document).on('scroll', onScroll = function () {
$('.navbar').css('opacity', ($(document).scrollTop() / fadenumber));
var fadeStart=0 ,fadeUntil=fadenumber;
var offset = $(document).scrollTop(),opacity=0
;
if( offset<=fadeStart ){
opacity=1;
}else if( offset<=fadeUntil ){
opacity=1-offset/fadeUntil;
}
$('.icon').css('opacity',opacity).html(opacity);
});
$(document).on('resize', function () {
if ($(window).width() > 1060) {
fadenumber = 500;
}
else if ($(window).width() > 800){
fadenumber = 600;
}
else if ($(window).width() > 600){
fadenumber = 400;
}
else {
fadenumber = 200;
}
onScroll();
});
[You should make variables global first]
Interpreter will check the width after resize.
You can copypaste your resize function code (without onScroll();) into scroll function, so it will check the width also when the document is being scrolled.
EDIT
You can put () after onResize function to make sure, variables will be set when document is ready (and you can put all in $(document).ready()), like this:
$(document).ready(function(){
var onResize;
$(document).on('resize', onResize = function () {
if ($(window).width() > 1060) {
fadenumber = 500;
}
else if ($(window).width() > 800){
fadenumber = 600;
}
else if ($(window).width() > 600){
fadenumber = 400;
}
else {
fadenumber = 200;
}
}()); // () to launch function right after it's declared
});
if ($(window).width() > 1060) {
fadenumber = 500;
}
else if ($(window).width() > 800){
fadenumber = 600;
}
else if ($(window).width() > 600){
fadenumber = 400;
}
else {
fadenumber = 200;
}
changeOpacityRate();
$(document).on('scroll', function ()
{
changeOpacityRate();
});
function changeOpacityRate()
{
$('.navbar').css('opacity', ($(document).scrollTop() / fadenumber));
var fadeStart=0 ,fadeUntil=fadenumber;
var offset = $(document).scrollTop(),opacity=0 ;
if( offset<=fadeStart )
{
opacity=1;
}
else if( offset<=fadeUntil )
{
opacity=1-offset/fadeUntil;
}
$('.icon').css('opacity',opacity).html(opacity);
}