Jquery Nav Detecting Screen Sizes - javascript

I'm encountering a slight problem with my navigation. When I resize my browser to check the mobile menu and click the 'header' a couple times for the dropdown menu, then resize my page back to a tablet or desktop size, my navigation disappears. This problem resolves itself if I delete this segment of code:
if ( width == GetWidth() ) {
return;
}
width = GetWidth();
But I need this section of code so the navigation does not disappear when I scroll down on mobile.
var screensize = document.documentElement.clientWidth;
$(document).ready(function(){
var isMobile = window.matchMedia("only screen and (max-width: 600px)");
if (isMobile.matches) {
$('#mobile_active li a').on('click',function() {
$('.Back a').text('Back');
$('#mobile_active li ul li a').slideToggle(150);
e.preventDefault();
});
}
$(window).resize(function(){
if ( width == GetWidth() ) {
return;
}
width = GetWidth();
if( $(window).width() < 600) {
$('#mobile_active').hide();
} else {
$('#mobile_active').show();
}
});
$('header').on('click', function() {
$('#mobile_active').slideToggle(500);
e.preventDefault();
});
});
Any advice or input would be of great help. Thank you.

I agree you should use media queries and javascript for this type of thing, but I think I have found the cause of your issue.
When in mobile mode you have a click event attached to your <header> with a slideToggle. This slideToggle sets an inline style of display:block; or display:none; on the #mobile_active after it animates; depending on wether its closed or opened. When you resize to desktop size the #mobile_active still has an inline style of display:none; which is why you can not see it any more.
It looks like you may have code to correct this on your resize event:
if( $(window).width() < 600) {
$('#mobile_active').hide();
} else {
$('#mobile_active').show();
}
I think it just needs placed before this code block:
if ( width == GetWidth() ) {
return;
}
width = GetWidth();
Which may be why when you remove it, it works

Related

sidebar fixed only on screen size > 992px and above still not working properly

I want to create a sidebar whose position is fixed only when the screen size is 992px and above. I've made the sidebar position fixed, but when the screen is 991 down the position is still fixed. I want when the screen size is 991px and down the position is relative.
but when i refresh the page, it works normally. Is there a strange behavior with the use of this javascript code?
Anyone can help me to solved this problem?
if ($(window).width() >= 992) {
var theLoc = 150;
var links = $('.d-submenu');
var content = $('.main-content');
$(window).scroll(function () {
console.log('scroll');
if (theLoc >= $(window).scrollTop()) {
if (links.hasClass('fixed')) {
links.removeClass('fixed');
content.removeClass('fixed');
}
} else {
if (!links.hasClass('fixed')) {
links.addClass('fixed');
content.addClass('fixed');
}
}
});
}
You need to add a event listener for page resize something like
$(window).on('resize', function(){
var win = $(this); //this = window
if (win.width() >= 992) { /* ... */ }
});
EDIT FOR FULL SOLUTION
function screenResize() {
if ($(window).width() >= 992) {
var theLoc = 150;
var links = $('.d-submenu');
var content = $('.main-content');
} REST OF YOUR CODE
// On page load call
screenResize();
// And recheck when window gets resized.
$(window).on('resize',function(){
screenResize();
});

How to rerender or refresh or get js code to work properly for different resolutions?

I had seen that there is similar questions, but couldn't find proper answer for my problem.
Code:
function test() {
var scroll = parseInt($('.sidebar').css('height'));
if (window.matchMedia('(min-width: 769px)').matches) {
$(window).scroll(function() {
if ( $(window).scrollTop() > scroll ) {
$('.element').addClass('fixed');
} else {
$('.element').removeClass('fixed');
}
});
} }
window.onload = function() { test(); }
As you can see this code (adding and removing simple class when scrolling) should work for resolutions bigger than 769px (width) and it works - when test this on mobile device with resolution 1024x768 at 1024px width - works fine, BUT the problem is when you rotate the device - now the width is 768px, but "fixed" class is again added and breaks layout. You have to refresh the whole page so the code to work properly.
I can make the whole page to reload on resize but this is slow and irritating for users.
Tried to set function and on resize but it doesn't work.
$(window).resize(function() {
clearTimeout(window.resizedFinished);
window.resizedFinished = setTimeout(function(){
test();
}, 10);
});
Tried to add "else" for the if (window.matchMedia('(min-width: 769px)').matches) but it doesn't work too.
Is there a way to fix this?
The scroll-event is added onload, and not removed on the resize-event. So the event-function is still being triggered. How about:
$(window).on('scroll resize', function() { // On both scroll and resize, call
if (
window.matchMedia('(min-width: 769px)').matches
&& $(window).scrollTop() > scroll
) {
$('.element').addClass('fixed');
} else {
$('.element').removeClass('fixed');
}
});

How can I show a fixed after scroll but hide it if the screen is smaller than

I am trying to add a fixed div on the top after the user scrolls down but how can I hide that same div if the resized window is smaller than 768px and show it back again if the window is bigger than 769px?
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 400) {
$('.js-quick-navbar').show();
} else if($(this).width() < 768) {
$('.js-quick-navbar').hide();
}
});
jsFiddle
If it's just a matter of showing or hiding a div based on the window width, then you could use Media queries.
#media (max-width:768px){
.quick-navbar {
display:none;
}
}
}
http://jsfiddle.net/daveSalomon/qefoLdwa/7/
However, if you need to support browsers which don't support CSS media queries (yuck!), then you could use jQuery, and listen on window.resize.
It's worth looking into throttling, and also optimising the following. For example, .show() will be called regardless of whether or not it is necessary. It'll also fire an event for every px the window is resized - you really want to batch them together and action it every x seconds. (Great post: http://benalman.com/projects/jquery-throttle-debounce-plugin/)
$(window).resize(function(){
var w = $(this).width();
if(w > 768){
$('.quick-navbar').show();
} else {
$('.quick-navbar').hide();
}
});
http://jsfiddle.net/daveSalomon/qefoLdwa/8/
Missed the scroll part - apologies.
$(window).scroll(function(){ ... });
if(w > 768 && $(window).scrollTop() > 200){ ... }
http://jsfiddle.net/daveSalomon/qefoLdwa/9/
CSS
.hidden {
display: hidden;
}
.visible {
display: block;
}
#media (max-width:768px){
.js-quick-navbar {
display:none !important; // Added important since we may have the .visible class attached to it at times
}
}
}
JS
$(document).scroll(function() {
var y = $(this).scrollTop();
if (y > 400) {
$('.js-quick-navbar').addClass('visible');
} else if($(this).width() < 768) {
$('.js-quick-navbar').addClass('hidden');
}
});

Make jQuery act dynamically depending on the width of the window

Hello! I've been learning jQuery for a little while now and am trying to sharpen my skills by creating a responsive website. I added a navigation bar, then a big slider, and below it is the main content of the website. Right now, jQuery (as both the menu background and the main background are black) adds a class to the navigation bar in order to turn it white as soon as you scroll past the slider (which has a height of 550px), so it will be easier to read.
Here's the thing: I want jQuery to add that class depending on the width of the window. If it's less than 600px wide, I want the class to be added automatically. Otherwise, I want jQuery to add it as soon as you scroll past the slider (since I hide it when the window is less than 600px wide). My code is below, and it works just fine if I resize the window and then refresh the page, but I want it to add the class dynamically. Do you think it is possible?
I hope I made myself clear (English is not my first language). Let me know if you need me to explain things better! Thank you in advance. :)
if ($(window).width() > 599 ) {
$(window).scroll(function() {
if ($(window).scrollTop() >= 550) { //if you scroll past the slider
$("#main nav").addClass("white-menu");
} else {
$("#main nav").removeClass("white-menu"); //so it turns black again
}
});
} else {
// add it automatically (the slider is hidden):
$("#main nav").addClass("white-menu");
};
you can use all the code inside scroll event
$(window).scroll(function() {
if ($(this).scrollTop() >= 550 && $(this).width() <= 599) { //if you scroll past the slider
$("#main nav").addClass("white-menu");
} else {
$("#main nav").removeClass("white-menu"); //so it turns black again
}
});
a similar DEMO
about resize you can use
$(window).on('resize',function() {
$("#main nav").removeClass("white-menu");
});
on window resize the code will remove the class till user scroll then the scroll event will fire after user scrolling
or instead of all of that you can just use
$(window).on('scroll resize',function() {
if ($(this).scrollTop() >= 550 && $(this).width() <= 599) { //if you scroll past the slider
$("#main nav").addClass("white-menu");
} else {
$("#main nav").removeClass("white-menu"); //so it turns black again
}
});
DEMO
.scroll allows you to listen to event, if you only listen when the window is the correct size, this listener won't get triggered if that changes, so I changed it around a bit:
$(window).scroll(function() {
if ($(window).width() > 599 ) {
if ($(window).scrollTop() >= 550) { //if you scroll past the slider
$("#main nav").addClass("white-menu");
} else {
$("#main nav").removeClass("white-menu"); //so it turns black again
}
}
});
Like Brian mentioned you should use CSS for this other case:
#media (max-width: 600px) {
#main nav {
// white-menu styles here
}
}
For reference the JS way would be:
$(window).resize(function() {
if ($(window).width() <= 599 ) {
$("#main nav").addClass("white-menu");
}
});
It also might be worth thinking about doing a throttle/debounce on these event listeners. They will get called a lot and if your JS starts to do anything more complicated you will see a performance hit. This example uses the underscore library:
var onScroll = function() {
if ($(window).width() > 599 ) {
if ($(window).scrollTop() >= 550) { //if you scroll past the slider
$("#main nav").addClass("white-menu");
} else {
$("#main nav").removeClass("white-menu"); //so it turns black again
}
}
}
// Don't run until the window has stopped being resized for at least 50ms
var debouncedOnScroll = _.debounce(onScroll, 50);
$(window).scroll(debouncedOnScroll);
See http://underscorejs.org/#debounce
Interesting. I used your code in a fiddle and it worked find. As it's state in another answer, the improve of your code will be using the scroll function to wrap all the actions:
$(window).scroll(function() {
$("#main nav").toggleClass("white-menu", ($(window).scrollTop() >= 550 && $(window).width() <= 599));
});

JQuery class swap not acting as expected

I'm writing a script whose function is to convert a drop down menu to an accordion style menu depending on the screen width. To do this, the script swaps out class names based on the width. Visually, everything works as expected when the screen size changes. Also, if I open up the developer tools in chrome and adjust screen width, I can see the class names change in HTML.
Functionally, however, the browser seems to hold onto whatever class name it was when the page loaded. Here's the script:
$(function()
{
var screenWidth;
var screenMode;
var initial_check = 0;
var currentMode;
//check main window width
function checkWidth()
{
screenWidth = $(window).width();
//main size changes
if (screenWidth >= 769)
{
screenMode = "large";
changeDisplayMode("large");
}
else if (screenWidth < 769 && screenWidth > 350)
{
screenMode = "medium";
changeDisplayMode("medium");
}
else if (screenWidth < 350)
{
screenMode = "medium";
changeDisplayMode("medium");
}
//size change to stack View Cart items and search button
if (screenWidth < 603)
{
//show search magnify glass
}
}
//check width when entering page
checkWidth();
$(window).resize(checkWidth);
/////////////////////////////////////////////////////////////////////////////////
/////////// ///////
/////////// Code for navigation transition from drop down to accordion ///////
/////////// ///////
/////////////////////////////////////////////////////////////////////////////////
function changeDisplayMode(mode)
{
if (currentMode != mode)
{
if (mode == "large")
{
//set on first launch
initial_check = 1;
if (initial_check == 1)
{
$("#header_image").show();
$("nav").removeClass("nav_medium").addClass("nav_large");
$("div.main_menu_item_medium").removeClass("main_menu_item_medium").addClass("main_menu_item_large");
$("div.sub_menu_medium").removeClass("sub_menu_medium").addClass("sub_menu_large");
$("div.sub_menu_item_medium").removeClass("sub_menu_item_medium").addClass("sub_menu_item_large");
}
currentMode = "large";
}
else if (mode == "medium")
{
//set on first launch
initial_check = 1;
if (initial_check == 1)
{
$("#header_image").hide();
$("nav").removeClass("nav_large").addClass("nav_medium");
$("div.main_menu_item_large").removeClass("main_menu_item_large").addClass("main_menu_item_medium");
$("div.sub_menu_large").removeClass("sub_menu_large").addClass("sub_menu_medium");
$("div.sub_menu_item_large").removeClass("sub_menu_item_large").addClass("sub_menu_item_medium");
}
currentMode = "medium";
}
}
}
//hide inital dropdown menus
$('.nav_large li ul').hide();
$('.sub_menu_large').hide();
$('.nav_medium li ul').hide();
$('.sub_menu_medium').hide();
//navigation hover in large mode
$('.nav_large ul li').hover(
function()
{
$('.sub_menu_large', this).show();
console.log("large hover");
},
function()
{
$('.sub_menu_large', this).hide();
console.log("large hidden");
}
);
//navigation hover in medium mode
$('.nav_medium ul li').hover(
function()
{
$('.sub_menu_medium', this).show();
console.log("medium hover");
},
function()
{
$('.sub_menu_medium', this).hide();
console.log("medium hidden");
}
);
//accordion style clicks in medium mode
$('.nav_medium ul li').click (
function()
{
$('.sub_menu_medium', this).show();
console.log("clicked medium");
}
);
});
As you can see, there's a large and medium mode. If I load the page in large mode, adjust the browser to medium, and hover over an element, it still logs as it's in large mode. Same thing going from medium to large. As stated, I can see the HTML change correctly when viewing the source.
So, I guess I'm looking for some sort of refresh that doesn't reload the page? Is the class name cached somehow? I've tested this in chrome and firefox with identical results.
The problem is that you might be changing the size of the browser to test. However this approach will not work and will always give you the same width of the browser window no matter how much you reduce it.
In case you want to test it for different window sizes you need to do it through the Emulator of the browsers. In chrome you can press f12 and then Esc, you will get a tab named Emulation. set the screen size from there and test it

Categories

Resources