Showing a dropdown on click instead of on hover - javascript

I am using Avada (fusion-theme) theme on Wordpress for my website (under construction).
They have a mega-menu option that I am using, but I would want it to appear when someone clicks on the main-menu item instead of hovering over it.
Site: www.paradigmtek.com
So right now if someone hovers over say "smart home" at the top, the sub menu appears (smart home tech support, smart hub or speaker setup, etc.). But I would like it to appear on click instead of on hover.
I don't think this will require not a simple CSS trick, but a JS one.
Anyone has experience with that theme or know how to do it?

You can simply add a class to change the opacity of the dropdown menu upon clicking one of the menus. In this example below, I'm adding show class to dropdown to change opacity from 0 to 1 upon clicking the menu. At the same time, I'm addding a class to the clicked menu (i.e. clicked) to give it an accent colour to indicate that it is the menu being clicked.
const menus = document.querySelectorAll('.menu')
const dropdown = document.querySelector('.dropdown')
let activeMenu = null
menus.forEach(menu => {
menu.addEventListener('click', e => {
// Removing previous active menu that is not itself
if (activeMenu && activeMenu !== menu) {
activeMenu.classList.remove('clicked')
activeMenu = menu
}
else if (activeMenu && activeMenu === menu) {
activeMenu = null
} else {
activeMenu = menu
}
menu.classList.toggle('clicked')
// If there is an active menu, show
if (activeMenu) dropdown.classList.add('show')
else dropdown.classList.remove('show')
})
})
* {
box-sizing: border-box;
font-family: Helvetica;
}
html,
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.container {
display: flex;
justify-content: center;
background: #121212;
}
.menu {
color: white;
margin: 20px;
padding: 20px;
border-radius: 5px;
cursor: pointer;
}
.menu:hover {
color: #ff8888;
}
.menu.clicked {
color: #ff8888;
}
.dropdown {
width: 100%;
height: 100px;
background: #333333;
display: flex;
flex-direction: column;
opacity: 0;
transition: opacity 0.5s ease;
}
.dropdown.show {
opacity: 1;
}
.line {
width: 100%;
height: 3px;
background: #00a5ff;
}
<div class="container">
<div class="menu">Menu 1</div>
<div class="menu">Menu 2</div>
<div class="menu">Menu 3</div>
<div class="menu">Menu 4</div>
</div>
<div class="dropdown">
<div class="line"></div>
</div>

In the options: avada options -> menu -> submenu
You just have to specify hover / click with the select button.
You can also build your own menu by creating a layout
-> avada -> layout
In your layout you can add a menu element on which you apply the wanted options.
Getting Started With Avada Layouts
Understanding Custom Headers
How To Use The Menu Element

Related

Add Javascript to down ARROW BUTTON to open and close sub menu

I've been trying for hours with this javascript navigation, I've researched many sites, including w3schools, codepen, and css tricks, and many others, I've spent hours reading through stack, and everything has helped a lot, now I'm almost finished, and I need some help making this menu work.
Essentially, it is a sub navigation menu that stays open when you click the down ARROW BUTTON and closes when you click anywhere on the page. Sometimes it works, and sometimes it doesn't.
The menu has two links:
Forum 1 / down ARROW BUTTON and
Forum 2 / down ARROW BUTTON
I can get Forum 1 down ARROW BUTTON to open the subnavigation sometimes, by clicking the down ARROW BUTTON, but I cannot get Forum 2 down ARROW BUTTON to trigger sub navigation at all.
I'm not sure if it is the way I have the css, or what.
I'm providing the full menu with css, html, and javascript,
Like I said, I can get the first down ARROW BUTTON to open the sub navigation sometimes, but that is about it. Can you help me get this working please?
Here is the styling for the navigation menu
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
}
.navbar {
overflow: hidden;
background-color: #18143c;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 7px 14px 16px;
text-decoration: none;
}
.subnav {
float: left;
overflow: auto;
}
.subnav .subnavbtn {
font-size: 16px;
border: none;
outline: none;
color: white;
padding: 14px 5px;
background-color: inherit;
font-family: inherit;
margin: 0;
margin-right:26px;
}
.navbar a:hover, .subnav:hover .subnavbtn {
background-color: #46485c;
}
.subnav-content-1 {
display: none;
position: absolute;
left: 0;
background-color: #46485c;
width: 100%;
z-index: 1;
overflow:auto;
}
.subnav-content-1 a {
float: left;
color: white;
text-decoration: none;
padding: 10px 10px;
}
.subnav-content-1 a:hover {
background-color: #eee;
color: black;
}
.show {display: block;}
Here is the HTML for the navigation menu
<div class="navbar">
Forums 1
<div class="subnav">
<button onclick="myFunction()" class="subnavbtn"><i class="fa fa-caret-down"></i></button>
<div id="myDropdown" class="subnav-content-1">
Test Main
Test link 1
Test link 1
Test link 1
</div>
</div>
Forums 2
<div class="subnav">
<button onclick="myFunction()" class="subnavbtn"><i class="fa fa-caret-down"></i></button>
<div id="myDropdown" class="subnav-content-1">
Test Main
Test link 2
Test link 2
Test link 2
</div>
</div>
</div>
And here is the javascript
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.subnavbtn')) {
var dropdowns = document.getElementsByClassName("subnav-content-1");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
here is a link to the page on W3schools where I've been working on this menu.
https://www.w3schools.com/code/tryit.asp?filename=GC3LUF0TLS6S
What I am trying to do is, get the menu working were, when you click the dropdown ARROW BUTTON, it opens the sub navigation menu, then to close sub navigation, you just click anywhere on the page.
This almost works!! Please help me get it working right.
Hi man I found a fix for you, I don't know if it is what you need but it gets that job done:
First change the id's for each dropdown as they are conflicting when js is called, then call that js function with a the id number of each dropdown:
<div class="navbar">
Forums 1
<div class="subnav">
<button onclick="**myFunction(1)**" class="subnavbtn"><i class="fa fa-caret-down"></i></button>
<div id="**myDropdown1**" class="subnav-content-1">
Test Main
Test link 1
Test link 1
Test link 1
</div>
</div>
Forums 2
<div class="subnav">
<button onclick="**myFunction(2)**" class="subnavbtn"><i class="fa fa-caret-down"></i></button>
<div id="**myDropdown2**" class="subnav-content-1">
Test Main
Test link 2
Test link 2
Test link 2
</div>
</div>
</div>
Then you should add a parameter to you js function to know which dropdown to toggle:
function myFunction(n) {
document.getElementById("myDropdown"+n).classList.toggle("show");
}

Close all open drop downs and consolidate code if possible

What I need to be able to do is to have the text drop downs close when another is selected so that I do not end up with a bunch of drop downs open on the page at the same time.
I have two text dropdowns that will be used one after the other alternating on a page. In other words accordion1, accordion2, accordion1, accordion2 and so on the reason I have accordion1 and accordion2 is that with my limited experience it is the only way I could figure out change the button color so the list could alternate colors. It would be nice to consolidate the code, but I can live with the extra code if need be.
Here is the code for accordion1
var acc = document.getElementsByClassName("accordion1");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
/* Toggle between adding and removing the "active" class,
to highlight the button that controls the panel */
this.classList.toggle("active1");
/* Toggle between hiding and showing the active panel */
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
var acc = document.getElementsByClassName("accordion2");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
/* Toggle between adding and removing the "active" class,
to highlight the button that controls the panel */
this.classList.toggle("active1");
/* Toggle between hiding and showing the active panel */
var panel = this.nextElementSibling;
if (panel.style.display === "block") {
panel.style.display = "none";
} else {
panel.style.display = "block";
}
});
}
.accordion1 {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
.accordion2 {
background-color: #8461E8;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
text-align: left;
border: none;
outline: none;
transition: 0.4s;
}
/* Add a background color to the button if it is clicked on (add the
.active class with JS), and when you move the mouse over it (hover) */
.active1,
.accordion1:hover {
background-color: #ccc;
}
/* Style the accordion panel. Note: hidden by default */
.panel1 {
padding: 0 18px;
background-color: white;
display: none;
overflow: hidden;
}
.accordion1:after {
content: '\02795';
/* Unicode character for "plus" sign (+) */
font-size: 13px;
color: #777;
float: right;
margin-left: 5px;
}
.accordion2:after {
content: '\02795';
/* Unicode character for "plus" sign (+) */
font-size: 13px;
color: #777;
float: right;
margin-left: 5px;
}
.active1:after {
content: "\2796";
/* Unicode character for "minus" sign (-) */
}
<Section><button class="accordion1"><h3>Alternators and regulators</h3>
</button>
<div id="accordion1-div" class="panel1">
<p>First group of words go here></div>
</Section>
<Section><button class="accordion2"><h3>Batteries and Inverters</h3>
</button>
<div id="accordion-div" class="panel1">
<p>Second set of words go here.</p>
</div>
</Section>
<Section><button class="accordion1"><h3>AC and DC Panels </h3>
</button>
<div id="accordian1-div" class="panel1">
<p>Third set of words reusing "accordion1 go here"</p>
</div>
</Section>
Any help or resources to figure out the needed code would be greatly appreciated.
Question 1 — "How do I not end up with a bunch of drop downs open on the page at the same time":
You close all dropdowns before opening another one. You can also create css rules to display or hide the dropdown. This way, it will be easier to find the currently active dropdown. See code below.
Question 2 — "How can I make the list alternate colors"
You can add more than one class to an element. Simply create color classes and add them to the right elements. See code below.
Notes:
Use the CSS selectors instead of JavaScript to show/hide the panel
Element h3 is not allowed as child of element button. Do it the other way round.
Use the same JavaScript code and CSS for all accordions.
Edit (scrollIntoView)
I added code to automatically scroll the window so that the active tab is visible.
It works only on Chrome, Firefox and Opera. Use this polyfill iamdustan/smoothscroll to use it in other browsers. See compatibility here and all functions here.
// Query all accordions
var accordions = document.querySelectorAll('.accordion');
for (var i = 0; i < accordions.length; i++) {
accordions[i].addEventListener('click', function() {
// Get the currently active accordion
var active = document.querySelector('.accordion.active');
// If there is one, deactivate it
if (active) {
active.classList.remove('active');
}
// Activate the new accordion, if it's not the one you just deactivated
if (active !== this) {
this.classList.add('active');
// Use scrollIntoView to adjust the window scroll position to show the content.
this.scrollIntoView({
behavior: 'smooth'
});
}
});
}
.accordion .header button {
text-align: left;
padding: 18px;
background: transparent;
border: none;
outline: none;
cursor: pointer;
width: 100%;
color: #444;
width: 100%;
transition: 0.4s;
}
/* Set the color according to the modifier class */
.accordion.gray button {
background-color: #eee;
}
.accordion.purple button {
background-color: #8461E8;
}
.accordion.active button,
.accordion button:hover {
background-color: #ccc;
}
.accordion .panel {
padding: 0 18px;
background-color: white;
display: none;
overflow: hidden;
}
/* Show the panel if the accordion is active */
.accordion.active .panel {
display: block;
}
.accordion button:after {
content: '\02795';
font-size: 13px;
color: #777;
float: right;
margin-left: 5px;
}
.accordion.active button:after {
content: "\2796";
}
<section>
<!-- Each accordion is wrapped by a div with the class 'accordion' -->
<!-- 'accordion' is the component, 'gray' is the color modifier -->
<div class="accordion gray">
<!-- h3 can contain a button -->
<h3 class="header">
<button>Alternators and regulators</button>
</h3>
<div class="panel">
<p>
First group of words go here.<br/> I'm afraid I just blue myself. No… but I'd like to be asked! Michael! It's called 'taking advantage.' It's what gets you ahead in life. Now, when you do this without getting punched in the chest, you'll have
more fun.
</p>
</div>
</div>
</section>
<section>
<!-- Use the 'purple' modifier class here -->
<div class="accordion purple">
<h3 class="header">
<button>Batteries and Inverters</button>
</h3>
<div class="panel">
<p>
Second set of words go here.<br/> Steve Holt! I don't criticize you! And if you're worried about criticism, sometimes a diet is the best defense. That's why you always leave a note! Well, what do you expect, mother? I don't criticize you! And
if you're worried about criticism, sometimes a diet is the best defense.<br/>
<br/> Across from where? As you may or may not know, Lindsay and I have hit a bit of a rough patch. Now, when you do this without getting punched in the chest, you'll have more fun. No… but I'd like to be asked!
</p>
</div>
</div>
</section>
<section>
<div class="accordion gray">
<h3 class="header">
<button>AC and DC Panels
</button>
</h3>
<div class="panel">
<p>
Third set of words go here.<br/> That's why you always leave a note! Not tricks, Michael, illusions. As you may or may not know, Lindsay and I have hit a bit of a rough patch. It's called 'taking advantage.' It's what gets you ahead in life.<br/>
<br/> Say goodbye to these, because it's the last time! First place chick is hot, but has an attitude, doesn't date magicians. I'm afraid I just blue myself. I'm afraid I just blue myself. I'm afraid I just blue myself.
</p>
</div>
</div>
</section>

On button click display list items, dropdown list should not hide until button is clicked again

I have looked everywhere possible as I am trying to develop a drop down button, but instead of options then the buttons display unordered list items, but when a user click off the button the the button does not close, but in order to close the button, then the button needs to be click again.
Down below you will find the way the button is when not clicked and the way the button appears when it has been clicked.
If you also go to the following website you will see an example of the button in action by click "See our list of websites"
Button on a website for example
Any help would be greatly appreciated and thanks in advance.
Here you go, key functions I used;
.click() for the a tag or the link, the function inside the .click() will be called.
.slideToggle() the ul after the click, this would hide or show the target element depending on its state.
Then add positon:absolute to the ul so that it wouldn't affect inline elements.
$(document).ready(function() {
$(".toggle-button").click(function() {
$(this).parent().find("ul").slideToggle(function() {
// Animation complete.
});
});
})
.links-unordered {
display: inline-block;
position: relative;
}
.links-unordered {
margin-top: 20px;
min-height: 30px;
}
.links-unordered .toggle-button {
text-decoration: none;
padding: 12px 16px 12px 16px;
transition: 0.2s;
border: 1px solid black;
}
.links-unordered .toggle-button:hover,
.links-unordered .toggle-button:active,
.links-unordered .toggle-button:focus,
.links-unordered .toggle-button:visited {
text-decoration: none;
color: black;
}
.links-unordered .toggle-button:hover {
border-width: 2px;
}
.links-unordered ul {
position: absolute;
top: 10px;
margin-top: 25px;
padding-inline-start: 20px;
}
.links-unordered ul li {
line-height: 25px;
padding-left: 15px;
}
.links-unordered a {
text-decoration: none;
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="links-unordered">
<a class="toggle-button" href="#">SEE OUR LIST OF WEBSITES</a>
<ul style="display:none;">
<li>cdn.sc.rockstargames.com</li>
<li>lifeinvader.com</li>
<li>rockstargames.com</li>
<li>socialclub.rockstargames.com</li>
</ul>
</div>
<div class="links-unordered">
<a class="toggle-button" href="#">SEE OUR LIST OF WEBSITES</a>
<ul style="display:none;">
<li>cdn.sc.rockstargames.com</li>
<li>lifeinvader.com</li>
<li>rockstargames.com</li>
<li>socialclub.rockstargames.com</li>
</ul>
</div>
I'm not sure if I understand what you want. But here's a sample of what you asked, a button that when you click, show a list. And when you click on an item, the list goes out and you have the item. Hope this helps you. It's a simple code, but if you have questions, go ahead and ask!!
function closeList(e) {
var site = e.target.innerText;
alert(site + ' clicked!!');
document.querySelector('#dvSites').style.display = 'none';
}
function showList() {
var dvSites = document.querySelector('#dvSites');
if (dvSites.style.display === '')
return; // already visible
dvSites.style.display = '';
}
// Add eventListener to close the div
var lis = document.querySelector('#dvSites').querySelectorAll('li');
for(var i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', closeList);
}
// Add eventListener to open the div
document.querySelector('#btnShow').addEventListener('click', showList);
<button id="btnShow">Show sites!!</button>
<div id="dvSites" style="display: none">
<ul>
<li>stackoverflow.com</li>
<li>www.google.com</li>
<li>www.sipmann.com</li> <!-- :) -->
</ul>
</div>

Use a Click Event to Add and Remove a Class to individual loop items

I want to add a CSS class to a nav menu item each time it's clicked (so i can then style that menu item so people know this is the page they are on). I know I need to loop through the .menu-item class and add / remove a new CSS class using a loop, but I can't seem to get it to play ball.
I'm guessing I need to make the .menu-item the 'this' object and use a boolean to add or remove the CSS class, dependent on whether the currentItem variable is set to true or false.
I can't seem to get this to play though and I'm not 100% sure I'm using the event listener in the correct way.
Any help would be awesome.
codepen: https://codepen.io/emilychews/pen/eeKPoo?editors=1010
JS
var navlinks = document.getElementsByClassName('menu-item')
var currentItem = false;
for (i = 0; i<navlinks.length; i+=1) {
function addCurrentItemToMenu() {
if (currentItem === false) {
navlinks = this
this.classList.add('current-item')
currentItem = true
} else {
this.classList.remove('current-item')
currentItem = false
}
}
}
navlinks.addEventListener("click", function(){
addCurrentItemToMenu()
}, false)
CSS
body, ul {padding: 0; margin: 0}
#main-header {width: 100%; height: 100px;}
#mobile-menu-button {display: none;}
#main-navigation {
position: relative;
width: 100%;
height: 100px;
background: red;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 10px 5% 10px 5%;
align-items: center;
}
ul#nav-menu-items {
display: flex;
margin-left: auto;
}
#main-navigation ul li {list-style-type: none;}
ul#nav-menu-items li a {
padding: 10px 15px;
margin: 0 5px;
box-sizing: border-box;
background: yellow;
text-decoration: none;
color:#000;
}
#main-navigation ul#nav-menu-items li a:hover {
color:blue;
transition: color .25s;
}
HTML
<header id="main-header">
<nav id="main-navigation">
<ul id="nav-menu-items">
<li class="menu-item">News</li>
<li class="menu-item">About</li>
<li class="menu-item">Contact</li>
</ul>
</nav>
</header>
Here is a modified codepen for your problem: https://codepen.io/anon/pen/RjJEWe?editors=1010
The code simply add current-item class to the clicked anchor, so you can style it however you want in css. You can also see event.preventDefault() in the code to prevent anchor from following your link, as it will reload the page and js won't do anything. It depends on the stack that you are using. If you have server backed website, the current link will be handled by the server and html returned will already have the class set appropriately, if you have frontend js framework (Angular, VueJS, ReactJS), you must handle it appropriately.
Just for your example you can see the code below:
var navlinks = document.querySelectorAll('li.menu-item > a');
// Loop through all the links and add event listener
navlinks.forEach(function(item) {
item.addEventListener('click', function(event) {
event.preventDefault();
// Remove the class from all elements
navlinks.forEach(function(item) {
item.classList.remove('current-item');
})
// add the class to the current one
this.classList.add('current-item');
});
});

cannot make list item visible with > CSS selector

I'm unable to make the popups 'redItem', 'blueItem' and 'greenItem' below visible again after setting their display to 'none'. I'm using a CSS selector to get them visible again when the mouse hovers over a node higher up in the nested list to no avail.
Here's the code:
<ul class="popups" style="vertical-align: bottom; padding: 0px; margin: 0px;">
<li style="width: 165px"><a id="topmostBox" href="#">One_high-up_item</a>
<ul class="popups">
<li>First-lower-item
<ul class="popups">
<li name="redItem" >Red</li>
<li name="blueItem">Blue</li>
<li name="greenItem">Green</li>
</ul>
</li>
</ul>
</li>
</ul>
.popups:hover > li {
display: block;
}
.popups {
background-color: white;
font-family: sans-serif;
font-size: 13.5px;
list-style: none;
position: relative;
border: 1px solid lightgray;
border-width: .05em;
border-top-color: rgb(165,165,165);
line-height: 1.2em;
display: inline-table;
}
function setTopColorAndVis(theNestedPopupAnchor)
{
var theColorName = theNestedPopupAnchor.innerHTML;
var topMenuBox = document.getElementById('topmostBox');
topMenuBox.innerHTML = theColorName ;
theNestedPopupAnchor.parentNode.style.display = "none";
}
What happens is this:
1) I select the color 'Red' (the 1st list item)
2) my call to setTopColorAndVis(this) makes the popup disappear (because the user selected an item, the color "Red", and now the popup is not needed for now)
3) but when I later hover the mouse over the "First-lower-item" list item, the child li that has the ul containing 'redItem', 'greenItem', 'blueItem' does not appear.
So my experience here is that I'm successfully able to hide the list items named 'redItem', 'blueItem' and 'greenItem' -- but when I hover over the "First-lower-item", despite my CSS code:
.popups:hover > li {
display: block;
}
The 'redItem', 'greenItem' and 'blueItem' do NOT reappear.
What am I missing here?
The inline style overrides you style in your css code. you should use onmouseover event and onmouseout instead.
Try
<li name="redItem" >Red</li>
function show(elem){
elem.parentNode.style.display = "block";
}
function hide(elem){
elem.parentNode.style.display = "none";
}
You cannot :hover over an element with display:none as it has no size...
instead of working with display, you can work with visibility - which will leave an area to hover over.
like so:
theNestedPopupAnchor.parentNode.style.visibility = 'hidden'
.popups:hover > li {
visibility: visible;
}
http://www.w3schools.com/cssref/pr_class_visibility.asp

Categories

Resources