Accordion on hamburger (Child links not displaying) - javascript

I'm trying to create an accordion which, on click, will display it's child links.
So in my demo below, on click of parent, I'm trying to display child.
$(function() {
// add icon on hamburger
$(".hs-item-has-children").append('<i></i>');
$(".hs-menu-children-wrapper").addClass('menu_hidden');
// on click, check if dropdown is down already
$(".hs-item-has-children").click(function() {
//$('.hs-menu-children-wrapper').toggleClass('menu_is_visibile');
if ($(".hs-menu-children-wrapper").hasClass('menu_hidden'))
$(".hs-menu-children-wrapper").removeClass('menu_hidden');
$(".hs-menu-children-wrapper").addClass('menu_is_visibile');
});
});
.menu li.hs-item-has-children i {
display: block;
position: absolute;
margin-top: 16px;
right: 50px;
margin-top: -28px;
}
.menu li.hs-item-has-children i {
display: block;
}
.menu li.hs-item-has-children i:before,
.menu li.hs-item-has-children i:after {
content: "";
position: absolute;
background-color: #ff6873;
width: 3px;
height: 9px;
}
.menu li.hs-item-has-children i:before {
transform: translate(-2px, 0) rotate(45deg);
}
.menu li.hs-item-has-children i:after {
transform: translate(2px, 0) rotate(-45deg);
}
.menu li.hs-item-has-children ul.hs-menu-children-wrapper.menu_hidden {
display: none !important;
}
.menu li.hs-item-has-children ul.hs-menu-children-wrapper.menu_is_visibile {
display: block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu">
<ul>
<li class="hs-item-has-children" role="menu">Parent
<ul class="hs-menu-children-wrapper menu_hidden">
<li class="hs-menu-item">Child</li>
<li class="hs-menu-item">Child</li>
<li class="hs-menu-item">Child</li>
</ul>
</li>
<li class="hs-item-has-children" role="menu">Parent 2
<ul class="hs-menu-children-wrapper menu_hidden">
<li class="hs-menu-item">Child</li>
<li class="hs-menu-item">Child</li>
<li class="hs-menu-item">Child</li>
</ul>
</li>
</ul>
</div>
It's also a HubSpot menu, so cannot alter the markup too much (which is why I'm using .append())
Edit:
Trying to make only the selected parent links child link show. I.e. if I click Parent 2 in the demo above, only show the child links for that ul (currently both open).

Change your function to:
$(".hs-item-has-children").click(function() {
$(this).children('.hs-menu-children-wrapper').toggleClass('menu_is_visibile');
});
Jsfiddle: https://jsfiddle.net/ukowjqav/1/
Instead of using an if-else, you can toggle the class itself to view each parent's children. Also note that I'm using thisin the function. That way the code knows which particular item it is referencing. Hope this helps.

Related

Is there any way to set CSS animation to work differently on e.g. button On / Off?

I am in a situation where I want to animate mobile navigation. User clicks on a burger and the nav slides down, by clicking on any link or the burger itself nav slides back up.
Till this day I solved this by making 2 divs where first has
display: block; with animation to slide down and the another has display: none; with animation to slide up. After clicking on burger these two options would switch and that will do the thing.
It works just fine, however, I think it can be done with less code.
Something like this?
This uses the css transition property to animate the sliding.
document.getElementById("toggle").addEventListener("click", e => {
document.getElementById("menu").classList.toggle("menu-hidden");
});
body {
margin: 0;
}
.menu {
height: 300px;
width: 100%;
background-color: lightgreen;
transition: all 0.5s;
overflow: hidden;
}
.menu-hidden {
height: 0;
}
<button id="toggle">Toggle menu</button>
<div class="menu" id="menu">Menu content</div>
Please try this. Make click () event to assign ON & OFF value to button.
function onoff(){
currentvalue = $('#onoff').val();
if(currentvalue == "Off"){
$('#onoff').val("On");
}else{
$('#onoff').val("Off")
}
}
</script>
<input type="button" value="On" id="onoff" onclick="onoff();"> ```
Here is another method. This simply makes it so the menu is positioned out of the screen using transform translate, transitions and z-index, and on hamburger click it toggles the menu to slide down to its original position. I have also added functionality so that menu items, on click, will also toggle the menu slide.
document.getElementById("hamburger").addEventListener("click", e => {
document.getElementById("menu").classList.toggle("slide");
});
Array.from(document.getElementsByClassName("menu-item")).forEach((item) => {
item.addEventListener("click", function() {
document.getElementById("menu").classList.toggle("slide");
});
}
);
body {
box-sizing: border-box;
margin: 0;
padding: 0;
}
nav {
position: relative;
background: #fff;
z-index: 2;
}
#menu {
background: lightblue;
margin: 0;
padding: 0;
position: absolute;
z-index: 1;
transform: translateY(-100%);
transition: 0.3s ease-in-out;
}
#menu li {
list-style: none;
padding: 0.5rem 1rem;
cursor: pointer;
}
.slide {
transform: translateY(0) !important;
transition: 0.3s ease-in-out;
}
<nav>
<button id="hamburger">Toggle</button>
</nav>
<ul id="menu">
<li class="menu-item">Link 1</li>
<li class="menu-item">Link 2</li>
<li class="menu-item">Link 3</li>
</ul>

How to get mega menu with nested UL without JS?

We have the following html structure for our menu (see codepin). We would like to modify the menu without having to use JS on page load to move any elements around.
Here is what I tried, but cannot get the custom-dropdown to show like the screenshot below.
Here is my codepin that I have so far, but we are having hard time getting it to align in two columns like the screenshot. The goals below have been simplified, but should be applicable to other links like Category and Company as well since they follow similar structure.
Goal (see screenshot):
On hover of Testing 1, Collaboratively testing 1 and transition accurate should display
On hover of Collaboratively testing 1 then the Enthusiastically communicate cross-platform and Uniquely reconceptualize accurate should display
Screenshot:
Underline below Testing 1 is to simulate on hover effect
Grey background behind Collaboratively Testing is to indicate on hover effect, which results in goal #2 where they are display to the right.
Multi-Level Drop Down Menu with Pure CSS
ul {
list-style: none;
padding: 0;
margin: 0;
background: #1bc2a2;
}
ul li {
display: block;
position: relative;
float: left;
background: #1bc2a2;
}
/* This hides the dropdowns */
li ul { display: none; }
ul li a {
display: block;
padding: 1em;
text-decoration: none;
white-space: nowrap;
color: #fff;
border-bottom: 3px solid #1bc2a2
}
ul li a:hover {border-bottom: 3px solid #2c3e50}
/* Display the dropdown */
li:hover > ul {
display: block;
position: absolute;
}
li:hover li { float: none; }
li:hover a { background: #1bc2a2; }
li:hover li a:hover { background: #2c3e50; }
.main-navigation li ul li { border-top: 0; }
/* Displays second level dropdowns to the right of the first level dropdown */
ul ul ul {
left: 100%;
top: 0;
}
/* Simple clearfix */
ul:before,
ul:after {
content: " "; /* 1 */
display: table; /* 2 */
}
ul:after { clear: both; }
here comes your html code
<h1>Multi-Level Drop Down Menu with Pure CSS</h1>
<ul class="main-navigation">
<li>Home</li>
<li>Front End Design
<ul>
<li>HTML</li>
<li>CSS
<ul>
<li>Resets</li>
<li>Grids</li>
<li>Frameworks</li>
</ul>
</li>
<li>JavaScript
<ul>
<li>Ajax</li>
<li>jQuery</li>
</ul>
</li>
</ul>
</li>
</ul>

hidden submenu in nav bar displaying on hover but not dropping down

I am very new to javascript, so I apologize in advance if I waste anyone's time with a problem that may have a "duh" answer :-)
I am creating a navigation bar for a webpage. It starts off as an unordered list, and I am styling it to float the list items horizontally across the page. That part works fine for me.
I started to work at incorporating an unordered list as a submenu of one of my original list items. When I hover the mouse over the main list item, the submenu items appear, and when I mouse out, the submenu items disappear. The problem is that when the submenu items appear, they display on top of the navigation link to the left, instead of breaking out and dropping down below the link that I am hovering over. I tried setting the position to relative, but then it just shoved the submenu to the right.
I think the problem may be with my css. If I do not apply the external style sheet, then things seem to work better.
Here is my html:
<ul class="nav">
<li>Home</li>
<li>Department Members</li>
<ul id="menu" style="display:none;position:absolute">
<li>Brian Kendricks</li>
<li>Tim Jones</li>
<li>David Kline</li>
</ul>
<li>Systems Used</li>
<li>System Status</li>
<li>Projects</li>
</ul>
My css is:
.nav li {
float: left;
width: 20%;
font-family: verdana,arial,sans-serif;
text-align: center;
padding-top: 5px;
padding-bottom: 5px;
background-image:none;
background-color: #004E98;
display: block;
}
.nav a {
color: white;
}
.nav a:hover {
color: white;
}
.nav li:a:hover {
background-color: #093F6D;
}
And here is my javascript:
function drop(menu) {
document.getElementById(menu).style.display = 'block';
document.getElementById(menu).style.position = 'relative';
}
function hide(menu) {
document.getElementById(menu).style.display = 'none';
}
I would like to stick to using javascript, as the course that I am taking does not wish for me to incorporate things like JQuery at this time.
Thanks in advance for any assistance that you may offer in pointing me in the right direction.
Make your submenu a child of the <li> they are under - instead of currently you have it a child of the overall <ul>. Then you can give the parent item relative positioning, and the child list absolute positioning with top 100% (putting it under the parent item).
function drop(menu) {
document.getElementById(menu).style.display = 'block';
}
function hide(menu) {
document.getElementById(menu).style.display = 'none';
}
.nav li {
float: left;
width: 20%;
font-family: verdana,arial,sans-serif;
text-align: center;
padding-top: 5px;
padding-bottom: 5px;
background-image:none;
background-color: #004E98;
display: block;
position: relative;
}
.nav a {
color: white;
}
.nav a:hover {
color: white;
}
.nav li:a:hover {
background-color: #093F6D;
}
.dropmenu {
position: absolute;
top:100%;
left: 0;
}
.dropmenu li {
display: block;
float: left;
width:100%;
}
<ul class="nav">
<li>Home</li>
<li>Department Members
<ul id="menu" class="dropmenu" style="display:none">
<li>Brian Kendricks</li>
<li>Tim Jones</li>
<li>David Kline</li>
</ul>
</li>
<li>Systems Used</li>
<li>System Status</li>
<li>Projects</li>
</ul>

Displaying submenus on hover without javascript

I have a webpage that uses jquery to display a submenu div while a user is hovering over an a:link in the main parent menu.
$('.menu ul li').hover(function() {
$(this).find('.dropnav').stop(true, true).fadeTo('fast', 1);
}, function() {
$(this).find('.dropnav').stop(true, true).fadeOut(800, 0);
});
The problem is, I want this webpage's navigation feature to be independent of javascript. So when users do not have javascript enabled, the menu will still display - just without the effects of scrolls or fades.
Thanks.
Use the :hover CSS pseudo-class.
.menu ul li:hover .dropnav {
opacity: 1;
/* display: block; ? */
}
Here is a pretty solid example of a CSS based menu. There is JavaScript that goes with it, if you are looking for backwards compatibility to IE6.
http://qrayg.com/learn/code/cssmenus/
HTML
<ul class="main-nav">
<li>main nav-1
</li>
<li>main nav-2
<ul class="sub-nav">
<li>sub-nav-2.1</li>
<li>sub-nav-2.2</li>
<li>sub-nav-2.3</li>
</ul>
</div>
</li>
<li>main nav-3
<li>main nav-4
</ul>
css
ul.main-nav > li { position: relative; display: block; float: left; margin: 0 15px;}
ul.main-nav > li > a {display: block; line-height: 40px; }
ul.sub-nav { display:none; position: absolute; top: 40px; left: 0; min-width: 200px;}
ul.main-nav > li:hover ul.sub-nav { display: block; z-index: 999; }
check this one for live demo http://jsfiddle.net/q9YZf/

Submenu disappears

CSS:
ul.topnav {
list-style: none;
margin: 0px;
padding: 0px;
display: inline;
}
ul.topnav li {
position: relative;
display: inline;
margin: 0px;
padding: 0px;
}
ul.topnav li span.subhover {background-position: center bottom; cursor: pointer;}
ul.topnav li ul.subnav {
list-style: none;
position: absolute;
display: none;
background-color: black;
margin: 0px;
padding: 0px;
border: 1px solid gray;
}
ul.topnav li ul.subnav li {
width: 170px;
margin: 0px;
padding: 0px;
}
HTML:
<ul class="topnav">
<li>Home</li>
<li>
Tutorials
<ul class="subnav">
<li>Sub Nav Link</li>
<li>Sub Nav Link</li>
</ul>
</li>
</ul>
Javascript/JQuery:
$(document).ready(function() {
$("ul.subnav").parent().append("<span>^</span>"); //Only shows drop down trigger when js is enabled (Adds empty span tag after ul.subnav*)
$("ul.topnav li span").click(function() { //When trigger is clicked...
//Following events are applied to the subnav itself (moving subnav up and down)
$(this).parent().find("ul.subnav").slideDown('fast').show(); //Drop down the subnav on click
$(this).parent().hover(function() {}, function(){
$(this).parent().find("ul.subnav").slideUp('slow'); //When the mouse hovers out of the subnav, move it back up
});
//Following events are applied to the trigger (Hover events for the trigger)
}).hover(function() {
$(this).addClass("subhover"); //On hover over, add class "subhover"
}, function(){ //On Hover Out
$(this).removeClass("subhover"); //On hover out, remove class "subhover"
});
});
The menu will show when the <span>^</span> is clicked, but the moment you want to select a sub item, the menu disappears.
What happens is you're no longer hovering so
$(this).parent().hover(function() {}, function(){
$(this).parent().find("ul.subnav").slideUp('slow'); //When the mouse hovers out of the subnav, move it back up
});
this is being called. What you have to do is put an invisible div behind the nav of whatever size you see fit, then use .mouseout() to call the .slideup().

Categories

Resources