Problem
I have a dropdown menu that toggles between a hamburger menu and a cross icon when the navigation opens and closes. However, if a user opens the menu, then resizes the window and the window width is still less than 768px (still open), it shows both the icons stacked on top of each other when it only should show the cross.
On a side note, I'm looking to just simplify the complexity of this Javascript snippet. I'm not sure that adding and removing a class of is-visible was the correct/best approach.
JSFiddle: https://jsfiddle.net/bdmebsu8/
scripts.js
$(function(){
// Window size
if ($(window).width() <= 768) {
$(".icon-cross").hide();
$(".icon-menu").addClass("is-visible");
$(".icon-menu").show();
} else {
$(".icon-menu").hide();
$(".icon-menu").removeClass("is-visible");
}
$(window).resize(function(){
var w = $(this).innerWidth();
if (w > 768) {
$(".nav__list--dropdown").hide();
$(".icon-cross").hide();
$(".icon-menu").hide();
$(".icon-cross").removeClass("is-visible");
$(".icon-menu").removeClass("is-visible");
} else {
$(".icon-cross").hide();
$(".icon-menu").show();
$(".icon-menu").addClass("is-visible");
}
});
// Dropdown menu
$(".nav__menu").on("click", function(){
$(".is-hidden").slideToggle("slow");
var menuVisible = $(".icon-menu").hasClass("is-visible")
if (menuVisible) {
$(".icon-menu").removeClass("is-visible");
$(".icon-menu").hide();
$(".icon-cross").addClass("is-visible");
$(".icon-cross").show();
} else {
$(".icon-cross").removeClass("is-visible");
$(".icon-cross").hide();
$(".icon-menu").addClass("is-visible");
$(".icon-menu").show();
}
});
});
index.html
<div class="dropdown">
<ul class="nav__list--dropdown is-hidden">
<li class="item--services--dropdown">Services</li>
<li class="item--projects--dropdown">Projects</li>
<li class="item--teaching--dropdown">Teaching</li>
<li class="item--blog--dropdown">Blog</li>
<li class="item--contact--dropdown">Contact</li>
</ul>
</div>
<div class="nav__menu">
<img src="src/img/sm-menu.png" class="icon-menu" alt="Open Menu">
<img src="src/img/cross-dark.png" class="icon-cross" alt="Close Menu">
</div>
What you could do to simplify your script:
$(function(){
function updateMenu(){
// all logic in here for checking width and show/hide/set classes
}
updateMenu(); // runs on doc ready
$(window).on("resize", updateMenu);
}
Related
I am building a responsive mobile menu. I am a beginner so don't know how to use loops effectively.
The Problem is that When in mobile view, hamburger menu icon shows and when it is clicked, it changes to close menu icon & when clicked again, changes to hamburger menu.
BUT it stucks there. it only works to 2 clicks and after that it stuck to hamburger menu icon & never changes to close menu icon.
JAVASCRIPT CODE:
window.addEventListener('resize', function detectWidth(){
let screenWidth = screen.width;
if(screenWidth <= 800){
document.querySelector("nav ul").innerHTML = `<img id="menuIcon" src="Header/menuIcon.png" alt="Menu Icon">`;
// TO SHOW MENU ITEMS & CLOSE MENU ICON AFTER CLICKING ON HAMBURGER MENU BUTTON
document.querySelector("#menuIcon").addEventListener("click", function(){
document.querySelector("#menuIcon").outerHTML = `<img id="closMenuIcon" src="Header/closeMenuIcon.png" alt="Close Menu Icon">`;
//TO CHANGE BACK TO MENU ICON
document.querySelector("#closMenuIcon").addEventListener("click", function () {
document.querySelector("#closMenuIcon").outerHTML = `<img id="menuIcon" src="Header/menuIcon.png" alt="Menu Icon">`;
});
})
} else{
document.querySelector("nav ul").innerHTML = `<ul>
<li>Home</li>
<li>Shop</li>
<li>About us</li>
<li>Contact us</li>
</ul>`;
}
});
please forgive me if it is so obvious, I am a beginner and i think it requires loop of some kind.
Even though It's better to use toggling css className, I want to point out on the problem in this case. In your case scenario, you apply event on button element but the thing is outerHTML replaces the element so all events get fired. If you want to stick out to your method, you need to redeclare the events one more time.
I found the answer myself. I really don't know how it works but yeah, at least it works now.
window.addEventListener('resize', function detectWidth(){
let screenWidth = screen.width;
if(screenWidth <= 800){
document.querySelector("nav ul").innerHTML = `<img id="menuIcon" src="Header/menuIcon.png" alt="Menu Icon">`;
// TO SHOW MENU ITEMS & CLOSE MENU ICON AFTER CLICKING ON HAMBURGER MENU BUTTON
function toggleMenu(){
document.querySelector("#menuIcon").addEventListener("click", function(){
document.querySelector("#menuIcon").outerHTML = `<img id="closMenuIcon" src="Header/closeMenuIcon.png" alt="Close Menu Icon">`;
//TO CHANGE BACK TO MENU ICON
document.querySelector("#closMenuIcon").addEventListener("click", function () {
document.querySelector("#closMenuIcon").outerHTML = `<img id="menuIcon" src="Header/menuIcon.png" alt="Menu Icon">`;
toggleMenu();
});
})
}
toggleMenu();
} else{
document.querySelector("nav ul").innerHTML = `<ul>
<li>Home</li>
<li>Shop</li>
<li>About us</li>
<li>Contact us</li>
</ul>`;
}
});
I am learning JavaScript. I created a navigation bar with two divs:
And added a function so that when the user scrolls down, the first div will fadeOut:
$(document).ready(function() {
var $nav = $('.first-nav'); //Caching element
// fade in .navbar
$(function() {
$(window).scroll(function() {
// set distance user needs to scroll before we start fadeIn
if ($(this).scrollTop() > 275) {
$nav.fadeOut("fast");
} else {
$nav.fadeIn();
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-default navbar-fixed-top pages">
<div class="container-fluid first-nav">
<button id="nav-toggle" data-target=".sidebar-right" data-toggle="sidebar" class="navbar-toggle toggle-right" type="button">
<span></span>
</button>
Login
<button id="get_quote_navbar" name="get_quote_navbar" class="btn btn-login">Get Quote</button>
<i class="fa fa-phone"></i> (877) 400-0232
<!-- Logo -->
<!-- /Logo -->
Home
For Home
For Business
</div>
<div id="navigation" class="col-md-12 sub-nav">
<div class="col-md-6 sub-nav-left">
Commercial
Construction
Multy-family
Partnership
</div>
<div class="col-md-3 sub-nav-right">
<button id="get_quote" name="get_quote_navbar" class="btn btn-quote">Get Quote</button>
</div>
</div>
</nav>
All works fine. In CSS, I created #media for min and max width. And when I do that, for desktop and tablet is all good, but when I want to put fixed first div for mobile, JavaScript makes a problem and I have blinked div when scroll up-down.
How I can add in JS function if (width < 1024) then $nav.fadeIn();?
Try:
if ($(window).width() < 1024) {
$nav.fadeIn();
}
If you want to work with media queries in javaScript, just use the window.matchMedia() as following:
if (window.matchMedia("(min-width: 400px)").matches) {
/* the viewport is at least 400 pixels wide */
} else {
/* the viewport is less than 400 pixels wide */
}
Full reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia
To get the effect on resizing the window, you need to do like:
function foo(){
//code here
}
foo();
$(window).on('resize orientationchange',foo);
Thanks guys, I succeeded. This is a code.
$(document).ready(function(){
var $nav = $('.first-nav');//Caching element
// hide .navbar first - you can also do this in css .nav{display:none;}
// fade in .navbar
$(function () {
$(window).scroll(function () {
if ($(this).scrollTop() > 275 && $(window).width() > 1024) {
$nav.fadeOut("fast");
} else {
$nav.fadeIn();
}
});
});
});
you can do like this for test the with of the window,
note: you have to refresh the page when you change the size of the window
var widthScreen = window.matchMedia('(max-width: 1023px)').matches;
if(widthScreen){
$nav.fadeIn();
}
So the first block of code opens and closes the .main-navigation while putting the shadow overlay over the page at the same time. But what I would like to accomplish is to click anywhere outside the navigation to do the same action(close the menu and remove the overlay) only if the menu is opened and overlay is over the page - so if those two classs are applied.
Fiddle: https://jsfiddle.net/bfgb951w/
<header id="ovlay">
<span class="nav-toggle eq">≡</span>
<nav class="main-navigation">
<span class="nav-toggle">×</span>
<ul class="menu">
<li>About</li>
<li>Works and stuff</li>
<li>Contact</li>
</ul>
</nav>
</header>
$(document).ready(function(){
$('.nav-toggle').on('click', function(){
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
});
});
$(document).click(function(){
if($('.nav-toggle').hasClass('open')) {
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
}
});
You never set the open class to the .nav-toggle element so while the $(document).click() fires, the if-statement within it always yields false. Change it to:
$(document).ready(function(){
$('.nav-toggle').on('click', function(){
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
return false;
});
});
$(document).click(function(event){
if($('.main-navigation').hasClass('open') && $(event.target).closest(".main-navigation").length == 0) {
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
}
});
Check this fiddle: https://jsfiddle.net/1n78d9jq/
Note the added check in the document.click that prevents closing when the click is on the main menu itself.
I am attempting to change a href url once the browser scroll down. I am swapping css classes based on browser position. I am swappping out an image with an anchor down tag applied to it with a logo that I now what to have a home link applied to it.
Check my site here: http://www.paynecocraft.com (WIP)
The main page has a yellow arrow at the bottom. Click it and the browser scrolls, the nav becomes sticky and the logo appears. I would like the logo to have a homepage link once it gets to that point.
Here is my html
<nav>
<ul class="inline-list main-links">
<li class="linkitem">About</li>
<li class="linkitem">Work</li>
<li class="linkitem">Store </li>
<li class="circlearrow"><a id="changeonscroll" href="#scrolldown"></a></li>
<li class="linkitem">Plans</li>
<li class="linkitem">Contact</li>
<li class="linkitem">Blog</li>
</ul>
</nav>
I'm referring to the "circlearrow" li.
Here is the javascript I am using, but its not working. I'm just now diving into Javascript so I probably don't have something right. Forgive me.
<script>
$(document).ready(function(){
$(window).bind('scroll', function() {
var navHeight = $( window ).height() - 80;
if ($(window).scrollTop() > navHeight) {
document.getElementById("changeonscroll").href = http://www.paynecocraft.com;
}
});
});
</script>
Try this:
JSFiddle (you need to resize the window to try to scroll)
$(document).ready(function () {
$(window).bind('scroll', function () {
var navHeight = $(window).height() - 80;
if ($(window).scrollTop() > navHeight) {
$("#changeonscroll").text('Hello World').attr('href', 'http://www.paynecocraft.com');
}
});
});
I want to achieve 2 things when in responsive small screen size:
Create a onclick CSS animated 'hamburger' icon into a cross icon (now it is just a fadeIn/Out effect).
Remove class on scroll event so cross icon turns back in default hamburger icon.
I'm now using svg images for the nav-btn.
I know that i have to add a removeClass action on the scroll event, but tried some different things, but my JS-skills aren't that good.
Hope there is someone that can help or guide me threw this either the one or the other.
Here the FIDDLE
Screenshots:
Cross need to changes back in hamburger icon on scroll:
Html:
<header>
<nav>
<div class="col-nav">
Logo
</div>
<ul>
<li class="col-nav">Item1</li>
<li class="col-nav">Item2</li>
<li class="col-nav">Item3</li>
</ul>
</nav>
</header>
Javascript:
$(function() {
$('.nav-btn').click(function() {
$('nav ul').fadeToggle(300);
$(this).toggleClass("open");
})
});
$(window).scroll(function() {
if ($(this).scrollTop() > 50) {
$('nav ul').hide(); }
});
Add $('.nav-btn').removeClass('open');
$(window).scroll(function() {
if ($(this).scrollTop() > 50) {
$('nav ul').hide();
$('.nav-btn').removeClass('open');
}
});