Activate dropdown with pure javascript - javascript

Right now I have a pure HTML CSS navigation bar with some dropdowns. However on ipad the hover will obviously not work.
I want to add a click event to the relevant menu items so the dropdown will also activate with an onclick event.
I've look at other answers but I'm not capable of reading javascript well enough so that I can modify them for my specific site.
here is a link to where I'm at now: http://2ftrade.nl/kareem/eindopdracht/
and this is the relevant html. In my css the default is display:none for the dropdown menus and is changed to display:block when hovered over the li that contains it.
<ul>
<li>Home</li>
<li><a title="">Opleiding</a>
<!-- the dropdown -->
<ul>
<li>Visie & Beleid</li>
<li>Opbouw Studieprogramma</li>
<li>Competenties</li>
<li>Diploma</li>
<li>Beroepen</li>
</ul>
</li>
<li>Onderwijsprogramma</li>
<li>Organisatie</li>
<li><a title="">Stages en Projecten</a>
<!-- another dropdown -->
<ul>
<li>Stages</li>
<li>Projecten</li>
</ul>
</li>
<li>Top</li>
</ul>
This is the css that hides the dropdown section
nav > ul > li > ul {
display: none;
position: absolute;
}
and this is what will display it when hovering
nav > ul > li:hover ul {
display: block;
}

you can attach event listener to your element:
var dropdown_button = document.getElementById('#your-button-that-activates-dropdown');
dropdown_button.addEventListener('click', function() {
//here do what you want to do when the button is clicked.
}, false);

you should use javascript events , some thing like this :
var btn = document.getElementById('btn') // this button is a key to run what you want
var drp = document.getElementById('drp') // this is your dropdown list
btn.onclick = function()
{
drp.style.display = 'block'
// other codes . . .
}

You can achieve this without using javascript.
Use the :target selector
example
Add an id and href for each target in the html
<ul>
<li>Home</li>
<li id="Opleiding">
<a title="" href="#Opleiding">Opleiding</a>
<!-- the dropdown -->
<ul>
<li>Visie & Beleid</li>
<li>Opbouw Studieprogramma</li>
<li>Competenties</li>
<li>Diploma</li>
<li>Beroepen</li>
</ul>
</li>
<li>Onderwijsprogramma</li>
<li>Organisatie</li>
<li id="StagesenProjecten">
Stages en Projecten
<!-- another dropdown -->
<ul>
<li>Stages</li>
<li>Projecten</li>
</ul>
</li>
<li>Top</li>
</ul>
in the css specify the style for the :target
nav > ul > li:target ul {
display: block;
}
nav > ul > li:hover ul {
display: block;
}
nav > ul > li > ul {
display: none;
position: absolute;
}

Related

jQuery on click, add class but also remove if the class is already present

I have a nav menu that needs to trigger with clicks rather than hovers. When the links are clicked, an .open class would be added to the parent li. If that parent already has the .open class, then it would get removed. It would also be removed if another link is clicked on. So far I can get the class added when clicked and removed when a sibling is clicked, but not removed when it's already .open.
I tried adding a hasClass conditional, but that didn't work either. Seemed like it reruns the function every time it's clicked and therefore ignores the hasClass conditional.
Can anyone provide help? I tried toggleClass, but that didn't work.
$('li a').on('click', function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
To do what you require you can use toggleClass() on the parent li when the element is clicked. To remove the class from all other li elements you can use removeClass() along with not() to exclude the current li. Try this:
$('li a').on('click', function() {
let $li = $(this).parent().toggleClass('open');
$('li').not($li).removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
You can use
jquery toggleClass() to toggle yellow highlight (.open css class) on click/unclicking the same link.
jquery siblings() to remove .open class on all the other li items.
Below is the link for the demo
https://jsfiddle.net/so1u8hq6/
$('li a').on('click', function() {
$(this).parent().siblings().removeClass('open');
$(this).parent().toggleClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
</nav>
Late to the party, but, after seeing the provided answers and some of the CSS you use I had to urge with my suggestions:
UX. Avoid styling LI tags in general, or at least set the desired display and move on. Style directly the a tag (with the necessary paddings etc.). You'll not only get less CSS to take care of, but also a larger touch interaction area. Makes no sense to style something yellow if it's not a UI part of something interactable. Also in JS, you don't need to take care about the LI wrappers any more - but only about the actual A Elements.
Don't use common selectors like $('li a') - those might target any LI→A elements in your app. Instead be more specific and use a Class like i.e: .tabs for the parent UL. Both in CSS and JS.
Try to use Event Delegation (in jQuey using the .on() method). Not only it will help you to catch the Event.delegateTarget parent UL where needed, but also the this (the clicked element), but mainly reference all the "group" of a elements enclosed in the common parent. That way you can have as many .tabs in a single page as you like. And yes, thanks to Event delegation you can even add dynamically LI Elements - and your JS will still work as expected.
Since you're using <a href="#"> Anchor elements, instead of (more properly) <button type="button>" Elements, you need to also use Event.preventDefault() in order to prevent the browser its default behavior and that's to follow anchors (scroll the page, navigate, etc...)
Use the selector "a.open" when you want to target and remove the "open" class. By just using "a" (or in other answers on this page - "li") you're uselessly touching elements trying to remove a class that's not there in the first place.
Finally, here's the CSS retouch and the proper jQuery needed for your task:
$(".tabs").on("click", "a", function(ev) {
ev.preventDefault();
$("a.open", ev.delegateTarget).not(this).removeClass("open");
$(this).toggleClass("open");
});
.tabs {
display: flex;
list-style: none;
padding: 0;
}
/* Style your Anchors, not the dummy LI wrappers */
.tabs a { padding: 10px; }
.tabs a.open { background-color: yellow; }
<ul class="tabs">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
To explain the only complicated line:
$(
"a.open", // Target just the ones (if any) of class "open"
ev.delegateTarget // inside the common ".tabs" ancestor
)
.not(this) // ... not the clicked element (since later we'll use .toggleClass on it)
.removeClass("open"); // ... remove that class "open"
the rest is pretty self explanatory.
Further read:
jQuery Event Delegation
jQuery event.delegateTarget
Event.preventDefault
So you only want the yellow background to appear as a signifier of user interaction rather than for the background color to be displayed? Have you tried using the mousedown/mouseup functions instead of .on('click', function(){...}?
I was able to simulate the click event where the color showcases via this method:
$('li a').mousedown(function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
$('li a').mouseup(function() {
$('li a').parent().removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>

Multiple dropdown navigation - how to change the trigger button

I am struggling with one of my dropdowns.
Currently it is set up to be triggered by an i tag to drop down the sub menu.
$('nav li i').click(function() {
I want to change it to (nav li a) so it is not the icon that has to be pressed
I also have the code:
var child = $(this).index('nav ul li i');
but i am not sure what to change this to?
You can see all the code in jsfiddle.
http://jsfiddle.net/susannalarsen/VNYAx/
Since I do not see the <a> element anywhere, I have changed the <i> to <a> for demonstration purposes. You can see the example on http://jsfiddle.net/VNYAx/3/
Basically I changed
$('nav li i').click(function() {
to
$('nav li a').click(function() {
And also
var child = $(this).index('nav ul li i');
to
var child = $(this).index('nav ul li a');
Is this what you need?
Instead of using the index of the icon as a way to identify which dropdown you want to slide down, you can save a reference to that dropdown by searching for '.dropdown' within the element clicked.
$('nav li').click(function () {
var $childDropdown = $(this).find('.dropdown');
if ($childDropdown.is(':visible')) {
$('.dropdown').slideUp(300);
} else {
$('.dropdown').slideUp(300);
$childDropdown.slideDown(300);
}
});
http://jsfiddle.net/9Fk7j/2/
Just an alternative approach to this problem using .slideToggle(). If you need anything explaining please comment and I will edit the answer. I have commented the JavaScript below. I also removed the extra <div> in the markup as the nested <ul> is a perfectly good container.
Demo
HTML
<nav id="moo">
<ul>
<li>Item A
<ul>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</li>
<li>Item B
<ul>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
</li>
</ul>
</nav>
CSS
ul {
padding: 0;
margin: 0;
}
li {
display: inline;
}
nav li {
position: relative;
}
ul ul {
display: none;
position: absolute;
border:1px solid #ccc;
padding: 10px;
}
ul ul li {
display: block;
}
JavaScript
var $allSubMenus = $('ul ul'); // handle to all submenus
$('nav li a').click(function (e) {
var $li = $(this).closest('li'); // get parent <li> of the <a> clicked on
var $subMenu = $li.find('ul'); // get our submenu
$allSubMenus.not($subMenu).slideUp(300); // hide all other submenus
$subMenu.slideToggle(300); // show our submenu
e.stopPropagation(); // stop event bubbling further
});
$(document).click(function () {
$allSubMenus.hide(); // no need to reselect, just use handle
});

How to cancel a CSS style set by 'hover child' selector on event?

I am making a CSS based menu, with submenu items that pop up when the root element is hovered. the problem I have is that I want the CSS menu to close when I click an item in the list, but at that point I am still technically hovering over the top element, so I figured I had to use javascript to hide the menu. But when I set the display property, I set it forever and it overrides the hover selector of the parent node. And so the submenu doesn't show up anymore.
This must be pretty common, but I can't find any answers...
Any help much appreciated!
html:
<ul class="level1">
<li>one
<ul class="level2">
<li id="test">two</li>
<li>three</li>
</ul>
</li>
</ul>
css:
.level1 li:hover > ul {
display: inline;
}
.level2 {
display: none;
}
js:
document
.getElementById('test')
.addEventListener('click',function () {
this.parentNode.style.display = 'none';
// After this the menu doesn't open anymore
// because the style is overriden
});
Here's the jsfiddle
You can try this.
<ul class="level1">
<li class="hoverMe">one
<ul class="level2">
<li id="test">two</li>
<li>three</li>
</ul>
</li>
</ul>
.hoverMe:hover > ul {
display: inline;
}
var test = document.getElementById('test');
test.onclick = function () {
this.parentNode.parentNode.className = "";
};
var level1 = document.getElementsByClassName('level1')[0];
level1.getElementsByTagName("li")[0].onmouseover = function () {
if (this.className != "hoverMe") {
this.className = "hoverMe";
}
};

Remember menu state on reload

I want to create a navigation menu with the exact same functionality as the one on this site: http://www.rex-ny.com/
I would prefer to do it only using HTML and CSS, but I tried all day and couldn't find a solution.
When I select a menu item, I want that menu to stay open after the page loads. Is this possible?
I want to also make the Main menu items clickable, so that they load a new page AND when that page loads that menu is open.
Here is what I have so far:
http://jsfiddle.net/MEL9d/
Here is the jquery:
$(document).ready(function () {
$('#menu > li > a').click(function(){
if ($(this).attr('class') != 'active'){
$('#menu li ul').hide();
$(this).next().toggle();
$('#menu li a').removeClass('active');
$(this).addClass('active');
}
});
});
And CSS:
#menu {
float: left;
}
#menu li a {
display: block;
}
#menu li ul {
display: none;
}
You can do this is plain HTML and CSS. Assuming you have a structure like this:
- site
+ css
+ js
index.html
about.html
You can add a class to the body of each page, so index for index.php and about for about.php:
<body class="about">
Then in your menu, add an id (or a class if you plan on having the menu in many places) to each item that corresponds to the page:
<ul id="menu">
<li id="index" class="active"><a href="index.html"></li>
<li id="about"><a href="about.html"></li>
</ul>
Finally, using CSS you can style the menu items for each page specifically:
.index #index,
.about #about,
#menu .active {
// styles for active item
}

How to make sub links appear when mouse upon a link

I have placed my code in http://jsfiddle.net/ChvjL/4/
While the mouse pointer is upon Link1 then the sub links link1a, link1b, link1c should appear.
Similarly for Link2 also.
Can anyone help me in resolving this
Thanks in advance
Amith
Here is an idea how it should be in your case:
html
<ul>
<li>Link1
<ul>
<li>Link1a</li>
<li>Link1b</li>
<li>Link1c</li>
</ul>
</li>
<li>Link2
<ul>
<li>Link2a</li>
<li>Link2b</li>
<li>Link2c</li>
</ul>
</li>
</ul>
Css
ul > li { width:100px; float:left; }
ul > li > ul { display:none; }
ul > li:hover > ul { display:block; }
ul > li > ul { padding-left:10px; }
Code http://jsfiddle.net/ChvjL/10/
Are you trying to say that when a person hovers at the link given, another link will be shown?
You can refer to this example. It's similar. You just need change the content:
http://www.dynamicdrive.com/style/csslibrary/item/css-image-gallery/

Categories

Resources