Javascript adding styling to element with same class - javascript

I am making a dropdown menu in a dropdown, I want that I have a few head items and if you click on one, the dropdown in that head item is displayed as a block element. But the problem is that they all have the same class and when I want to add a class all the dropdowns inside the head items get that class. What am I doing wrong here?
jQuery(document).ready(function(){
var click = false;
jQuery(".navbar-collapse .nav li").click(function() {
if(click == false) {
jQuery(".navbar-collapse .nav li ul").addClass('clicked');
click = true;
} else {
jQuery(".navbar-collapse .nav li ul").removeClass('clicked');
click = false;
}
});
});
.clicked {
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav menu">
<li class="item-101 default deeper parent">
Home
<ul class="nav-child unstyled small clicked">
<li class="item-124">
Maandmail
</li>
</ul>
</li>
<li class="item-102 default deeper parent">
Contact
<ul class="nav-child unstyled small clicked">
<li class="item-125">
Contact pagina
</li>
</ul>
</li>
</ul>
Does anyone know why this is happening and how to fix this issue?

You have to make the code look at the specific UL relative to the item you've clicked on:
jQuery(document).ready(function() {
var click = false;
jQuery(".navbar-collapse .nav li").click(function(e) {
if (click == false) {
jQuery(e.currentTarget).find("ul").addClass('clicked');
click = true;
} else {
jQuery(e.currentTarget).find("ul").removeClass('clicked');
click = false;
}
});
});

Related

How To Add Active Class To a Current Navbar Element?

hope you all doing great.
I've been trying to add the (active class )to each of the navbar links when the user is on that specific section of the page with this
Tutorial (i'm stuck at 2:45:05) and no success so far can anyone tell me what i did wrong .thank you.
const menu = document.querySelector(' nav .container ul');
const navItems = menu.querySelectorAll('li');
navItems.forEach(item => {
const link = item.querySelector('a');
ink.addEventListener('click', () => {
link.classList.add(".active");
});
});
nav .container ul li a.active {
background: var(--color-primary);
color: var(--color-white);
}
<nav>
<div class="container">
<a href="#">
<h3> AMANI DEV </h3>
</a>
<ul>
<li>Home</li>
<li>About</li>
<li>Skills</li>
<li>Services </li>
<li>Portfolio </li>
<li>Contact Me </li>
</ul>
</div>
</nav>
Typo with ink not link.
When you assign a class with classList you don't include the .: classList.add('active').
In your CSS background should probably be background-color.
If you want to remove the other active links before applying the new one you can use forEach to iterate over the links and use classList.remove('active') on each one.
You may find event delegation easier to manage. Rather than attaching multiple listeners to multiple elements attach one listener to the list element that watches out for events from its child elements as they "bubble up the DOM. You can then check that the clicked element is a link, remove the active classes from the previous link(s), and then apply the active class to the clicked link.
Here's an example using event delegation.
// Cache the list, and the items
const list = document.querySelector(' nav .container ul');
const links = list.querySelectorAll('a');
// Add one listener to the list element
list.addEventListener('click', handleClick);
// If the clicked element is a link remove all
// the active classes from the other links, and then
// add the active class to the link that was clicked on
function handleClick(e) {
if (e.target.matches('a')) {
links.forEach(link => link.classList.remove('active'));
e.target.classList.add('active');
}
}
:root { --color-white: white; --color-primary: red; }
.active {
background-color: var(--color-primary);
color: var(--color-white);
}
<nav>
<div class="container">
<a href="#">
<h3> AMANI DEV </h3>
</a>
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>About</li>
<li>Skills</li>
<li>Services </li>
<li>Portfolio </li>
<li>Contact Me </li>
</ul>
</div>
</nav>
You need to do querySelectorAll in a tag not on the li tag. Just do this and do let me know.
Modify the code in the following line :
ink.addEventListener('click',() => {
to
link.addEventListener('click',() => {
to be like this
const menu = document.querySelector(' nav .container ul');
const navItems = menu.querySelectorAll('li');
navItems.forEach(item => {
const link = item.querySelector('a');
link.addEventListener('click',() => {
link.classList.add(".active");
});
});
document.querySelectorAll('ul li').forEach(el => {
el.onclick = () => {
document.querySelectorAll('ul li').forEach(el => el.classList.remove('active'));
el.classList.add('active');
}
})
here a demo code:
document.querySelectorAll('#myNav li').forEach(el => {
el.onclick = () => {
document.querySelectorAll('#myNav li').forEach(el => el.classList.remove('active'));
el.classList.add('active');
}
})
.active {
font-size: 70px;
}
<nav>
<div class="container">
<a href="#">
<h3> AMANI DEV </h3>
</a>
<ul id="myNav">
<li><a class="active" href="#home">Home</a></li>
<li>About</li>
<li>Skills</li>
<li>Services </li>
<li>Portfolio </li>
<li>Contact Me </li>
</ul>
</div>
</nav>
// selecting all a element on the page
const links = document.querySelectorAll('a');
// adding a click event on all elements
links.forEach((link) => {
link.addEventListener('click', (e) => {
// if we click first thing is deleting the active class from all link
links.forEach((link) => {
link.classList.remove('active')
})
// then in the end add the active class only in the correct one
e.target.classList.add('active')
})
})

How can I active link in Navigation Bar when I click any item located in that bar?

I have a problem about changing the class attribute as active when I click any selected item in the navigation bar.
I wrote this js code which is shown below to implement this process but it didn't work.
Here is my HeaderPartialView part.
.... css files
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Here is my _Layout.cshtml part.
....
#{
Html.RenderAction("HeaderPartial", "Home");
}
#{
Html.RenderAction("NavbarPartial", "Home");
}
....
#{
Html.RenderAction("JSFilesPartial", "Home");
}
Here is my JSFilesPartial files.
<script src="~/Content/SiteLayout/assets/js/navigation-bar.js"></script>
Here is my navigation-bar.js file.
$(document).ready(function () {
var current = location.pathname;
$('.navigation-bar li a').each(function(){
var $this = $(this);
if($this.attr('href').indexOf(current) !== -1){
$this.addClass('active');
}
})
});
Here is NavbarPartial file.
<nav id="navbar" class="navbar">
<ul class="navigation-bar">
<li><a class="active" href="/Home/Index">Home</a></li>
<li>About Us</li>
<li>Projects</li>
</ul>
<i class="bi bi-list mobile-nav-toggle"></i>
</nav><!-- .navbar -->
How can I fix the issue?
$(document).ready(() => {
$(".somClass li a").on('click', (e) => {
$(".somClass li a").removeClass('active');
$(e.target).addClass('active');
});
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="somClass">
<li><a class="active" href="#">link 1</a></li>
<li>link 2</li>
<li>link 3</li>
</ul>
Since you have active class as prop of anchor element you should try with .navigation-bar li a instead
You're adding the active class on the li element. It should be adding to the a element instead. The following should work:
<script type="text/javascript">
$(document).ready(function () {
$(".navigation-bar li a").on("click", function () {
$(".navigation-bar li a").removeClass("active");
$(this).addClass("active");
});
});
</script>
But it will fail because you're switching pages, and the javascript is reloaded every time you click in a anchor element.
I think this is what you're looking for:
var current = location.pathname;
$('.navigation-bar li a').each(function(){
var $this = $(this);
if($this.attr('href').indexOf(current) !== -1){
$this.addClass('active');
}
})
It basically searches with navigation element is currently active, adding the active class on the a element.
Here is the solution:
Navbar
<nav id="navbar" class="navbar">
<ul class="navigation-bar">
<li>AnaSayfa</li>
<li>Hakkımızda</li>
<li>Hizmetler</li>
<li>Portfolio</li>
<li>Blog</li>
<li>Biz Kimiz</li>
<li>Bize Ulaşın</li>
</ul>
<i class="bi bi-list mobile-nav-toggle"></i>
</nav><!-- .navbar -->
Js file
$(document).ready(function () {
var current = location.pathname;
$('.navigation-bar li a').each(function () {
var $this = $(this);
if($this.attr('href').indexOf(current) !== -1){
$this.addClass('active');
}
})
});

jQuery or JavaScript menu drop down on click

Right now, I'm trying to build a vertical menu that will have a drop down sub menu below it.
Below is my HTML and the jQuery function I am using:
$(function() {
$('#menusomething > li').click(function(e) {
e.stopPropagation();
var $el = $('ul', this);
$('#menusomething > li > ul').not($el).slideUp();
$el.stop(true, true).slideToggle(400);
});
$('#menusomething > li > ul > li').click(function(e) {
e.stopImmediatePropagation();
});
});
<div id="navmenu">
<ul id="menusomething" style="padding-left:30px">
<li>HOME</li>
<li>ABOUT</li>
<li>CHAPTERS</li>
<ul class="submenu">
<li>Dallas</li>
<li>Los Angeles</li>
<li>New York</li>
<li>Northern California</li>
<li>Orange County</li>
<li>Phoenix</li>
<li>San Diego</li>
<li>Washington DC</li>
</ul>
<li>MEMBER SERVICES</li>
Figured out the answer for anyone who sees this. First had to move the closing li tag from chapters to the end of .submenu Then used this and now it works as wanted.
$(function() {
$('#menusomething li > .submenu').parent().click(function() {
var submenu = $(this).children('.submenu');
if ( $(submenu).is(':hidden') ) {
$(submenu).slideDown(400);
} else {
$(submenu).slideUp(400);
}
});
});
The following code does what I believe you desire: Have a <ul> element that is the nextElementSibling of the first level <li> element slide open and closed when it is clicked. As you mentioned in comments that you desired, it now starts closed due to adding style="display: none;" to the <ul>.
Note: From a user interface perspective, the <li> entries which don't have sub-menus, or are otherwise links, should not have the text enclosed in <a> tags. With the <a> tags the user will think they are clickable, when a click does nothing. This is confusing to a user. It appears that you may have some be sub-menus and some be direct links. If possible, there should be some visual difference between the two types to hint to the user as to what will happen when they click.
Along with other issues, your HTML has nothing that will match either the '#menusomething > li > ul' or the '#menusomething > li > ul > li' selectors. Specifically, you have no <UL> elements that are children of <LI> elements.
$(function() {
$('#menusomething > li').click(function(e) {
e.stopPropagation();
var nextSib = this.nextElementSibling;
if(nextSib && nextSib.nodeName === 'UL') {
//If we get here the nextSib exists and is a <UL> that immediately follows
// the <LI> which was clicked.
$(nextSib).slideToggle(400);
}
});
$('#menusomething > ul > li').click(function(e) {
console.log('Clicked on chapter: ' + this.textContent);
e.stopImmediatePropagation();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="navmenu">
<ul id="menusomething" style="padding-left:30px">
<li>HOME</li>
<li>ABOUT</li>
<li>CHAPTERS</li>
<ul class="submenu" style="display: none;">
<li>Dallas</li>
<li>Los Angeles</li>
<li>New York</li>
<li>Northern California</li>
<li>Orange County</li>
<li>Phoenix</li>
<li>San Diego</li>
<li>Washington DC</li>
</ul>
<li>MEMBER SERVICES</li>
</ul>
</div>

how to make this slide menu work

Example: https://jsfiddle.net/lmgonzalves/xj6a74jy/1/
Result: I would like to make a slideUp + slideDown menu the has multiple levels.
I'm stuck trying to get this slide menu to work and I'm not sure how about to get it to work. I've tried using "height"0px" on some css when clicked but ultimately I get back to the same problem. I can make it through the first click in making the slide menu work (meaning there is a slideUp and slideDown), but any level after that the slider just slides up and not down leaving me with no visible menu. Here is what I have:
$('.mobile-nav .navigation a').on('click',function(e){
e.preventDefault();
var t = $(this);
var active = t.closest('li.active');
active.children('ul,a, li.back').not(t.closest('ul')).slideUp();
t.next('ul').slideDown();
});
.mobile-nav .navigation {background:#eee; width:250px; position:relative;}
.mobile-nav .navigation ul {margin:0; padding:0;}
.mobile-nav .navigation a {display:block; line-height:30px;}
.mobile-nav .navigation li ul {display:none;}
<div class="mobile-nav">
<div class="navigation">
<ul>
<li class="active">
All
<ul style="display:block;">
<li>
Topic 1
<ul>
<li class="back">Back</li>
<li>
Some Topic
<ul>
<li class="back">Back</li>
<li>
Some Topic1
((( the menu keeps getting repeated here going deeper, using the format of BackTopic 1Topic 1Topic2 with varying number of li's in each ul.
So the first ul looks like this:
<div class="mobile-nav">
<div class="navigation">
<ul>
<li class="active">
All
</li>
</ul>
/* With 3 more ul's and li's in each
<ul></ul>
<ul></ul>
<ul></ul>
</div>
</div>
When I click on one of the a href tag's, the menu slides to the next level showing the ul, which is the 2nd ul. But when I click on any of the li a's within this ul, I can see the menu start to slide down, but at the same time, the entire ul slides up showing nothing. The ul that was opened now is display:none; even though the next ul is now showing block. I can't figure out how to keep the slides going as they were in the first click.
I can redo classes and such if there is a better way to make this happen.
Fiddled something for you: Fiddle
Hope this is what you need. Just changed the way of selecting the elements.
(function ($) {
"use strict";
$('.mobile-nav')
.on('click', 'a', function (e) {
var $cTarget = $(e.currentTarget),
$dropdown = $cTarget.next('ul'),
$parentUl = $cTarget.closest('ul'),
$activeElem = $parentUl.find('ul.active');
$parentUl.children('li').each(function (key, elem) {
var $elem = $(elem);
if(!$cTarget.parent('li').is($elem)) {
$elem.slideUp();
}
});
$activeElem.toggleClass('active').slideUp();
if (!$dropdown.is($activeElem)) {
$dropdown.toggleClass('active').slideDown();
}
})
.on('click', '.back', function (e) {
var $cTarget = $(e.currentTarget),
$dropdown = $cTarget.closest('ul');
$dropdown.toggleClass('active').slideUp();
$cTarget.parents('li').first().siblings().slideDown();
});})(jQuery);
So these answers are going to be pretty close to each other, but I haven't seen one that meets your "only one item can be open at a time criteria." The JQuery is a little verbose if you want to stick with slipeUp and slideDown but here's an example of the code for handling it for the top-level unordered lists:
$('.toplevel > span').click(function () {
if ($(this).parent().hasClass('activeTop')) {
$('.activeTop').removeClass('activeTop');
$(this).parent().children('ul').slideUp();
return;
}
$('.activeTop').children('ul').slideUp();
$('.activeTop').removeClass('activeTop');
$(this).parent().addClass('activeTop');
$('.activeTop').children('ul').slideDown();
});
I replaced the a tags with spans (and cleaned up the HTML a bit) so I didn't have to deal with my demo fiddle navigating away, but here's a demo implementing the behavior for both top- and second-level menu items.
Check out this fiddle, I would make your structure a little simpler like this https://jsfiddle.net/jk90pxgt/1/ and then your jQuery is only a couple of lines. You can obviously add back buttons if you would like and styling is up to you but this is just a much cleaner way to do the slide menu. Also don't use links and prevent the default, it is just extra code. Just do your click function on the LI
Here is the jQuery
$(".mobile-menu li").click(function(e){
e.stopPropagation();
$(this).children(".sub-menu").slideToggle();
});
New HTML Structure
<ul class="mobile-menu">
<li>First Item
<ul class="sub-menu">
<li>First Sub-Item
<ul class="sub-menu">
<li>First Sub-Item</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Item
<ul class="sub-menu">
<li>First Sub-Item
<ul class="sub-menu">
<li>First Sub-Item
<ul class="sub-menu">
<li>First Sub-Item</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Third Item</li>
</ul>
And CSS
.sub-menu {
display:none;
}
li {
cursor:pointer;
}
Here is how I was able to make this work:
$('.mobile-nav .navigation a').on('click',function(e){
var t = $(this), li = t.closest('li'), ul = li.closest('ul'), a = ul.siblings('a');
if(li.hasClass('back')) {
e.preventDefault();
//do back code here
var sib = ul.closest('li').siblings('li');
a = ul.parents('ul').eq(0).siblings('a');
ul.slideUp();
sib.add(a).slideDown();
} else if(t.siblings().length > 0) {
e.preventDefault();
li.siblings('li').add(a).slideUp();
t.next('ul').slideDown();
}
});

Responsive menu show and hide on click

I trying to write a responsive menu. It's actually works but I can't get the on clik effect in CSS. For this moment I'm using a hover. How to make that when the screen width is lower than 750px I have to click on menu from pic. number 2 (ul) to show menu from pic. number 3 (li) ? This is a one page site so when I clik on some element from drop down menu it's should hide menu agin (li).
HTML:
<header>
<nav id="menu">
<ul>
<li class="li">WITAJ</li>
<li class="li">O MNIE</li>
<li class="li">DOŚWIADCZENIE</li>
<li class="li">CO ROBIĘ?</li>
<li class="li">KONTAKT</li>
<li>MOJE PRACE</li
></ul>
</nav>
</header>
CSS:
#media screen and (max-width: 750px) {
header nav#menu ul:hover > li{
display:block !important;
}
header nav#menu ul li{
display:none !important;
}
}
You cannot achieve a click effect in CSS. It is common to use JavaScript for that.
This is an easy jQuery solution:
$(function() {
var menuVisible = false;
$('#menuBtn').click(function() {
if (menuVisible) {
$('#myMenu').css({'display':'none'});
menuVisible = false;
return;
}
$('#myMenu').css({'display':'block'});
menuVisible = true;
});
$('#myMenu').click(function() {
$(this).css({'display':'none'});
menuVisible = false;
});
});
It also hides the menu, after the user clicked on an entry.
In CSS, you have to force the menu to be visible or not by using media queries. Here an example: sfplex
This is the HTML structure of this example:
<div id="menuBtn">click me</div>
<nav id="myMenu">
<ul>
<li>entry 1</li>
<li>entry 2</li>
<li>entry 3</li>
<li>entry 4</li>
</ul>
</nav>
See the working example in jsFiddle.
How about something like this:
$('#menu').on('click', function(){
$('#menu ul').css("display", "block");
});
$('#menu a').on('click', function(){
$('#menu ul').css("display", "none");
});
What about using JavaScript for this purpose like this:
$(document).ready(function(){
$("#floor").click(function(){
$("#floor_panel").slideToggle("slow");
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="floor">FLOOR ▾ </div>
<div id="floor_panel">
<form name="floor" action="{{ url_for('select_work', url='Floor') }}" method="post">
{{ floor.name }}
<div id="choose"><input type="submit" value="Choose"></div>
</form>
</div>
</div>
It displays panel floor and by pressing it - panel floor_panel will slide.

Categories