I am trying to build an animated sidebar that slides in and out when you click the button. This was quite easy to achieve however I ran in to a problem when making the sidebar 'more' responsive. Basically, I wanted the sidebar to be 200px wide when the width is less than 500 and 300px wide otherwise. This was done in a media query. The problem I've run into is that when you resize the window the sidebar goes out of position if you have already run the function before resizing.
This problem can occur for example if a user rotates their mobile screen whilst using the sidebar and so I feel it's best to try and fix it.
Here is the jQuery:
function sidebar(){
var menuWidth = $('#menu').width();
if($('#menu-link').hasClass('hidden')){
$('#menu-link').removeClass('hidden');
$('.push').animate({right: "-=" + menuWidth});
}else{
$('#menu-link').addClass('hidden');
$('.push').animate({right: "+=" + menuWidth});
}
};
$('body').on('click', '#menu-link', sidebar);
The sidebar changes to 200px <500 and is otherwise 300px. What is the best way to code this or is it better to keep it simple by just always making the sidebar 200px even though it's not as aesthetically pleasing at larger resolutions.
Here is a link to a JSFiddle of my code
https://jsfiddle.net/fqcydqu7/
Edit: Sorry, to explain the actual problem clearly - Before you resize, this code runs fine and is perfect. However, if you run this code (ie. open and close the sidebar) and then resize the window so the media query is active you will see that the sidebar is out of position by 100px. The opposite will happen if you reverse the order.
Okay guys I came up with a solution for my problem.
Basically, I remove the media query from CSS and set the div to always be 300px.
The jquery uses a variable that is updated whenever the window is resized to judge how much to slide the menu. (200px or 300px).
here is the code:
// variable is set to 0 by default
var menuWidth = 0;
//call to function that will set this variable
setWidth();
function setWidth(){
if(windowSize <= 800){ //if its less than 800px wide, set the variable to 200px (the menu is still 300px)
menuWidth = "200px";
}else{
menuWidth = "300px"; //otherwise set the variable to 300px
}
}
$(window).resize(function(){ //when a user resizes the window, run the setWidth function to readjust the variable
setWidth(); //this re-runs setWidth
//the following closes the menu if it's already open to avoid glitches
if($('#menu-link').hasClass('hidden')){
$('#menu-link').removeClass('hidden');
$('.push').animate({right: "-=" + menuWidth});
}
});
//nav slide
function sidebar(){
if($('#menu-link').hasClass('showing')){ //checks to see if the nav is showing or not
$('#menu-link').removeClass('showing'); //remove the showing tag
$('.push').animate({right: "-=" + menuWidth}); //closes the nav
}else{ //if the nav doesnt have showing tag it must be hidden
$('#menu-link').addClass('showing'); //add the showing tag
$('.push').animate({right: "+=" + menuWidth}); //open the nav
}
};
With this code, the menu will only slide out by 200px when the window is less than 800px wide and 300px if it's wider. The div will always be in the correct position even if the user rotates the mobile or changes the window width.
Related
Bit of a jquery / javascript noob question here. I have a subnav element that I am sticking to the bottom of my primary nav once someone hits a certain scroll point. To do that, I'm offsetting the subnav element by the height of the main nav element, as shown below.
$(function() {
$('.sticky-nav').stickybits({
useStickyClasses: true,
stickyBitStickyOffset: $('.navbar-fixed-top').outerHeight(),
});
});
The problem that I'm running into is '.navbar-fixed-top' has a different height at mobile / tablet and desktop sizes (the height changes at 992px) and the offset gets messed up if someone resizes the screen (i.e., if they start at desktop, and then resize to mobile / tablet, there's too much space above the subnav because the main nav was taller in desktop).
My question is, how can I update the code above to dynamically update the outerHeight when the height of the .navbar-fixed-top element changes?
I tried the code below, inspired by the answer to this question: Resize element width on window resize jquery, but it's not working
$(function() {
var topNavHeight = $('.navbar-fixed-top').outerHeight();
$(window).on('resize', function(event) {
var topNavHeight = $('.navbar-fixed-top').outerHeight();
});
$('.sticky-nav').stickybits({
useStickyClasses: true,
stickyBitStickyOffset: topNavHeight,
});
});
Thanks!
I think this will work:
$(function() {
let stickything;
function set_sticky() {
if (stickything) {
stickything.cleanup();
}
stickything = $('.sticky-nav').stickybits({
useStickyClasses: true,
stickyBitStickyOffset: $('.navbar-fixed-top').outerHeight(),
});
}
$(window).on('resize', set_sticky);
set_sticky();
});
Just changing a variable isn't enough, you have to tell stickbits to update. There doesn't seem be a way to update the offset so this just reinitializes it.
I have a .navbar.navbar-inverse.navbar-fixed-top navigation bar that always stays on top of the page. I have given the body a padding of 70 px and this works well with it.
The problem is if I resize the browser, then the nav-bar is no longer nice and neat with a fixed height. Instead it wraps all the items in it, the height of the nav bar becomes more than 70 px and covers parts of the page.
To fix this, I tried using JQuery to check the height of the nav bar and give body more padding, I put this in document.ready()
if ($(".navbar.navbar-inverse.navbar-fixed-top").height() > 100) {
$("html, body").css("padding-top", "150px");
}
However, this solution does not work because the browser is not reloaded when its size shrinks so therefore this check does not happen dynamically. So how do I fix this?
You can use the window resize event listener here. Something like this:
$( window ).resize(function() {
if ($(".navbar.navbar-inverse.navbar-fixed-top").height() > 100) {
$("html, body").css("padding-top", "150px");
}
});
Additionally you could also go the Bootstrap way and collapse and expand the Navbar into a button, depending on screen resolution. The above approach is slightly less than ideal IMO
I use Jquery to get the height of the devices displaying a website, to make sure that my homepage has a height of 100%, and when scrolled thru, header menu will go fixed to top.
For that, I measure Window InnerHeight with a functiun, which is called on document ready, and window resize events (to keep the design clean when user changes portrait / landscpae mode on mobile, or resizes his window on desktop).
Problem on mobile : the adress bar on android is displayed on page load, and hides on scroll down, then reappears on scroll up. This makes some page elements change sizes on evey opportunity and moves contents in the page. Not pleasant for the user.
function setHeight() {
windowHeight = $(window).innerHeight();
$('.home-intro').css('min-height', windowHeight);
}
$( window ).resize(function() {
setHeight();
});
Is there a way to get the window size, not affected by the adress bar being displayed or not ?
I know this answer is a year late, but I've struggled with this issue as well. I've found that using "window.document.documentElement.clientHeight" instead of "$(window).innerHeight();" makes it so the when the address bar disappears your min-height targeted elements won't resize again to fill the extra 50px or so.
Here's what I'm using on my project:
function adjustBackgrounds() {
windowHeight = window.document.documentElement.clientHeight;
$('#section-01-home').css('min-height', windowHeight);
}
// Triggers Sizing on Load (783 = 800px accounting for 17px of scrollbar)
if ($(window).width() <= 783) {
adjustBackgrounds();
} else {
}
// Triggers Sizing on Browser Resize (783 = 800px accounting for 17px of scrollbar)
$(window).resize(function() {
if ($(window).width() <= 783) {
adjustBackgrounds();
} else {
}
});
I am building a template where there are large navigation buttons at the very top that, when clicked, make a corresponding page (an absolutely positioned DIV) slide out from underneath the button and fill the whole page via CSS transitions.
I have a series of commands in a window resize function that keep everything in place/the right size if the window changes size. It is all working fine, except for a small issue where when the page is "out", if the browser window gets resized vertically, the CSS height transition triggers as opposed to the DIV snapping to the new height instantly (the DIV is 100% width and a dynamically calculated height the makes it fill the screen below the navigation buttons exactly). My solution to that was to add a line of code that would change the transition property to not include height BEFORE updating the height, then change it back immediately after. It seems to do nothing at all though. My code:
window.addEventListener('resize', function(event){
bottomLoc = findBottom.getBoundingClientRect();
if (pageOut1 == false) {
pageLoc1 = pageButton1.getBoundingClientRect(); //redefine location variable
document.getElementById("page1").style.top = pageLoc1.top + 70 + "px"; //update closed page position
document.getElementById("page1").style.left = pageLoc1.left + "px"; //update closed page position
} else if (pageOut1 == true) {
document.getElementById("page1").style.transition = "width 0.5s, left 0.5s"; //turn off height transition
document.getElementById("page1").style.height = bottomLoc.bottom - 70 + "px"; //update height
document.getElementById("page1").style.transition = "height 0.5s, width 0.5s, left 0.5s"; //turn height transition back on
}
});
The part that doesn't seem to be working is in the "else if" statement. Even though I take out the "height 0.5s" before the height update happens, it still does the transition. This is not exactly a huge, website breaking problem, but it does cause a scroll bar to randomly appear and disappear when resized smaller, which looks bad.
Hopefully someone can help me understand why this is not working, as this would help with a lot of other templates I have that require dynamic repositioning of absolutely positioned elements. Thanks!
This question sort of relates to this one: Append div to body when URL hash # changes
I'm using Curtain.js and currently I have a fixed div that pops up when the hash changes. I.E the div fades in when the user scrolls down the page to different panels. I don't want this div to be visible on the first panel.
The problem I now have is that when the visitor scrolls back up the page to the top the fixed div is still visible. I.e. appearing on top of the first panel. I would like to fade that div out as soon as it hits the bottom of that first panel. The other issue is that the panel's height adjusts to the height of the browser window (fluid/responsive layout) ruling out any fixed pixel JS solutions, which is what my code is based on:
// fade in/fade out banner titles
$(window).trigger('scroll');
var divs = $('.nav-wrap');
$(window).scroll(function(){
if($(window).scrollTop() < 550){
divs.fadeOut("slow");
} else {
divs.fadeIn("slow");
}
});
Anyone have any suggestions??
you can use window.height() which returns the height of the browser's viewport:
var vp = $(window).height(); // height of the browser's viewport
var divs = $('.nav-wrap');
$(window).scroll(function(){
if($(window).scrollTop() < vp){
divs.fadeOut("slow");
} else {
divs.fadeIn("slow");
}
});