Reputation: 816
I have a dropdown menu that I have created using CSS and jQuery that I am trying to make dropdown either on on hover and on click.
By default I want the dropdown to be displayed on click, but given the class .dropdown-hover
I want it to be displayed when hovered over.
Here is a JSFiddle of what I currently have: http://jsfiddle.net/dR8hL/1/
Right now, no matter what class is applied to the dropdown it is displayed on hover and I am unsure of how to fix that.
HTML
<div class="dropdown dropdown-hover">Dropdown on hover
<ul class="dropdown-menu">
<li><a href="#">Profile</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Log out</a></li>
</ul>
</div>
<div class="dropdown">Dropdown on click
<ul class="dropdown-menu">
<li><a href="#">Profile</a></li>
<li><a href="#">Settings</a></li>
<li><a href="#">Log out</a></li>
</ul>
</div>
CSS
.dropdown {
cursor: pointer;
outline: none;
position: relative;
width: auto;
}
.dropdown .dropdown-menu {
background-color: #fff;
border: 1px solid #eee;
border-radius: inherit;
font-weight: inherit;
left: 0;
margin-left: 0px;
opacity: 0;
pointer-events: none;
position: absolute;
right: 0;
text-transform: none;
width: 200px;
z-index: 99999;
-webkit-transition: all 0.3s ease-in;
-moz-transition: all 0.3s ease-in;
-ms-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
transition: all 0.3s ease-in;
}
.dropdown .dropdown-menu a { text-decoration: none; }
.dropdown .dropdown-menu p {
margin: 0;
padding: 10px 15px;
}
.dropdown .dropdown-menu span { line-height: inherit; }
.dropdown ul.dropdown-menu { list-style-type: none; }
.dropdown .dropdown-menu li {
display: block;
padding: 5px 10px;
}
.dropdown .dropdown-menu li:hover { background-color: #f3f8f8; }
.dropdown.dropdown-active .dropdown-menu {
opacity: 1;
pointer-events: auto;
}
jQuery
function DropDown(el) {
this.dd = el;
this.initEvents();
}
DropDown.prototype = {
initEvents: function () {
var obj = this;
// Determine if dropdown is on hover or on click
if ($(".dropdown").hasClass("dropdown-hover")) {
// Toggle .dropdown-active on hover
$(".dropdown").mouseenter(function (event) {
$(this).addClass("dropdown-active");
event.stopPropagation();
});
$(".dropdown-menu").mouseleave(function () {
$(".dropdown").removeClass("dropdown-active");
});
} else {
// Toggle .dropdown-active on click
obj.dd.on('click', function (event) {
$(this).toggleClass('dropdown-active');
event.stopPropagation();
});
}
}
}
$(function () {
var dd = new DropDown($('.dropdown'));
$(document).click(function () {
// Remove class from all dropdowns
$('.dropdown').removeClass('dropdown-active');
});
});
Upvotes: 1
Views: 5426
Reputation: 2312
You can implement this via simple CSS & little bit of JS -
WORKING DEMO - http://codepen.io/nitishdhar/pen/rpqct
HTML Snippet to Use
<ul class="drop">
<li>Dropdown on Hover
<ul>
<li>Profile</li>
<li>Settings</li>
<li>Log out</li>
</ul>
</li>
</ul>
<ul class="drop-on-click">
<li>Dropdown on Click
<ul>
<li>Profile</li>
<li>Settings</li>
<li>Log out</li>
</ul>
</li>
</ul>
You need to assign the class 'drop' to the menu that should open on hover. Also, assign just the class 'drop-on-click' to the one that you want to open on click.
Important CSS
ul li ul {
padding: 0;
position: absolute;
top: 48px;
left: 0;
width: 150px;
display: none;
opacity: 0;
visibility: hidden;
}
ul.drop li:hover ul {
display: block;
opacity: 1;
visibility: visible;
}
There is more CSS in the demo link but that mostly handles the UI aspects.
Now the JS that handles the click scenario -
$(document).ready(function() {
$('.drop-on-click').click(function(){
$(this).toggleClass('drop');
});
$('.drop-on-click ul li').hover(
function() {
$('.drop-on-click').addClass('drop');
}, function() {
$('.drop-on-click').removeClass('drop');
}
);
});
So basically the JS is adding the already handled class 'drop' that will give the menu the property to dropdown as per the written CSS. Now when we move over the dropped down menu, we need to retain the drop class until we are over the li elements, once we move out, we remove the class.
Upvotes: 1
Reputation: 398
Could you not just target the .dropdown-hover class. You shouldn't need the if statement
$(".dropdown-hover").mouseenter(function (event) {
event.stopPropagation();
$(this).addClass("dropdown-active");
});
$(".dropdown-hover").mouseleave(function () {
$(".dropdown").removeClass("dropdown-active");
});
// Toggle .dropdown-active on click
obj.dd.on('click', function (event) {
event.stopPropagation();
$(this).toggleClass('dropdown-active');
});
Updated JSFiddle http://jsfiddle.net/47mSS/
Upvotes: 3