Need aid on Javascript dropdown menu - javascript

So essentially I can't figure out why this menu won't dropdown when I click on the hamburger icon, any help will be greatly appreciated
Javascript:
function myFunction(){
var hamburger=document.getElementById('nav-btn')
var dropdownContent=document.getElementsByClassName('nav')
hamburger.onclick=dropdownContent.classList.toggle("show");
//or hamburger.onclick=dropdownContent.style.display("block");
}
CSS:
#nav-btn {
display: none;
}
#media (max-width: 1099px) {
li {
display: none;
}
#nav-btn {
display: inline;
position: absolute;
right: 10px;
bottom: 110px;
}
#nav-btn:hover {
content: url('Menu.png');
}
HTML:
<html>
<body>
<span id="nav-btn"><image src="Menugreen.png" input type="button" onclick="myFunction()"/></span>
<div class="nav">
<ul>
<li id="Programs"> Programs </li>
<li> T-Shirts </li>
<li> About </li>
</ul>
</div>
</body>
</html>
Again I am just asking for advice on why the dropdown span id of nav-btn doesn't dropdown the content of ul everything else works fine. Thank you!

You are trying to toggle the show class, but don't have a show class defined. toggleClass() is for adding or removing a CSS class by its name.
// Get DOM references
var hamburger = document.getElementById('nav-btn')
var dropdownContent = document.querySelector('.nav')
// Set up event handler
hamburger.addEventListener("click", function(){
dropdownContent.classList.toggle("hide");
});
#nav-btn {
display: none;
}
#media (max-width: 1099px) {
.hide {
display: none;
}
#nav-btn {
display: inline;
position: absolute;
right: 10px;
bottom: 110px;
}
/* Change the image when you hover over the image, not the span*/
#nav-btn > img:hover {
content: url('Menu.png');
}
}
<span id="nav-btn">
<image src="Menugreen.png" alt="menu">
<input type="button" value=" - - -">
</span>
<div class="nav">
<ul>
<li id="Programs">Programs</li>
<li> T-Shirts </li>
<li> About </li>
</ul>
</div>

Related

Delete object with javascript

I have designed a small panel using the following code, which will display the content to the user by clicking on it:
$('.body_panel').find('li').click(function() {
if ($(this).has("ul")) {
$(this).children('.icon-title-right_panel').hide();
$(this).children('.icon-title-down_panel').show();
} else {
$(this).children('.icon-title-right_panel').show();
$(this).children('.icon-title-down_panel').hide();
}
});
$('.MyPanel').find('li').click(function(evt) {
evt.stopPropagation();
$(this).children('ul').slideToggle();
});
.MyPanel ul li {
cursor: pointer;
position: relative;
}
.MyPanel ul li .icon-title-right_panel,
.MyPanel ul li .icon-title-down_panel {
position: absolute;
top: 0;
right: 0;
font-size: 30px;
}
.MyPanel ul li .icon-title-down_panel {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"/>
<div class="MyPanel">
<ul class="body_panel">
<li class="title_panel">
<h5>title</h5>
<span class="fas fa-circle-chevron-right icon-title-right_panel"></span>
<span class="fas fa-circle-chevron-down icon-title-down_panel"></span>
<ul class="box-contect_panel">
<li class="contect_panel">
<h1>contect</h1>
</li>
</ul>
</li>
</ul>
</div>
By clicking on the title of any icon on the right side, it will be removed. and it appears by clicking again.
As I specified in the script code; What alternative code should I write to delete the icon on the right by clicking on the title and the icon on the bottom appears instead?
Please try to do like this. the key is to catch the toggle status when you click li.
$('.body_panel').find('li').click(function() {
if($(this).parent().find("ul").eq(0).is(':visible')) {
$(this).children('.icon-title-right_panel').show();
$(this).children('.icon-title-down_panel').hide();
} else {
$(this).children('.icon-title-right_panel').hide();
$(this).children('.icon-title-down_panel').show();
}
});
$('.MyPanel').find('li').click(function(evt) {
evt.stopPropagation();
$(this).children('ul').slideToggle();
});
.MyPanel ul li {
cursor: pointer;
position: relative;
}
.MyPanel ul li .icon-title-right_panel,
.MyPanel ul li .icon-title-down_panel {
position: absolute;
top: 0;
right: 0;
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css"/>
<div class="MyPanel">
<ul class="body_panel">
<li class="title_panel">
<h5>title</h5>
<span class="fas fa-circle-chevron-right icon-title-right_panel"></span>
<span class="fas fa-circle-chevron-down icon-title-down_panel"></span>
<ul class="box-contect_panel">
<li class="contect_panel">
<h1>contect</h1>
</li>
</ul>
</li>
</ul>
</div>

mouse toggled event isn't responsive on element that supposed to act as nav drop down menu

My navbar has 3 elements, image, burger-btn styling, and <ul> of 3 items.
When my browser width is 700px or below, I'm hiding my <ul> and the burger-btn element will be in its place. When I click the button I need a drop-down menu that lists out my unordered list. But, my button isn't doing what it's supposed to do.
I tried console.log to check whether my eventListner is picking up the mouse click or not, and my function is fired. I'm getting "clicked" when I click the hamburger element.
const hambrugerBtn = document.getElementById("hamburgur");
const nav_list = document.getElementById("nav_list");
function toggledevent() {
hambrugerBtn.classList.toggle("show");
console.log("clicked");
// hambrugerBtn.style.backgroundColor = "red";
}
hambrugerBtn.addEventListener("click", toggledevent);
.hamburgur {
border: 0;
background-color: transparent;
width: 10px;
}
.nav_list {
display: none;
}
.nav_list.show {
display: flex;
flex-direction: column;
}
#media only screen and (min-width: 700px) {
.hamburger {
display: none;
/* height: 0px; */
}
.nav_list {
display: flex;
justify-content: flex-end;
list-style-type: none;
}
}
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet" />
<script src="https://use.fontawesome.com/releases/v6.2.0/js/all.js"></script>
<nav>
<img class="logo" id="funnylogo" src="images/funny_logo-removebg-preview.png" alt="About Section" />
<button class="hamburgur" id="hamburgur">
<i class="fa-solid fa-bars"></i>
</button>
<ul class="nav_list" id="nav_list">
<li>
About Me
</li>
<li> Profile</li>
<li> For Contact</li>
</ul>
</nav>
You made a mistake in the dropdown selector. Give the button the show class, not the drop-down menu that is placed in the code immediately after the button. This is the .show + .nav-list selector.
const hambrugerBtn = document.getElementById("hamburgur");
const nav_list = document.getElementById("nav_list");
function toggledevent() {
hambrugerBtn.classList.toggle("show");
console.log("clicked");
// hambrugerBtn.style.backgroundColor = "red";
}
hambrugerBtn.addEventListener("click", toggledevent);
.hamburgur {
border: 0;
background-color: transparent;
width: 10px;
}
.nav_list {
display: none;
}
.show+.nav_list {
display: flex;
flex-direction: column;
}
#media only screen and (min-width: 700px) {
.hamburger {
display: none;
/* height: 0px; */
}
.nav_list {
display: flex;
justify-content: flex-end;
list-style-type: none;
}
}
<link href="https://use.fontawesome.com/releases/v6.2.0/css/all.css" rel="stylesheet" />
<script src="https://use.fontawesome.com/releases/v6.2.0/js/all.js"></script>
<nav>
<img class="logo" id="funnylogo" src="images/funny_logo-removebg-preview.png" alt="About Section" />
<button class="hamburgur" id="hamburgur">
<i class="fa-solid fa-bars"></i>
</button>
<ul class="nav_list" id="nav_list">
<li>
About Me
</li>
<li> Profile</li>
<li> For Contact</li>
</ul>
</nav>

How to prevent link from opening in nested <ul> if <li> hasClass

how to prevent opening link if parent li hasClass: has-menu ? it must work for all nested level
in example below only Sub Sub cat 1/1 and Sub cat 1/2 should open link but if i make it work then collapse with + and - is broken , how to combinate both collapse and link opening only if li dont have class: has-menu
$('li').click(function(e){
if ($(this).hasClass('has-menu')) {
e.preventDefault();
e.stopPropagation();
$(this).children("div").children("ul").toggleClass("menu-close");
$(this).toggleClass("menu-open");
}
})
ul{
padding: 0px;
list-style: none;
}
ul li{
padding: 5px 0;
}
ul li a{
width: 100%;
display: inline-block;
}
.menu-close{
display: none;
/*background-color:red;*/
}
/* Main menu */
.menu-main{
width: 250px;
}
.menu-main li{
position: relative;
}
.has-menu:before{
content: '+';
position: absolute;
right: 0;
}
.has-menu.menu-open:before{
content: '-' !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu-main">
<li class="has-menu">
Test 1
<div class="menu-wrapper">
<ul class="menu-child menu-close">
<li class="has-menu">
Sub cat 1/1
<div class="menu-wrapper">
<ul class="menu-subchild menu-close">
<li>
Sub Sub cat 1/1
</li>
</ul>
</div>
</li>
</ul>
<ul class="menu-child menu-close">
<li>
Sub cat 1/2
</li>
</ul>
</div>
</li>
</ul>
.has-menu>a{
pointer-events: none;
}
Try this.
just disable pointer-events on anchor tags that have parent with class .has-menu

Collapseble list with columns?

I need to have a hierarchical, collapsible list that has 3 columns. I have the first two parts working, but I can't seem to get the CSS quite right for the third. The picture shows the current code:
(The slightly duplicated text to the left of col3 is a visual error with the fiddle.)
The goal is to have a three col pseudo-table within a collapsible list such that col1 has the standard list indenting, and col2 is centered for all levels and col3 is at the right for all levels. It should look like this:
I tried to accomplish this by having them both float right and then adding a margin/padding to either col2 or col3 so as to move col2 towards the middle where I want it to be. However, somehow col2 ends up on the outside of col3. Seems impossible to me, but with CSS no bug is impossible.
I have tried various other combinations of margins and paddings and float: lefts without luck.
Here's an almost working fiddle.
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<body>
<div id="listContainer">
<div class="listControl">
<a id="expandList"><button>Expand All</button></a>
<a id="collapseList"><button>Collapse All</button></a>
</div>
<ul id="expList">
<li>
<div class="col1">Non-parent</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
</li>
<li>
<div class="col1">Parent</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
<ul>
<li>
<div class="col1">Child</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
</li>
</ul>
</li>
<li>
<div class="col1">Grandparent</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
<ul>
<li>
<div class="col1">Parent</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
<ul>
<li>
<div class="col1">Child</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
</li>
</ul>
</li>
<li>
<div class="col1">Parent</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
<ul>
<li>
<div class="col1">Child</div>
<div class="col2">Col2</div>
<div class="col3">Col3</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
CSS:
/********************/
/* EXPANDABLE LIST */
/********************/
#listContainer {
margin-top: 15px;
}
#expList ul,
#expList li {
list-style: none;
margin: 0;
padding: 0;
cursor: pointer;
}
#expList p {
margin: 0;
display: block;
}
#expList p:hover {
background-color: #121212;
}
#expList li {
line-height: 140%;
text-indent: 0px;
background-position: 1px 8px;
padding-left: 20px;
background-repeat: no-repeat;
}
/*This works in Firefox following W3C standards, but not in other browsers!*/
/*https://drafts.csswg.org/css-lists/#marker-content*/
/* Collapsed state for list element */
#expList .collapsed {
/* list-style-type: "+";*/
list-style: none;
/*padding: 0px;*/
}
/* Expanded state for list element
/* NOTE: This class must be located UNDER the collapsed one */
#expList .expanded {
/*list-style-type: "-";*/
list-style: none;
/*padding: 0px;*/
}
/*code that works for non-Firefox*/
#expList .collapsed:before {
content: "+";
width: 1em !important;
margin-left: -1.2em;
display: inline-block;
}
#expList .expanded:before {
content: "-";
width: 1em !important;
margin-left: -1.2em;
display: inline-block;
}
#expList {
clear: both;
}
.col1 {
display: inline;
/*padding-right: 100px;*/
}
.col2 {
display: inline;
float: right;
}
.col3 {
display: inline;
float: right;
}
JS:
/**************************************************************/
/* Prepares the cv to be dynamically expandable/collapsible */
/**************************************************************/
function prepareList() {
$('#expList').find('li:has(ul)')
.click(function(event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ul').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ul').hide();
//Hack to add links inside the cv
$('#expList a').unbind('click').click(function() {
window.location($(this).attr('href'));
return false;
});
//Create the button funtionality
$('#expandList')
.unbind('click')
.click(function() {
$('.collapsed').addClass('expanded');
$('.collapsed').children('ul').show('medium');
})
$('#collapseList')
.unbind('click')
.click(function() {
$('.collapsed').removeClass('expanded');
$('.collapsed').children('ul').hide('medium');
})
};
/**************************************************************/
/* Functions to execute on loading the document */
/**************************************************************/
$(document).ready(function() {
prepareList()
});
The solution to this was to realize that float: right apparently also makes the blocks align right, so that they appear in reverse order. With this in mind, one can just switch the order of the blocks to get the normal order back.
E.g.:
<div class="col1">Non-parent</div>
<div class="col4">Col4</div>
<div class="col3">Col3</div>
<div class="col2">Col2</div>
Working fiddle.

z-index does not work with nested absolute elements

I am trying to develop a dropdown which contains a ul list that is expandable. An element of the list is visible by default. When the list is expanded, all the elements should be visible and it should be positioned over the dropdown. I attached the snippet and as you can see, the list expands but the li elements are not over the dropdown, even though the ul has an absolute position and a greater z-index.
var dropdown = false;
var list = false;
function toggleList () {
toggle('.hidden', list);
list = !list;
}
function toggleDropdown () {
toggle('.dropdown', dropdown);
dropdown = !dropdown;
}
function toggle (selector, isAlreadyOpened) {
if(isAlreadyOpened) $(selector).hide();
else $(selector).show();
}
.parent {
position: relative;
background-color: red;
width: 50%;
}
.dropdown {
width: 40%;
height: 100px;
background-color: blue;
display: none;
position: absolute;
right: 0;
z-index: 10;
overflow: hidden;
}
.list {
position: absolute;
z-index: 20;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<button onclick="toggleDropdown()">Toggle dropdown</button>
<div class="dropdown">
First Dropdown
<button onclick="toggleList()">Toggle list</button>
<ul class="list">
<li>1st element</li>
<li class="hidden">2nd element</li>
<li class="hidden">3rd element</li>
<li class="hidden">4th element</li>
<li class="hidden">5th element</li>
<li class="hidden">6th element</li>
</ul>
</div>
</div>
Someone knows how to help on this?
Thanks!
Remove overflow: hidden from .dropdown and there you go!
var dropdown = false;
var list = false;
function toggleList () {
toggle('.hidden', list);
list = !list;
}
function toggleDropdown () {
toggle('.dropdown', dropdown);
dropdown = !dropdown;
}
function toggle (selector, isAlreadyOpened) {
if(isAlreadyOpened) $(selector).hide();
else $(selector).show();
}
.parent {
position: relative;
background-color: red;
width: 50%;
}
.dropdown {
width: 40%;
height: 100px;
background-color: blue;
display: none;
position: absolute;
right: 0;
z-index: 10;
}
.list {
position: absolute;
z-index: 20;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<button onclick="toggleDropdown()">Toggle dropdown</button>
<div class="dropdown">
First Dropdown
<button onclick="toggleList()">Toggle list</button>
<ul class="list">
<li>1st element</li>
<li class="hidden">2nd element</li>
<li class="hidden">3rd element</li>
<li class="hidden">4th element</li>
<li class="hidden">5th element</li>
<li class="hidden">6th element</li>
</ul>
</div>
</div>
Well, I actually feel a bit dumb. I came back to my code and I noticed the overflow: hidden on the .dropdown element. I removed it and it fixed the issue.

Categories

Resources