I created a JQuery script, which fade in a sidebar, when scrolling down for 500px. This is working without any errors. However, I tried to wrap it in another function, which checks the media size. The fade in should only work, if the media size is greater than 1024. It does not work and I don't get any error in the console. Can you pls help me?
jQuery(function($) {
function checkPosition() {
if (window.matchMedia('(min-width: 767px)').matches) {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$("body").addClass("right_side_menu_opened");
$(".side_menu").addClass("nav-fade");
}
else {
$("body").removeClass("right_side_menu_opened");
$(".side_menu").removeClass("nav-fade");
}
});
} else {
}
}
});
You have wrapped the whole JS inside a function which never gets called.
You should
remove the function declaration (function checkPosition())
or call the function (checkPosition())
Removing the declaration:
jQuery(function($) {
if (window.matchMedia('(min-width: 767px)').matches) {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$("body").addClass("right_side_menu_opened");
$(".side_menu").addClass("nav-fade");
}
else {
$("body").removeClass("right_side_menu_opened");
$(".side_menu").removeClass("nav-fade");
}
});
} else {
}
});
Calling the function:
jQuery(function($) {
function checkPosition() {
if (window.matchMedia('(min-width: 767px)').matches) {
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 500) {
$("body").addClass("right_side_menu_opened");
$(".side_menu").addClass("nav-fade");
}
else {
$("body").removeClass("right_side_menu_opened");
$(".side_menu").removeClass("nav-fade");
}
});
} else {
}
}
checkPosition();
});
Note: if you want to check viewport size, you could use $(window).width(); to get the width of viewport.
Related
Hey stackoverflow community!
I have a small issue regarding this JS logic to add a class name to my body tag to hide the side navigation menu upon window resizing. Let me try to explain the issue as clearly as I can. Currently I'm using a UI template by creativetime called Argon. The page when loaded on a full scaled width looks like this:
When I resize the window after the page has loaded it looks like this:
But when I refresh the page, the side navigation is no longer there as how it should be, which is like this:
After refreshing the page, resizing the window thereafter makes the side navigation to hide as it should. The sidenav just doesn't go hidden on first page load for some reason.
The JS for this is as follows:
var Layout = (function() {
function pinSidenav() {
$('.sidenav-toggler').addClass('active');
$('.sidenav-toggler').data('action', 'sidenav-unpin');
$('body').removeClass('g-sidenav-hidden').addClass('g-sidenav-show g-sidenav-pinned');
$('body').append('<div class="backdrop d-xl-none" data-action="sidenav-unpin" data-target='+$('#sidenav-main').data('target')+' />');
// Store the sidenav state in a cookie session
Cookies.set('sidenav-state', 'pinned');
}
function unpinSidenav() {
$('.sidenav-toggler').removeClass('active');
$('.sidenav-toggler').data('action', 'sidenav-pin');
$('body').removeClass('g-sidenav-pinned').addClass('g-sidenav-hidden');
$('body').find('.backdrop').remove();
// Store the sidenav state in a cookie session
Cookies.set('sidenav-state', 'unpinned');
}
// Set sidenav state from cookie
var $sidenavState = Cookies.get('sidenav-state') ? Cookies.get('sidenav-state') : 'pinned';
if($(window).width() > 1200) {
if($sidenavState == 'pinned') {
pinSidenav()
}
if(Cookies.get('sidenav-state') == 'unpinned') {
unpinSidenav()
}
$(window).resize(function() {
if( $('body').hasClass('g-sidenav-show') && !$('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-show').addClass('g-sidenav-hidden');
}
})
}
if($(window).width() < 1200){
$('body').removeClass('g-sidenav-hide').addClass('g-sidenav-hidden');
$('body').removeClass('g-sidenav-show');
$(window).resize(function() {
if( $('body').hasClass('g-sidenav-show') && !$('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-show').addClass('g-sidenav-hidden');
}
})
}
$("body").on("click", "[data-action]", function(e) {
e.preventDefault();
var $this = $(this);
var action = $this.data('action');
var target = $this.data('target');
// Manage actions
switch (action) {
case 'search-show':
target = $this.data('target');
$('body').removeClass('g-navbar-search-show').addClass('g-navbar-search-showing');
setTimeout(function() {
$('body').removeClass('g-navbar-search-showing').addClass('g-navbar-search-show');
}, 150);
setTimeout(function() {
$('body').addClass('g-navbar-search-shown');
}, 300)
break;
case 'search-close':
target = $this.data('target');
$('body').removeClass('g-navbar-search-shown');
setTimeout(function() {
$('body').removeClass('g-navbar-search-show').addClass('g-navbar-search-hiding');
}, 150);
setTimeout(function() {
$('body').removeClass('g-navbar-search-hiding').addClass('g-navbar-search-hidden');
}, 300);
setTimeout(function() {
$('body').removeClass('g-navbar-search-hidden');
}, 500);
break;
}
})
// Add sidenav modifier classes on mouse events
$('.sidenav').on('mouseenter', function() {
if(! $('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-hide').removeClass('g-sidenav-hidden').addClass('g-sidenav-show');
}
})
$('.sidenav').on('mouseleave', function() {
if(! $('body').hasClass('g-sidenav-pinned')) {
$('body').removeClass('g-sidenav-show').addClass('g-sidenav-hide');
setTimeout(function() {
$('body').removeClass('g-sidenav-hide').addClass('g-sidenav-hidden');
}, 300);
}
})
// Make the body full screen size if it has not enough content inside
$(window).on('load resize', function() {
if($('body').height() < 800) {
$('body').css('min-height', '100vh');
$('#footer-main').addClass('footer-auto-bottom')
}
})
})();
Working JS Fiddle: https://jsfiddle.net/Vaulient/kthw39gs/6/
I have a class of .header-is-active that is applied to the <body> tag when a user scrolls.
I would like an animation to be triggered when the class is added and then the animation to run in reverse when the class is removed.
Everything happens as expected except for the animation. I'm using jQuery and Greensock to make everything happen.
Here's what I currently have:
$(function() {
var body = $('body');
var trigger = $('.trigger');
var tween = TweenMax.to(trigger, 0.5, {css:{height: "100vh"},});
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
body.addClass('header-is-active');
tween();
} else {
body.removeClass('header-is-active');
}
});
});
The issue I have is the tweened value height: 100vh is being applied regardless with .header-is-active or not. Is there something missing?
At the end of your $(window).scroll() function, give this a shot:
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 50) {
body.addClass('header-is-active');
tween();
} else {
body.removeClass('header-is-active');
}
// jQuery way
if(body.hasClass('header-is-active')) {
// Run animation
} else {
// Run reverse animation
}
// Non-jQuery way (just for reference)
var body = document.body;
if(body.classList.contains('header-is-active') {
// Run animation
} else {
// Run reverse animation
}
});
If it doesn't work, since it's running async, you can add a setTimeout() to the above so it's called after your function. It should look something like this
setTimeout(function() {
if(body.hasClass('header-is-active')) {
// run animation
} else {
// run reverse
}
}, 0);
I have a codepen here -
http://codepen.io/ashconnolly/pen/EjMbQp
function homepanelHeights() {
$('.img_panel').each(function() {
if (currentWidth < 700) {
var panelcopyHeight = $(this).find('.panel_copy_inner').outerHeight();
console.log(panelcopyHeight);
$(this).css('height', panelcopyHeight);
} else {
// remove inline style
$(this).css("height", "");
}
});
}
$(document).ready(function() {
$('.img_panel').each(homepanelHeights);
});
$(window).resize(function() {
$('.img_panel').each(homepanelHeights);
});
I want to apply a function to each element with .img_panel.
Do you know why the each function call is not working?
I assume its because of the arguments I'm passing, but can not work it out.
it works if I simply repeat the function in the doc.ready and window.resize, but that is a bit dirty..
Hope you can help!
You just need to call homepanelHeights(); Because when you using $('.img_panel').each(...) in homepanelHeights, you're already iterating through it, $('.img_panel').each(homepanelHeights);, combine with the logic inside the function, can be considered as:
// This is the outer
$('.img_panel').each(function() {
// This is inside your homepanelHeights
$('.img_panel').each(function() {
// Do something.
});
});
So you can see that that the logic n*n times.
currentWidth is undefined in your codepen. Added a fake to show.
function homepanelHeights(){
$('.img_panel').each(function (){
// VVVV Make the `currentWidth` get value here, it needs the current width
// when window content is fully loaded, or resized.
var currentWidth = $(window).width();
if (currentWidth < 700){
var panelcopyHeight = $(this).find('.panel_copy_inner').outerHeight();
console.log(panelcopyHeight);
$(this).css('height', panelcopyHeight);
} else {
// remove inline style
$(this).css("height", "");
}
});
}
// As A. Wolff said :
// $(window).on('load resize', homepanelHeights); Can simplify the code.
$(document).ready(function() {
homepanelHeights();
});
$(window).resize(function() {
homepanelHeights();
});
.img_panel {background:salmon; width:200px; height:300px; margin-bottom:10px; display:table;
.panel_copy_inner {height:100%; display: table-cell; vertical-align:middle; text-align: center;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="img_panel">
<div class="panel_copy_inner">Test</div>
</div>
<div class="img_panel">
<div class="panel_copy_inner">Test</div>
</div>
<div class="img_panel">
<div class="panel_copy_inner">Test</div>
</div>
If you want to use the function homepanelHeights as $('.img_panel').each(homepanelHeights);
You can rewrite the logic to:
var currentWidth;
// You need to either define a `currentWidth` here by something.
function homepanelHeights(){
if (currentWidth < 700){
var panelcopyHeight = $(this).find('.panel_copy_inner').outerHeight();
console.log(panelcopyHeight);
$(this).css('height', panelcopyHeight);
} else {
// remove inline style
$(this).css("height", "");
}
}
// As A. Wolff said :
$(window).on('load resize', function() {
// Update the width here. So you don't need to get currentWidth
// each time you operate on an element.
currentWidth = $(window).width();
$('.img_panel').each(homepanelHeights);
});
Demo is on jsfiddle.
Here i have modified the code to achieve the functionality for each element.
Please see the code below.
homepanelHeights=function(key, val) {
var currentWidth = $(window).width();
console.log(currentWidth);
if (currentWidth < 700) {
var panelcopyHeight = $(this).find('.panel_copy_inner').outerHeight();
//console.log(panelcopyHeight);
$(this).css('height', panelcopyHeight);
} else {
// remove inline style
$(this).css("height", "");
}
}
/**/
$(document).ready(function() {
$('.img_panel').each(homepanelHeights);
});
$(window).resize(function() {
$('.img_panel').each(homepanelHeights);
});
function homepanelHeights(){
//This will iterate through all element having img_panel class
$('.img_panel').each(function(){
//get current div's height
var currentWidth = //assign some value here, it is undefined in your current code;
// your logic implemetation
if (currentWidth < 700)
{
var panelcopyHeight = $(this).find('.panel_copy_inner').outerHeight();
console.log(panelcopyHeight);
$(this).css('height', panelcopyHeight);
}
else {
$(this).css("height", "");
}
})
}
// on window load && resize
$(window).on('load resize',function() {
homepanelHeights();
});
//Or instead of window on load you can also use document's ready event
$(document).ready(function() {
homepanelHeights();
});
document.ready runs when the DOM is ready, e.g. all elements are there to be found/used, but not necessarily all the content.
window.onload fires later (or at the same time in the worst/failing cases) when images and such are loaded. So, if you're using image dimensions for example, you often want to use this instead
I've got a script that changes the background when an anchor touches the top of the page.
https://jsfiddle.net/u9pexc4v/
var targetOffset = $("#anchor-point").offset().top;
var $w = $(window).scroll(function () {
if ($w.scrollTop() > targetOffset) {
$(".projectTitle").addClass("topper");
} else {
$(".projectTitle").removeClass("topper");
}
});
However, it does not work when it's inside the modal window.
https://jsfiddle.net/qhrmtass/
I believe you need to attach the scroll event to the element that's scrolling.
$('.remodal').scroll(function () {
console.log('Scrolling...');
if ($('.remodal').scrollTop() > targetOffset) {
$(".projectTitle").addClass("topper");
} else {
$(".projectTitle").removeClass("topper");
}
});
Updated fiddle
im trying to get my bootstrap dropdowns to be open by default at screens at or smaller than 600px (mobile).
this seems to get it to try but it looks like something overrides it and closes it again:
<script type="text/javascript">
$(window).load(function () {
var width = $(window).width();
if (width >= 0 && width <= 600) {
$('#openBrowseMobile').addClass('open');
}
else {
$('#openBrowseMobile').removeClass('open');
}
})
.load();
</script>
any ideas on how to make this work?
I can get it to work on resize with this, but i need it to work on pageload/doc ready..
<script type="text/javascript">
$(window).resize(function () {
console.log('resize called');
var width = $(window).width();
if (width >= 0 && width <= 600) {
$('#openBrowseMobile').addClass('open');
}
else {
$('#openBrowseMobile').removeClass('open');
}
})
.resize();
</script>
You can move them into the same handler, by triggering on multiple events.
<script type="text/javascript">
$(window).on('load resize',function () {
console.log('resize called');
var width = $(window).width();
if (width >= 0 && width <= 600) {
$('#openBrowseMobile').addClass('open');
}
else {
$('#openBrowseMobile').removeClass('open');
}
});
</script>
I had the same issue,
here is another approach using jquery that doesn't involve messing with less code or css.
I just added a trigger to open the dropdown menu inmediately after menu is opened.
There's a timeout that waits until the main menu is opened.
(there will be 100 ms delay until dropdown is opened), If you like it to don't wait I guess that can be changed in less.
$(".navbar-toggle").click(function() {
if (window.matchMedia("(max-width: 768px)").matches) {
// on mobile, dropdown default opened:
setTimeout(function() {
$(".dropdown-toggle").click();
}, 100);
}
});