Close the mobile menu in id links - javascript

This is the mobile menu I wrote for my site.
Sometimes some links are id. (Example: herf="#id")
I want the menu to be closed automatically when the user clicks when there are such links. (Close the hamburger icon as well.)
In JavaScript, can you tell me what to do?
/* eslint-env browser */
(function() {
'use strict';
document.addEventListener('DOMContentLoaded', function() {
let hamburger = document.querySelector('.js-hamburger');
let hamburgerMenu = function () {
document.querySelector('.js-navs').classList.toggle('is-open');
};
if (hamburger) {
hamburger.addEventListener('click', hamburgerMenu, false);
}
});
})();
<link href="https://restaurant-landing.surge.sh/styles/main.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="o-section c-section--header" style="background-image: none;">
<div class="o-section__wrapper">
<div class="c-header">
<div class="c-header__col">
<div class="c-hamburger">
<input class="c-hamburger__checkbox js-hamburger" type="checkbox" aria-label="Menu" />
<span class="c-hamburger__icon"></span>
<span class="c-hamburger__icon"></span>
<span class="c-hamburger__icon"></span>
</div>
</div>
<div class="c-header__col">
<div class="c-header__wrap js-navs">
<ul class="s-nav">
<li>
WHY US
</li>
<li>
MENU
</li>
<li>
POPULAR DISHES
</li>
<li>
BOOK
</li>
<li>
CONTACT
</li>
</ul>
</div>
</div>
</div>
</div>
</header>

I think this does the trick:
const hashLinks = document.querySelectorAll('.s-nav a');
hashLinks.forEach((element) => {
if(element.hash[0] == '#') {
element.addEventListener('click', hamburgerMenu);
}
});
How it works:
gets all the links inside your menu
iterates over each element
if the element's link has a hashtag as the first character
assign a click event listener to toggle the menu

/* eslint-env browser */
(function() {
'use strict';
document.addEventListener('DOMContentLoaded', function() {
let hamburger = document.querySelector('.js-hamburger');
let hamburgerMenu = function () {
document.querySelector('.js-navs').classList.toggle('is-open');
};
if (hamburger) {
hamburger.addEventListener('click', hamburgerMenu, false);
};
$(".s-nav a").each((indx,link) => {
if(link.hash.startsWith("#")) link.addEventListener("click",hamburgerMenu);
});
});
})();
<link href="https://restaurant-landing.surge.sh/styles/main.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header class="o-section c-section--header" style="background-image: none;">
<div class="o-section__wrapper">
<div class="c-header">
<div class="c-header__col">
<div class="c-hamburger">
<input class="c-hamburger__checkbox js-hamburger" type="checkbox" aria-label="Menu" />
<span class="c-hamburger__icon"></span>
<span class="c-hamburger__icon"></span>
<span class="c-hamburger__icon"></span>
</div>
</div>
<div class="c-header__col">
<div class="c-header__wrap js-navs">
<ul class="s-nav">
<li>
WHY US
</li>
<li>
MENU
</li>
<li>
POPULAR DISHES
</li>
<li>
BOOK
</li>
<li>
CONTACT
</li>
</ul>
</div>
</div>
</div>
</div>
</header>

Related

multiple elements attached to one click event listener

what i want to happen is that on clicking one of the #playlist instances in the unordered list, it will take the corresponding instances inner text and use it to find the rest of the information, like the csv and cover. this is what i have so far but im not sure if im going in the right direction or how to continue. thanks
const playlistCover = document.querySelector('#playlist-cover');
const playlistName = document.querySelector('#playlist-name');
const playlistDuration = document.querySelector('#playlist-duration');
const playlistLength = document.querySelector('#playlist-length');
const playlistSize = document.querySelector('#playlist-size');
const playlistSelector = document.querySelectorAll('.playlist #playlist').forEach(item => {
item.addEventListener('click', event => {
loadPlaylist();
})
})
function loadPlaylist() {
playlistName.innerText = playlist
playlistCover.src = `static/playlists/${playlist}/cover.png`
playlistCSV = `static/playlists/${playlist}/${playlist}.csv`
}
<div class="playlists">
<h3>Playlists</h3>
<ul>
<li class="playlist">
<a id="playlist" href="#hyperpop">hyperpop</a><a id="options">...</a>
</li>
<li class="playlist">
<a id="playlist" href="#uk-rap">uk-rap</a><a id="options">...</a>
</li>
<li class="playlist">
<a id="playlist" href="#misc">misc</a><a id="options">...</a>
</li>
</ul>
</div>
<div class="main">
<div class="playlist-container">
<div class="info">
<div class="playlist-cover">
<img src="static/playlists/uk-rap/cover.png" alt="playlist-cover" id="playlist-cover">
</div>
<div class="playlist-details">
<div class="header">
<h1 id="playlist-name">uk-rap</h1>
</div>
<div id="playlist-data">
<p class="playlist-duration">6 hours 42 minutes</p>
<p class="playlist-songs">192 songs</p>
<p class="playlist-size">372.5 mb </p>
</div>
</div>
</div>
</div>
<script src="static/scripts/playlist loader.js"></script>
</div>
Here is a simplified version of your code.
The way it works is by making the information hidden by default.
Then, when you click on the name of the playlist, the information appears.
This is handled by toggling the hidden class by using elm.classList.toggle().
document.querySelectorAll(".playlist .info")
.forEach(p => p.parentElement.addEventListener(
"click",
() => p.classList.toggle("hidden"))
);
.hidden {
display: none;
}
li {
list-style: none;
}
.playlist>span:hover {
cursor: pointer;
font-weight: bold;
}
<div class="container">
<ul class="playlists">
<li class="playlist">
<span>UK-Rap</span>
<div class="info hidden">
<div class="duration">6 hours 42 mins</div>
<div class="songs">192 songs</div>
<div class="size">372.5 mb</div>
</div>
</li>
<li class="playlist">
<span>Jazz</span>
</li>
<li class="playlist">
<span>Pop</span>
</li>
</ul>
</div>

problems with nav in mobile view

I am trying to have an icon that is going to show up in my mobile veiw where you can click show and hide the menu,
right now my code doesnt work, it does not open at all
my problem is trying to figure out id's and inputs here
not sure what I am doing wrong, could someone point me to the right direction please ? Thanks in advance
//this is what I have
<nav class="navMenu">
<input id="menu-icon" type="checkbox">
<label id="menu-icon" class="iconMenuLbl" for="menu-icon"></label>
<ul>
<li>
<img class="navImg" src="media/Home-tall.png" alt="">
</li>
<li>
<img class="navImg" src="media/My-Details-tall.png" alt="">
</li>
<li>
<img class="navImg" src="media/My-Loans-tall.png" alt="">
</li>
<li id="loggedin-box" class="">
<form method="POST" action="login">
<div>
<strong>some name</strong>
</div>
<button style="padding:0px;" name="logout" type="submit">
<img class="navImg" src="media/Sign-Out.png">
</button>
</form>
</li>
</ul>
</nav>
//js file
$(function() {
var menuVisible = false;
$('#menu-icon').click(function() {
if (menuVisible) {
$('.navMenu').css({'display':'none'});
menuVisible = false;
return;
}
$('.navMenu').css({'display':'block'});
menuVisible = true;
});
$('.navMenu').click(function() {
$(this).css({'display':'none'});
menuVisible = false;
});
});
You have two ids sharing the same name. 'menu-icon' try changing one of the ids to another name. IDs should be unique. -- ALSO move your input field out of the nav tag.

How to find nth p element?

I want to find the 3rd p tag of each category, based on first p tag's value.
e.g. The first p tag value is Tie, then find the quantity of it.
If the html element tree should be formatted in a better way, I am open to it. The html for all ul is written from code behind at C# to load items from database.
$("#wel div ").each(function(index, element) {
if ($(this).('p:nth-of-type(1)').html() == "Tie")
{
$(this).('p:nth-of-type(3)').css('background-color','red');
}
}
<div id="fel">Category1
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p> <!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
<div id="wel">Category2
<ul>
<li>
<div >
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p><!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</ul>
</div>
JSFiddle
You can 2 top level elements with different ids fel and wel so need to use #wel div, #fel div to find the category div elements, then need to use .find() to find the p
$("#wel div, #fel div").each(function (index, element) {
if ($(this).find('p:nth-of-type(1)').html().trim() == "Tie") {
$(this).find('p:nth-of-type(3)').css('background-color', 'red');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="fel">Category1
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
<div id="wel">Category2
<li>
<div>
<p>Shirt</p>
<p>Price:$25</p>
<p>Quantity:20</p>
</div>
</li>
<li>
<div>
<p>Tie</p>
<p>Price:$10</p>
<p>Quantity:10</p>
<!--find this?-->
</div>
</li>
<li>
<div>
<p>Trousers</p>
<p>Price:$50</p>
<p>Quantity:5</p>
</div>
</li>
</div>
You can also do
$("#wel div, #fel div ").each(function (index, element) {
var $ps = $(this).find('p');
if ($ps.eq(0).html().trim() == "Tie") {
$ps.eq(2).css('background-color', 'red');
}
})
Demo: Fiddle
Here's the generic way of doing it
$(document).ready(function(){
var div = $('p:contains("Tie")').parent()
$('p:contains("Tie")').parent()
var price = $(div).find("p:contains('Price')").css('background-color','red');
console.log(price)
});
Please refer the fiddle here

Using Jquery to toggle class based on menu item clicked

Ok im working on this website where Id like to have the content of a div change to content based on the menu item clicked. I do not have pages for the different menu items but I have all the different content in divs in the index page. I would like to incorporate JQuery but I just cannot seem to find a way to link the menu item class or id to the corresponding div element. My code below":
<html>
<body>
<div class="navbar grid_12">
<ul>
<li class="btn" id="home">Home</li>
<li class="btn" id="about">About Me</li>
<li class="btn" id="gallery">Gallery</li>
<li class="btn" id="resume">Resume</li>
<li class="btn" id="contact">Contact Me</li>
</ul>
</div>
<div class="content-container">
<div class="bio content">
About me content
</div>
<div class="contact content">
Contact me content
</div>
<div class="gallery content">
gallery content
</div>
</div>
</body>
</html>
etc..
as for my JQuery coding so far this is where i am after hours of trying different things out
//Update Content-Container Div
$(document).ready(function(){
var $main = $(".content-container");
var $section = $(".content");
$("#about").click(function(){
$main.empty();
$main.find(".bio");
$(".bio").show();
});
});
Instead of writing individual handlers for each menu item, use a data-* attribute to refer to a particular content which need to be displayed, then in the click handler use that attribute to decide which content has to be displayed
<div class="navbar grid_12">
<ul>
<li class="btn" id="home">Home</li>
<li class="btn" id="about" data-target=".bio">About Me</li>
<li class="btn" id="gallery" data-target=".gallery">Gallery</li>
<li class="btn" id="resume">Resume</li>
<li class="btn" id="contact" data-target=".contact">Contact Me</li>
</ul>
</div>
<div class="content-container">
<div class="bio content">
About me content
</div>
<div class="contact content">
Contact me content
</div>
<div class="gallery content">
gallery content
</div>
</div>
then
$(document).ready(function () {
var $main = $(".content-container");
var $section = $(".content").hide();
$(".navbar li.btn").click(function (e) {
e.preventDefault();
$section.hide();
var target = $(this).data('target');
if(target){
$section.filter(target).show();
}
});
});
Demo: Fiddle
Check out jquery tabs,
I think you need this.
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Tabs - Default functionality</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
</head>
<body>
<div id="tabs">
<ul>
<li>Home</li>
<li>About Me</li>
<li>Gallery</li>
<li>Resume</li>
<li>Contact Me</li>
</ul>
<div id="tabs-1">
<p>Home content</p>
</div>
<div id="tabs-2">
<p>About me content</p>
</div>
<div id="tabs-3">
<p>Gallery content </p>
</div>
<div id="tabs-4">
<p>Resume content </p>
</div>
<div id="tabs-5">
<p>Contact Me content </p>
</div>
</div>
</body>
</html>
Try:
Assuming ids are associated with relevant classes.
HTML:
<li class="btn" id="bio">About Me</li>
JS:
$(".btn").click(function () {
$(".content-container .content").hide();
$(".content-container").find("."+$(this).attr("id")).show();
});
DEMO here.
Here I initially hid everything, then based on what links you click, the page displays the correct content. Note that your about page has the wrong id attribute so it will not work but your contact and gallery pages work. This is roughly how the twitter bootstrap framework works, I do suggest you look at that.
var $main = $(".content-container");
var $section = $(".content");
$section.hide();
$("li.btn").on('click', function() {
var link_id = $(this).attr('id');
var content = $main.find("." + link_id);
$section.hide();
content.show();
})
Working Example
const containers = Array.from(document.querySelectorAll('.content'));
// Slicing for link as it's not related to changing the slide content,
// so we don't want to bind behaviour to it.
const links = Array.from(document.querySelectorAll('.navbar ul .btn a')).slice(1);
$(function() {
hideEls(containers);
});
function hideEls (els) {
if (Array.isArray(els)) {
els.forEach(el => {
el.style.display = 'none';
});
}
return;
}
function showEl (els, i, e) {
e.preventDefault();
hideEls(els);
els[i].style.display = 'block';
}
links.forEach((link, i) => {
link.addEventListener('click', showEl.bind(null, containers, i));
});
Here's a fiddle

Parallax next and previous navigation

At the moment for my parallax site i have next and previous buttons on each section. I would like to just have one set of prev/next navigation that will go to each section.
Can you advise me on whitch route to go down please?
html:
<head>
<title>The history of aeronautics</title>
<meta charset="utf-8" />
<meta name="description" content="A parallax scrolling experiment using jQuery" />
<link rel="stylesheet" media="all" href="css/main.css" />
<script src="js/modernizr.custom.37797.js"></script>
<!-- Grab Google CDN's jQuery. fall back to local if necessary -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>!window.jQuery && document.write('<script src="/js/jquery-1.6.1.min.js"><\/script>')</script>
<script src="js/parallax.js"></script>
</head>
<body>
<div id="wrapper">
<div id="car"><img src="images/car.png"></div>
<nav id="primary">
<ul>
<li>
<h1>Hospital</h1>
<a class="hospital" href="#hospital">View</a>
</li>
<li>
<h1>University</h1>
<a class="university" href="#university">View</a>
</li>
<li>
<h1>Health Centre</h1>
<a class="health-centre" href="#health-centre">View</a>
</li>
<li>
<h1>Horiba HQ</h1>
<a class="horiba-hq" href="#horiba-hq">View</a>
</li>
<li>
<h1>Entertainment Hub</h1>
<a class="entertainment-hub" href="#entertainment-hub">View</a>
</li>
<li>
<h1>Vet</h1>
<a class="vet" href="#vet">View</a>
</li>
<li>
<h1>General Hospital</h1>
<a class="general-hospital" href="#general-hospital">View</a>
</li>
</ul>
</nav>
<div id="content">
<article id="hospital">
<img src="images/image1.png"/>
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-2">
<div class="ch-info">
<h3><a class="university" href="#university">Next</a></h3>
</div>
</div>
</li>
</ul>
</article>
<article id="university">
<img src="images/image2.png"/>
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info">
<h3><a class="hospital" href="#hospital">Prev</a></h3>
</div>
</div>
</li>
<li>
<div class="ch-item ch-img-2">
<div class="ch-info">
<h3><a class="health-centre" href="#health-centre">Next</a></h3>
</div>
</div>
</li>
</ul>
</article>
<article id="health-centre">
<img src="images/image3.png"/>
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info">
<h3><a class="university" href="#university">Prev</a></h3>
</div>
</div>
</li>
<li>
<div class="ch-item ch-img-2">
<div class="ch-info">
<h3><a class="horiba-hq" href="#horiba-hq">Next</a></h3>
</div>
</div>
</li>
</ul>
</article>
<article id="horiba-hq">
<img src="images/image4.png"/>
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info">
<h3><a class="health-centre" href="#health-centre">Prev</a></h3>
</div>
</div>
</li>
<li>
<div class="ch-item ch-img-2">
<div class="ch-info">
<h3><a class="entertainment-hub" href="#entertainment-hub">Next</a></h3>
</div>
</div>
</li>
</ul>
</article>
<article id="entertainment-hub">
<img src="images/image5.png" />
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info">
<h3><a class="horiba-hq" href="#horiba-hq">Prev</a></h3>
</div>
</div>
</li>
<li>
<div class="ch-item ch-img-2">
<div class="ch-info">
<h3><a class="vet" href="#vet">Next</a></h3>
</div>
</div>
</li>
</ul>
</article>
<article id="vet">
<img src="images/image6.png"/>
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info">
<h3><a class="entertainment-hub" href="#entertainment-hub">Prev</a></h3>
</div>
</div>
</li>
<li>
<div class="ch-item ch-img-2">
<div class="ch-info">
<h3><a class="general-hospital" href="#general-hospital">Next</a></h3>
</div>
</div>
</li>
</ul>
</article>
<article id="general-hospital">
<img src="images/hospital.png"/>
<ul class="ch-grid">
<li>
<div class="ch-item ch-img-1">
<div class="ch-info">
<h3><a class="vet" href="#vet">Prev</a></h3>
</div>
</div>
</li>
</ul>
</article>
</div>
<!-- Parallax foreground -->
<div id="parallax-bg3">
</div>
<!-- Parallax midground clouds -->
<div id="parallax-bg2">
<img id="bg2-1" src="images/blurred-buildings.png" />
</div>
<!-- Parallax background clouds -->
<div id="parallax-bg1">
<img id="bg1-1" src="images/clouds.png" />
</div>
</div>
</body>
js:
$(document).ready(function() {
redrawDotNav();
/* Scroll event handler */
$(window).bind('scroll',function(e){
parallaxScroll();
redrawDotNav();
});
/* Next/prev and primary nav btn click handlers */
$('a.hospital').click(function(){
$('html, body').animate({
scrollTop:0
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
});
$('a.university').click(function(){
$('html, body').animate({
scrollTop:1500
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
});
$('a.health-centre').click(function(){
$('html, body').animate({
scrollTop:3800
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
return false;
});
$('a.horiba-hq').click(function(){
$('html, body').animate({
scrollTop:5500
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
});
$('a.entertainment-hub').click(function(){
$('html, body').animate({
scrollTop:6800
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
});
$('a.vet').click(function(){
$('html, body').animate({
scrollTop:7700
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
});
$('a.general-hospital').click(function(){
$('html, body').animate({
scrollTop:11000
}, 1000, function() {
parallaxScroll(); // Callback is required for iOS
});
});
/* Show/hide dot lav labels on hover */
$('nav#primary a').hover(
function () {
$(this).prev('h1').show();
},
function () {
$(this).prev('h1').hide();
}
);
});
/* Scroll the background layers */
function parallaxScroll(){
var scrolled = $(window).scrollTop();
$('#content').css('left',(0-(scrolled*.9))+'px');
$('#parallax-bg1').css('left',(0-(scrolled*.25))+'px');
$('#parallax-bg2').css('left',(0-(scrolled*.5))+'px');
$('#parallax-bg3').css('left',(0-(scrolled*.9))+'px');
}
/* Set navigation dots to an active state as the user scrolls */
function redrawDotNav(){
var section1Top = 0;
// The top of each section is offset by half the distance to the previous section.
var section2Top = $('#university').offset().left + 1000;
var section3Top = $('#health-centre').offset().left +3000;
var section4Top = $('#horiba-hq').offset().left +4000;
var section5Top = $('#entertainment-hub').offset().left +6000;
var section6Top = $('#vet').offset().left +6800;
var section7Top = $('#general-hospital').offset().left +9100;
$('nav#primary a').removeClass('active');
if($(document).scrollTop() >= section1Top && $(document).scrollTop() < section2Top){
$('nav#primary a.hospital').addClass('active');
} else if ($(document).scrollTop() >= section2Top && $(document).scrollTop() < section3Top){
$('nav#primary a.university').addClass('active');
} else if ($(document).scrollTop() >= section3Top && $(document).scrollTop() < section4Top){
$('nav#primary a.health-centre').addClass('active');
} else if ($(document).scrollTop() >= section4Top && $(document).scrollTop() < section5Top){
$('nav#primary a.horiba-hq').addClass('active');
} else if ($(document).scrollTop() >= section5Top && $(document).scrollTop() < section6Top){
$('nav#primary a.entertainment-hub').addClass('active');
} else if ($(document).scrollTop() >= section6Top && $(document).scrollTop() < section7Top){
$('nav#primary a.vet').addClass('active');
} else if ($(document).scrollTop() >= section7Top){
$('nav#primary a.general-hospital').addClass('active');
}
}
I have tried adding this which can be seen here but it doesnt click through to the next section
js used:
$(function() {
var $tabs = $('#content').tabs();
$(".ui-tabs-panel").each(function(i){
var totalSize = $(".ui-tabs-panel").size() - 1;
if (i != totalSize) {
next = i + 2;
$(this).append("<a href='#' class='next-tab mover' rel='" + next + "'>Next Page »</a>");
}
if (i != 0) {
prev = i;
$(this).append("<a href='#' class='prev-tab mover' rel='" + prev + "'>« Prev Page</a>");
}
});
$('.next-tab, .prev-tab').click(function() {
$tabs.tabs('select', $(this).attr("rel"));
return false;
});
});
Sorry about long post wanted to give as much info as possible
Thanks
You didn't insert anchor tag in href next page, you need to add it for each section of page, then automatically will go to next or previous page by clicking on that.. cause you just insert (#) so thats why nothing happened...

Categories