convert CSS Hover to JS onClick for Dropdown Menu? - javascript

I want to create a simple dropdown menu when a user clicks on an image. Currently I'm using CSS hover but it doesn't stay so I want to convert it to a JS onClick function.
<html>
<head>
<style>
ul {
text-align: left;
display: inline;
margin: 0;
list-style: none;
}
ul li {
display: inline-block;
position: relative;
}
ul li ul {
padding: 0;
position: absolute;
display: none;
opacity: 0;
visibility: hidden;
}
ul li ul li {
display: block;
}
ul li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
</style></head><body>
<ul>
<li>
<img src="https://cdn1.iconfinder.com/data/icons/thincons/100/menu-128.png" width="20px;" height="18px;"/>
<ul class="lang">
<li>Web Design</li>
<li>Web Development</li>
<li>Illustrations</li>
</ul>
</li>
</ul>
</body>
</html>

With a little jQuery, we can easily toggle a class on or off to represent 'showing' the menu:
$("#menu").click(function(){
$(this).toggleClass("activated");
});
And changing the CSS (instead of :hover) to:
ul li.activated ul {
display: block;
opacity: 1;
visibility: visible;
}
The HTML only needs that first li element to have an id, which lets us use jQuery to bind a click event to it.
<ul>
<li id="menu">
You can see it all in action on this fiddle.
Edit: For a non-jQuery solution, you can use the following Javascript code:
var myEl = document.getElementById('menu');
myEl.addEventListener('click', function() {
this.classList.toggle('activated');
}, false);

Related

How to stop :hover and have onClick on navigation sub menu

I am trying to make a responsive navigation on my Wordpress site where I am building a template from scratch. I have decent experience with HTML and CSS(SCSS) some PHP but not so much Javascript or the Wordpress way.
I am looking to remove the :hover element on my sub menu under the 'services' li and instead have it trigger on click on tablet and mobile devices. I understand it will be similar to how I have done the mobile menu button but I am struggling to figure out the best way to do it.
Can anyone give me an idea please? Thanks in advance.
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
header {
height: 128px;
border-bottom: 1px solid #f0f0f0;
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 4000;
background: white;
}
header .nav-container {
max-width: 100em;
margin: auto;
display: flex;
justify-content: space-between;
z-index: 45;
padding: 0 1.5rem;
}
header .nav-container .logo {
width: 14%;
padding-top: 2.8rem;
}
header .nav-container p {
display: none;
}
#media only screen and (max-width: 600px) {
header .nav-container p {
display: flex;
}
}
header .nav-container nav {
padding-top: 2rem;
}
#media only screen and (max-width: 600px) {
header .nav-container nav {
display: none;
}
}
#media only screen and (max-width: 600px) {
header .nav-container nav ul {
flex-direction: column;
display: flex;
}
}
header .nav-container nav ul li {
position: relative;
display: inline-block;
}
header .nav-container nav ul li a {
display: inline-block;
transition: all 0.5s linear;
text-decoration: none;
padding: 16px 10px;
color: #00458B;
}
header .nav-container nav ul li a:hover {
color: #00458B;
}
header .nav-container nav ul li ul {
display: none;
background: white;
position: absolute;
top: 100%;
width: 160px;
padding: 0;
z-index: 500;
}
header .nav-container nav ul li ul li, header .nav-container nav ul li ul a {
width: 100%;
}
header .nav-container nav ul li:hover ul {
display: block;
}
header .nav-container nav ul .menu-item-40 a {
padding: 0;
}
<header>
<div class="nav-container">
<p onclick="myFunction()"> Click</p>
<nav class="nav" role="navigation" id="myDIV">
<ul>
<li class="nav-item">Home
</li>
<li class="nav-item">About us
</li>
<li class="nav-item">Services
<ul class="sub-menu">
<li class="nav-item ">Windows
</li>
<li class="nav-item">Glass
</li>
<li class="nav-item">Doors
</li>
<li class="nav-item">Roofline
</li>
</ul>
</li>
<li class="nav-item">Our Work
</li>
<li class="nav-item">Contact Us
</li>
</ul>
</nav>
</div>
</header>
Wrap it with Media Query so it doesn't work on Mobile and tablet.
header .nav-container nav ul li:hover ul {
display: block;
}
This is only one of many possible solutions, but I think it gives you an idea off how to solve the problem.
First you have to wrap following selector with a media query to disable the hover when your mobile button shows up. In your case it would look like this:
#media only screen and (min-width: 601px) {
header .nav-container nav ul li:hover ul {
display: block;
}
}
To attach the toggle functionality I would suggest to add a js-submenu-toggle class to all a elements which have a submenu as sibling. I prefer to add a js prefix to my classes to mark them as classes that are only used in combination with javascript and have no styling attached to them:
<ul>
...
<li class="nav-item">
Services
<ul class="sub-menu">
...
</ul>
</li>
...
</ul>
For the actual functionality use the toggle function to add and remove an is-active class on click to the submenu element and the matchMedia function to make the toggle functionality only available when your mobile menu button is visible:
document.addEventListener('click', event => {
const element = event.target;
const mediaQuery = window.matchMedia('(max-width: 600px)');
if(element.matches('.js-submenu-toggle') && mediaQuery.matches) {
// Prevents the default behaviour of the `a`-tag with an `href`-attribute
event.preventDefault();
element.nextElementSibling.classList.toggle('is-active');
}
});
The is-active class should look like this:
.is-active {
display: block;
}

How to make a slideshow where the user can use navigation buttons, no timers

I'm trying to create a slideshow for my website, where it doesn't use any timer of a kind because that's what I have right now, but I want the user to be able to use the navigational buttons. I've been trying to google it but everything I come across seems really complex and I can't get a hold of it. So was wondering if anyone here would be willing to explain how I would do that.
Here a picture of the situation is and how I'm gonna use it. It's an overlay.
does you website support bootstrap if its is you can use bootstrap Carousel slider.
you can stop auto slide by setting the property
$('.carousel').carousel({
interval: false
});
USE THIS CODE FOR NAVIGATION PANEL WITH DROP DOWN FUNCTION
body
{
/*background: url (whatever you want to use) no-repeat; */
background-size: cover;
font-family: Arial;
color: white
}
ul
{
margin: 0px;
padding: 0px;
list-style: none;
}
ul li
{
float: left;
width: 200px;
height: 40px;
background-color: black;
opacity: .8;
line-height: 40px;
text-align: center;
font-size: 20px;
}
ul li a
{
color: white;
display: block;
}
ul li a:hover
{
background color:green;
}
ul li ul li
{
display: none;
}
ul li:hover ul li
{
display: block;
}
<html>
<link href ='style.css' rel= 'stylesheet' >
<ul>
<li><a>Home</a></li>
<li><a>About</a>
<ul>
<li><a>First</a></li>
<li><a>Second</a></li>
</ul>
</li>
<li><a>Things to do</a>
<ul>
<li><a>First</a></li>
<li><a>Second</a></li>
</ul>
</li>
<li><a>Contact</a>
<ul>
<li><a>First</a></li>
<li><a>Second</a></li>
</ul>
</li>
<li><a>News</a>
<ul>
<li><a>First</a></li>
</ul>
</li>
</html>

css hover to onclick conversation

I was wondering if anyone could help me out. I'm trying to make a simple folio site, and I have this link in the top nav that when clicked on would appear a horizontal menu underneath the header. So far I have goten it to work with just css, but I don't like how the menu appears when hovered, it would look much more professional if it appeared when clicked and stayed there until you click on the same link again. if anyone could help me that'll be great. I've tried all sorts of java tutorials and won't very successful I didn't fully understand it.
<header>
<a class="home" href="../index.htm" title="Home Page"></a>
<a class="to_nav" href="#nav" ></a>
<div class="logo">
<a href="#top">
<h1>Deeran</h1>
<span>Graphic Design</span>
</a>
</div>
<nav>
<ul class="drop">
<li>
<a id="menu"></a>
<ul class="hide">
<li>Portfolio</li>
<li>About</li>
<li>Contact/Hire</li>
</ul>
</li>
</ul>
</nav>
</header>
And here's the css
nav {margin: 0; padding: 0;}
nav ul li a#menu {
display: block;
width: 67px;
height: 50px;
position: absolute;
right: 0px;
top: 0px;
margin-top: 9px;
margin-right: 15px;
margin-bottom: 0px;
margin-left: 15px;
}
nav ul ul.hide {
display: none;
list-style: none;
margin: 10px 0 0;
text-indent: none;
clear: both;
width: 100%;
position: absolute;
left: 0px;
}
nav ul ul.hide li {margin: 0;}
nav ul li:hover > ul {
display: block;
list-style-type: none;
}
if there was one simple way to convert that one :hover function to onClick I would be very grateful :)
make
nav ul li:hover > ul {
display: block;
list-style-type: none;
}
to
nav ul li.active > ul {
display: block;
list-style-type: none;
}
Then use javascript to add a class active onClick.
What makes SO wonderful is that we can refer to similar cases easily :)
For javascript part please refer this answer .
Add/Remove class onclick with JavaScript no librarys
The 'click' event cannot be listened for with css. Remove your :hover rule and add some JavaScript. In the code you provided, you don't have anything in the #menu element for the user to click on, so I added some text for the fiddle.
http://jsfiddle.net/Fc75u/
JavaScript:
var toggle = document.getElementById('menu');
var menu = document.getElementsByClassName('hide');
toggle.addEventListener('click', function(event) {
menu[0].style.display == "block" ? menu[0].style.display = "none" : menu[0].style.display = "block";
});
jQuery:
$('#menu').click(function () {
$('.hide').toggle();
});

How to display a div outside of multi-leveled menu when hovering on sub-level item

I have a menu comprised of HTML and CSS and I'm trying to get it so that once the user hovers over the sub level item within the menu, the div info1 will appear to the right of the menu. Ideally, I would like to do this with HTML and CSS if possible, but if there is a simpler fix with jQuery or JavaScript, that would work too. I would certainly appreciate the help.
Here's the HTML:
<body>
<div id="navigation">
<nav>
<ul class="top-level">
<li>Top-level Item
<ul class="sub-level">
<li>Sub-level Item</li>
<li>Sub-level Item</li>
<li>Sub-level Item</li>
</ul>
</li>
<li>Top-level Item
<ul class="sub-level">
<li>Sub-level Item
<li>Sub-level Item</li>
<li>Sub-level Item</li>
<li>Sub-level Item</li>
</ul>
</li>
</nav>
</div>
<div ID="info1">
<center><img src="image.jpg" border="0" height=170 width=250 ></center><br><center><table BORDER=4 CELLPADDING=6 ><tr><td><br>I want this div to display on the right side of the screen once the mouse has hovered over a sub-level menu item.<br><br></td></tr></table></center>
</div>
</body>
and here's the CSS:
#navigation
{
width: 200px;
font-size: 0.75em;
}
#navigation ul
{
margin: 0px;
padding: 0px;
}
#navigation li
{
list-style: none;
}
ul.top-level li
{
border-bottom: #fff solid;
border-top: #fff solid;
border-width: 1px;
}
#navigation a
{
color: #fff;
cursor: pointer;
display:block;
height:25px;
line-height: 25px;
text-indent: 10px;
text-decoration:none;
width:100%;
}
#navigation li:hover
{
background: #f90;
position: relative;
}
ul.sub-level
{
display: none;
}
li:hover .sub-level
{
background: #999;
border: #fff solid;
border-width: 1px;
display: block;
position: absolute;
left: 200px;
top: -1px;
}
ul.sub-level li
{
border: none;
float:left;
width:200px;
}
#info1
{
font-family: "Verdana,Arial,Helvetica";
size: -1;
display: none;
}
*/ I thought this might work*/
li:hover .top-level li:hover .sub-level + #info1
{
display: block;
}
The code can be viewed at http://jsfiddle.net/brisket27/C5Pn9/7/
You can not go back or traverse the dom up with CSS. "There are no parent selectors in CSS, not even in CSS3" via CSS-Tricks
You can solve your problem with some basic jquery:
Demo: jsFiddle
$('.top-level li .sub-level li').on('mouseover', function() {
// Position #info1 off to the side of the .sub-level
$('#info1').css({
'top': $(this).parent('.sub-level').position().top,
'left': $(this).parent('.sub-level').position().left + $(this).parent('.sub-level').outerWidth(),
});
$('#info1').show();
}).on('mouseleave', function() {
$('#info1').hide();
});
The current code puts #info1 next to the sub-level. If you want #info1 always on the absolute right side of the screen, remove the position code in the js and just apply right: 0; to #info1 in CSS.
Your approach was in a correct direction. I'll try to explain why this code did not work -
*/ I thought this might work*/
li:hover .top-level li:hover .sub-level + #info1 {
display: block;
}
This is Adjacent sibling combinator, applicable to only the 'Adjacent' siblings.
In your case, div #info1 is outside the nav logic.
Your CSS rule would work if the div you want to display was placed right after the ul li's
for ex.
1) In the following example Divs #one and #two are adjacent.
<div = "one">I</div>
<div = "two">II</div>
but the one mentioned below are not.
<div = "cover">
<div = "one">I</div>
</div>
<div = "two">II</div>
2) As mentioned, here
<ul class="sub-level">
<li>Sub-level Item
</li>
</ul>
<div id="test">HERE IS A DIV</div> <!-- This div is adjacent to ul -->
and a CSS rule, will WORK!
ul.sub-level:hover + #test { /* This works because #test and ul.sub-level are adjacent*/
display: none;
}
Said that, I guess it will be easier for you to go for option like jquery to implement your logic instead of CSS.
$(document).ready(function(){
$('ul.sub-level li').mouseenter(function(){
$('#info1').show();
});
$('ul.sub-level li').mouseleave(function(){
$('#info1').hide();
});
});
Use the following snippet using jquery for the hover effect:
$(".sub-level>li").mouseenter(function() {
$("#info1").show();
}).mouseleave(function() {
$("#info1").hide();
});
To display the block on right of the screen you can use either use:
#info1 {
position: absolute; right:0;
}
or
#info1 {
float:right;
}

Dynamically set width of li to match width of parent ul

I am making a drop-up using li nested in ul but am not able to set the width of li to dynamically match the width of the ul.
Please note that the li elements are constricted within a drop-up list.
The below looks like too much css but in essence it's just about the ul and li.
THE CSS
<style type="text/css" media="screen, tv, projection">
/* - - - ADxMenu: BASIC styles - - - */
/* remove all list stylings
.menu, .menu ul {
margin: 0;
padding: 0;
border: 0;
list-style-type: none;
display: block;
}
*/
.menu li {
margin: 0;
padding: 0;
border: 0;
display: block;
float: left; /* move all main list items into one row, by floating them */
position: relative; /* position each LI, thus creating potential IE.win overlap problem */
z-index: 5; /* thus we need to apply explicit z-index here... */
}
.menu li:hover {
z-index: 10000; /* ...and here. this makes sure active item is always above anything else in the menu */
white-space: normal;/* required to resolve IE7 :hover bug (z-index above is ignored if this is not present)
see http://www.tanfa.co.uk/css/articles/pure-css-popups-bug.asp for other stuff that work */
}
.menu li li {
float: none;/* items of the nested menus are kept on separate lines */
}
.menu ul {
visibility: hidden; /* initially hide all submenus. */
position: absolute;
z-index: 10;
left: 0; /* while hidden, always keep them at the bottom left corner, */
bottom: 0; /* to avoid scrollbars as much as possible */
}
.menu li:hover>ul {
visibility: visible; /* display submenu them on hover */
bottom: 100%; /* 1st level go above their parent item */
}
.menu li li:hover>ul { /* 2nd+ levels go on the right side of the parent item */
bottom: 0;
left: 100%;
}
/* -- float.clear --
force containment of floated LIs inside of UL */
.menu:after, .menu ul:after {
content: ".";
height: 0;
display: block;
visibility: hidden;
overflow: hidden;
clear: both;
}
.menu, .menu ul { /* IE7 float clear: */
min-height: 0;
}
.menu ul ul {
padding: 30px 30px 30px 10px;
margin: 0 0 -30px -10px;
}
/* - - - ADxMenu: DESIGN styles - - - */
.menu, .menu ul li {
color: #eee;
background: #000;
}
.menu ul {
background: #000;
width: 11em;
}
.menu a {
text-decoration: none;
padding: .4em 1em;
display: block;
position: relative;
font-family:BlairMdITCTTMedium;
color:#848484;
font-size:11px;
}
.menu a:hover, .menu li:hover>a {
color: #ccc;
}
.menu li li { /* create borders around each item */
border: 1px solid #000;
}
.menu ul>li + li { /* and remove the top border on all but first item in the list */
border-top: 0;
}
.menu li li:hover>ul { /* inset 2nd+ submenus, to show off overlapping */
bottom: 5px;
left: 90%;
}
/* Fix for IE5/Mac \*//*/
.menu a {
float: left;
}
/* End Fix */
/*]]>*/
</style>
**THE HTML CODE**
<ul class="menu">
<li style="width:80px;">
<a id="menu1" title="View all posts filed under Accessories" href="http://monique-relander.be/objects/accessories/">Accessories</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li style="width:80px;">
<a title="View all posts filed under Furniture" href="http://monique-relander.be/objects/furniture/">Furniture</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li style="width:80px;">
<a title="View all posts filed under Lighting" href="http://monique-relander.be/objects/lighting/">Lighting</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li style="width:80px;">
<a title="View all posts filed under Mirrors" href="http://monique-relander.be/objects/mirrors/">Mirrors</a>
<ul>
<li>Home</li>
<li>Feeds</li>
<li>Archive</li>
</ul>
</li>
<li class="none" style="width:140px;">
<a title="View all posts filed under NEW ARRIVALS" href="http://monique-relander.be/objects/new-arrivals/">New Arrivals</a></li>
<li style="width:130px;">
<a title="View all posts filed under Sold Gallery" href="http://monique-relander.be/objects/sold-gallery/">Sold Gallery</a></li>
<li class="cat-item right">
Contact</li>
</ul>
The width of the li seems to be the same as the ul by default.
Atleast based on my experiments here http://jsfiddle.net/dwCsW/
If you remove the ul width it will be 100%, and by setting ul width the li will follow.
So there must be something else in your code removing that.
You could either give the li's a percentage width in the css... there are 7 of them, right? so maybe make each 10% wide, put 4% between each one and 3% at the beginning and end? Or, you could use JavaScript and detect the page resize event, then get the page/ul width and set the width of each li item using some good ol' fashioned number crunchin'!

Categories