I want to create a tab and when someone hover on that tab someway below a new ul items should display with fade in and fade out effect. Till now I have used mouseenter and the new diplay items should stay there to choose other options.
HTML
<ul class="sector-nav">
<li>Residential</li>
<li>Commerical</li>
<li>Private</li>
</ul>
<ul class="res-pro residential-pro">
<li>rProject 1</li>
<li>rProject 2</li>
<li>rProject 3</li>
</ul>
<ul class="com-pro commercial-pro">
<li>cProject 1</li>
<li>cProject 2</li>
<li>cProject 3</li>
</ul>
JS
$(document).ready(function() { $('.residential-main').mouseenter(function() { $('.residential-pro').show(); }); $('.residential-main').mouseleave(function () { $('.residential-pro').hide(); }); });
$(document).ready(function() { $('.commercial-main').mouseenter(function() { $('.commercial-pro').show(); }); $('.commercial-main').mouseleave(function () { $('.commercial-pro').hide(); }); });
See jsFiddle
You don't need javascript for this as you can do it using CSS only with the :hover psuedo selector.
First you need to make the related ul elements children of their parent li:
<ul class="sector-nav">
<li>
Residential
<ul class="res-pro residential-pro">
<li>rProject 1</li>
<li>rProject 2</li>
<li>rProject 3</li>
</ul>
</li>
<li>
Commerical
<ul class="com-pro commercial-pro">
<li>cProject 1</li>
<li>cProject 2</li>
<li>cProject 3</li>
</ul>
</li>
<li>Private</li>
</ul>
Then amend the following selectors to hide/show the relevant ul elements on hover:
.sector-nav > li {
display: inline;
padding-right: 20px;
border-right-width: 1px;
border-right-style: solid;
border-right-color: #999;
padding-left: 20px;
position: relative;
}
.sector-nav li > ul {
display: none;
position: absolute;
}
.sector-nav > li:hover > ul {
display: block;
}
Example fiddle
The better way would be to use CSS. Here is fiddle a with fadeIn animation example.
.fadeIn {
border: 1px solid #48484A;
font-size: 18px;
opacity:0;
-webkit-transition : all 2s ease-out;
-moz-transition : all 2s ease-out;
-o-transition : all 2s ease-out;
transition : all 2s ease-out;
}
.thisText:hover .fadeIn {
opacity: 1;
}
But since your are using JQuery, you can also use his fadein function which provide animation.
Here is an example from the JQuery documentation:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>fadeIn demo</title>
<style>
p {
position: relative;
width: 400px;
height: 90px;
}
div {
position: absolute;
width: 400px;
height: 65px;
font-size: 36px;
text-align: center;
color: yellow;
background: red;
padding-top: 25px;
top: 0;
left: 0;
display: none;
}
span {
display: none;
}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<p>
Let it be known that the party of the first part
and the party of the second part are henceforth
and hereto directed to assess the allegations
for factual correctness... (click!)
<div><span>CENSORED!</span></div>
</p>
<script>
$( "a" ).click(function() {
$( "div" ).fadeIn( 3000, function() {
$( "span" ).fadeIn( 100 );
});
return false;
});
</script>
</body>
</html>
See the doc for more examples (JQuery doc)
If you want to use js, your solution is very close.
Just replace jquery show,hide with fadeIn and fadeOut respectively and initially hide the elements from css. However you also need to modify your html, so that children are presented under their parents.
HTML
<ul class="sector-nav">
<li class="residential-main">Residential<ul class="res-pro residential-pro">
<li>rProject 1
</li>
<li>rProject 2
</li>
<li>rProject 3
</li>
</ul>
</li>
<li class="commercial-main"><a href="#" >Commerical</a>
<ul class="com-pro commercial-pro">
<li>cProject 1
</li>
<li>cProject 2
</li>
<li>cProject 3
</li>
</ul>
</li>
<li>Private
</li>
</ul>
CSS
.sector-nav li {
display: inline;
}
.residential-pro , .commercial-pro{
display:none;
position:absolute;
padding:0;
}
.residential-pro li, .commercial-pro li{
display:block;
}
JS
$(document).ready(function () {
$('.residential-main,.residential-pro').mouseenter(function () {
$('.residential-pro').stop(false,true).offset({left:$('.residential-main').offset().left}).fadeIn();
});
$('.residential-main').mouseleave(function () {
$('.residential-pro').stop(false,true).fadeOut();
});
});
$(document).ready(function () {
$('.commercial-main,.commercial-pro').mouseenter(function () {
$('.commercial-pro').stop(false,true).offset({left:$('.commercial-main').offset().left}).fadeIn();
});
$('.commercial-main').mouseleave(function () {
$('.commercial-pro').stop(false,true).fadeOut();
});
});
http://jsfiddle.net/tEMQj/7/
Related
I have gotten it to open and close when hovering over the nav link but how do I keep it open so I can access the content on the menu? I need it to work exactly how a dropdown menu works.
This is what I have done so far I also need the html layout to stay the same.
$('.nav-link--dropdown').mouseover(function() {
$('.dropdown-menu').css('display', 'block');
});
$('.nav-link--dropdown').mouseleave(function() {
$('.dropdown-menu').css('display', 'none');
});
ul {
list-style: none;
padding: 0px;
display: flex;
}
li {
margin-right: 10px;
}
.dropdown-menu {
display: none;
}
.dropdown-menu ul {
display: block;
background-color: grey;
color: white;
padding: 10px;
text-align: center;
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav">
<ul>
<li class="nav-link">home</li>
<li class="nav-link--dropdown">dropdown</li>
</ul>
</div>
<div class="dropdown-menu">
<ul>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
</ul>
</div>
View on jsFiddle
Should remove margin use padding for that, if not when we enter that margin area mouse leave event will trigger.
$('.nav-link--dropdown').mouseover(function () {
$('.dropdown-menu').css('display', 'block');
});
$('.dropdown-menu').mouseover(function () {
$('.dropdown-menu').css('display', 'block');
});
$('.nav-link--dropdown').mouseleave(function () {
$('.dropdown-menu').css('display', 'none');
});
$('.dropdown-menu').mouseleave(function () {
$('.dropdown-menu').css('display', 'none');
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
ul {
list-style: none;
padding: 0px;
display: flex;
}
li {
padding: 10px;
}
.dropdown-menu {
display: none;
}
.dropdown-menu ul {
display: block;
background-color: grey;
color: white;
padding: 10px;
text-align: center;
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="nav">
<ul>
<li class="nav-link">home</li>
<li class="nav-link--dropdown">dropdown</li>
</ul>
</div>
<div class="dropdown-menu">
<ul>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
</ul>
</div>
The problem you have here is that you leave the nav-link--dropdown when you move to your dropdown-menu. The simple solution: Include your dropdown-menu in your nav item.
$('.nav-link--dropdown').mouseover(function() {
$('.dropdown-menu').css('display', 'block');
});
$('.nav-link--dropdown').mouseleave(function() {
$('.dropdown-menu').css('display', 'none');
});
ul {
list-style: none;
padding: 0px;
display: flex;
}
li {
margin-right: 10px;
}
.dropdown-menu {
display: none;
}
.dropdown-menu ul {
display: block;
background-color: grey;
color: white;
padding: 10px;
text-align: center;
width: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="nav">
<ul>
<li class="nav-link">home</li>
<li class="nav-link--dropdown">
dropdown
<div class="dropdown-menu">
<ul>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
</ul>
</div>
</li>
</ul>
</div>
You can achieve this by bundling the menu item you want to hover over and it's dropdown in the same div.
<div class="nav">
<ul>
<li class="nav-link">home</li>
<div class="innerNav">
<li class="nav-link--dropdown">dropdown</li>
<div class="dropdown-menu">
<ul>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
<li class="dropdown-menu__link">random text</li>
</ul>
</div>
</div>
</ul>
</div>
And:
$('.innerNav').mouseover(function () {
$('.dropdown-menu').css('display', 'block');
});
$('.innerNav').mouseleave(function () {
$('.dropdown-menu').css('display', 'none');
});
See this JSFiddle: https://jsfiddle.net/rmdfqh6c/
Since your problem is the mouseleave event will trigger when you try to move the mouse to the bellow dropdown menu, if you really must keep the elements separated, add the dropdown-menu to the class that keeps the display:block
$('.nav-link--dropdown, .dropdown-menu').mouseover(function () {
$('.dropdown-menu').css('display', 'block');
});
$('.nav-link--dropdown, .dropdown-menu').mouseleave(function () {
$('.dropdown-menu').css('display', 'none');
});
And remove margin/padding from menu items. Use line-height instead if you want some spacing:
.nav ul li {
line-height: 40px;
}
ul {
list-style: none;
margin: 0; // <--- I changed this from padding: 0px;
display: flex;
}
Otherwise the other suggested solutions to include the dropdown within you parent <ul> element is the best.
JSFiddle
I have the following fiddle demo of a working sidenav menu with sliding sub menu contents. I followed the same demo without using Jquery (actually first using plain JS and then via CSS hover selector instead of click) and in my case sub menu doesn't slides/animates in the same way.
.submenu {
display: none;
}
.parent:hover .submenu,.submeun:hover {
display: block;
}
Is that animation due to Jquery toggle method?
$(document).ready(function() {
$('.parent').click(function() {
$('.submenu').toggle('visible');
});
});
How can I replicate the same approach without using jquery, via css or plain JS as I don't want to use jquery just for one simple sliding animation.
JSFIDDLE
This way ?
document.getElementById('home').addEventListener('click', function(e) {
var nextEl = e.target.nextElementSibling;
if(!nextEl.classList.contains('submenu')) {
return false;
}
if(nextEl.classList.contains('show')) {
nextEl.classList.remove('show')
}
else {
nextEl.classList.add('show');
}
});
.submenu {
-webkit-transition: max-height 1s;
-moz-transition: max-height 1s;
-ms-transition: max-height 1s;
-o-transition: max-height 1s;
transition: max-height 1s;
background: #e5feff;
overflow: hidden;
max-height: 0;
}
.submenu.show {
max-height: 300px;
}
<div id="sidebar">
<ul>
<li id="home" class="parent">Home</li>
<li class="submenu"><ul >
<li>Home 1</li>
<li>Home 2</li>
<li>Home 3</li>
</ul> </li>
<li>Explore</li>
</ul>
</div>
You could use slideToggle() and so avoid changing classes . This is just an option
Also , keep in mind that a submenu must be inside the parent li, for example <li>Home<ul><li>Sub link</li></ul></li> . I changed your HTML accordingly
see snippet below
$(document).ready(function() {
$('.parent').click(function() {
$(this).children(".submenu").slideToggle()
});
});
body, html {
height: 100%;
margin: 0;
overflow:hidden;
}
#sidebar {
background: #DF314D;
width: 240px;
height: 100%;
}
#sidebar ul {
padding: 0;
list-style: none;
}
#sidebar ul li {
padding: 15px 20px 15px 35px;
color: white;
}
#sidebar li:hover {
background: #C9223D;
}
.submenu {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="sidebar">
<ul>
<li class="parent">Home
<ul class="submenu">
<li>Home 1</li>
<li>Home 2</li>
<li>Home 3</li>
</ul>
</li>
<li>Explore</li>
</ul>
</div>
I have grid of floated elements, for which I created a filter. I want this filter to hide and show the items and while doing so I want the items to re adjust with transitions and fades.. At the moment the items just jump around.
As you can see here:
JSFIDDLE
How can I make the items slide to their position?
Heres the code:
HTML
<ul class="filters">
<li data="1">filter 1</li>
<li data="2">filter 2</li>
<li data="3">filter 3</li>
<li data="4">filter 4</li>
</ul>
<br>
<ul class="items">
<li data="1">1</li>
<li data="2">2</li>
<li data="1">3</li>
<li data="3">4</li>
<li data="4">5</li>
<li data="2">6</li>
<li data="3">7</li>
<li data="4">8</li>
</ul>
CSS
ul {
list-style: none;
padding: 0;
}
.filters li {
float:left;
margin-right: 10px;
cursor: pointer;
}
.items li {
width: 100px;
height: 100px;
background: #ccc;
float: left;
margin: 20px;
}
JQUERY
$(document).ready( function() {
$('.filters li').click( function () {
var data;
data = $(this).attr('data');
$('.items li').each( function() {
if($(this).attr('data') !== data) {
$(this).fadeOut();
}
else {
$(this).fadeIn();
}
});
});
});
As I mentioned in the comments you would need a different operation than fadeIn/Out as that involves the display property and that cannot be animated or transitioned.
Animating non-display values seems more optimal.
Something like this:
$(document).ready(function() {
$('.filters li').click(function() {
var data;
data = $(this).attr('data');
$('.items li').each(function() {
if ($(this).attr('data') !== data) {
$(this).addClass('hidden');
} else {
$(this).removeClass('hidden');
}
});
});
});
ul {
list-style: none;
padding: 0;
}
.filters li {
float: left;
margin-right: 10px;
cursor: pointer;
}
.items li {
width: 100px;
height: 100px;
background: #ccc;
float: left;
margin: 20px;
transition: all .5s ease;
}
li.hidden {
height: 0;
width: 0;
margin: 0;
opacity: 0;
font-size: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="filters">
<li data="1">filter 1</li>
<li data="2">filter 2</li>
<li data="3">filter 3</li>
<li data="4">filter 4</li>
</ul>
<br>
<ul class="items">
<li data="1">1</li>
<li data="2">2</li>
<li data="1">3</li>
<li data="3">4</li>
<li data="4">5</li>
<li data="2">6</li>
<li data="3">7</li>
<li data="4">8</li>
</ul>
You could set a delay for the fade in to ensure the fade out has completed.
The 500ms delay below is is a slightly longer duration as the fade in.
$(document).ready(function() {
$('.filters li').click(function() {
var data;
data = $(this).attr('data');
$('.items li').each(function() {
if ($(this).attr('data') !== data) {
$(this).fadeOut();
} else {
$(this).delay(525).fadeIn();
}
});
});
});
ul {
list-style: none;
padding: 0;
}
.filters li {
float: left;
margin-right: 10px;
cursor: pointer;
}
.items li {
width: 100px;
height: 100px;
background: #ccc;
float: left;
margin: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="filters">
<li data="1">filter 1</li>
<li data="2">filter 2</li>
<li data="3">filter 3</li>
<li data="4">filter 4</li>
</ul>
<br>
<ul class="items">
<li data="1">1</li>
<li data="2">2</li>
<li data="1">3</li>
<li data="3">4</li>
<li data="4">5</li>
<li data="2">6</li>
<li data="3">7</li>
<li data="4">8</li>
</ul>
It's the overlap of fadeOut and fadeIn that makes it look like they are jumping.
Try hiding the filtered out items quick and slideDown the applicable boxes:
$(document).ready( function() {
$('.filters li').click( function () {
var data;
data = $(this).attr('data');
$('.items li').each( function() {
if($(this).attr('data') !== data) {
$(this).slideUp();
}
else {
$(this).delay(525).slideDown();
}
});
});
});
I have been trying to fix this problem for a while. Basically I am creating a drop down menu that has divs that contain the ul's so that I can have a box with a fixed width which will allow me to have images within the box.
An example of this would be BestBuy.com's navigation menu. I really like the design, but I'm having a difficult time replicating it.
My CSS works without trouble ONLY when the li's are not links. Example: It works when it is <li>Link</li> and not <li>Link</li>.
Of course inside that <li> is another list.
Anyway, I decided to use JQuery to fix the issue and I am about halfway there.
Here is my JQuery:
$(document).ready(function () {
$(".navbar ul li").hover(function() {
$(".navlink > div:first").addClass("active");
}, function() {
$(".navlink > div:first").removeClass("active");
});
$(".secondarylink").hover(function() {
$(".secondarylink > div").addClass("active");
}, function() {
$(".secondarylink > div").removeClass("active");
});
});
Here is my markup:
<div class="navbar">
<ul>
<li class="navlink"> Products
<div class="secondlevel">
<ul>
<li class="secondarylink">Testing 1
<div class="thirdlevel two-columns">
<div class="column">
<ul>
<li>Testing 1 </li>
<li>Testing 2 </li>
<li>Testing 3 </li>
<li>Testing 4 </li>
</ul>
</div>
<div class="column">
<ul>
<li>Testing 1 </li>
<li>Testing 2 </li>
<li>Testing 3 </li>
<li>Testing 4 </li>
</ul>
</div>
</div>
</li>
<li class="secondarylink">Testing 2
<div class="thirdlevel">
<ul>
<li>Testing 1</li>
<li>Testing 2</li>
<li>Testing 3</li>
<li>Testing 4</li>
</ul>
</div>
</li>
<li>Testing 3</li>
<li>Testing 4</li>
</ul>
</div>
</li>
<li class="navlink">Test Link</li>
</ul>
</div>
And my styling:
body {
font-family:sans-serif;
background: #eee;
}
.navlink {
display:block;
}
.navbar {
background:lightblue;
width: 100%;
padding:0;
}
.navbar ul {
list-style:none;
padding:0;
margin:0;
}
.navbar ul>li {
display:inline-block;
}
.navbar ul li ul>li {
display:block;
}
.secondlevel {
position:absolute;
width:350px;
height:477px;
background:#fff;
padding:0;
border: 1px solid #c3c4c4;
}
.thirdlevel {
position:absolute;
width:350px;
height:477px;
background:lightgreen;
left:350px;
border: 1px solid #c3c4c4;
top:-1px;
}
.thirdlevel.two-columns {
width:700px;
}
.thirdlevel div:first-child {
position:absolute;
left:0;
}
.thirdlevel div {
position:absolute;
right:0;
}
.column {
width:350px;
}
.thirdlevel {
display:none;
}
.secondlevel {
display:none;
}
/*
.navbar ul li:hover > div:first-child {
display:block;
}
*/
.active {
display:block;
}
.hidden {
display:none;
}
.navbar ul li a {
display:block;
}
Demo
As you can see, in my CSS I had .navbar ul li:hover > div:first-child { display:block;}. This works, but without the links... Someone told me to try making the <a> display:block; but that didn't work either.
All I need to do(I think) is be able to select div:first-child for this to work, but so far I haven't found anything that works. What am I doing wrong?
Any help is greatly appreciated. Thank you people!
I'm not entirely sure what you're after, but maybe this helps.
With CSS:
.navbar > ul > li:hover > .secondlevel {
display: block;
}
.navbar .secondarylink:hover > .thirdlevel {
display: block;
}
Demo
With jQuery:
$(".navbar ul li").hover(function () {
$(this).find('.secondlevel').show();
}, function () {
$(this).find('.secondlevel').hide();
});
$(".secondarylink").hover(function () {
$(this).find('.thirdlevel').show();
}, function () {
$(this).find('.thirdlevel').hide();
});
Demo
It's doesn't matter with the <li>item</li> or <li>item</li> as long as you have the correct script.
As I looked into your script, the action you trigger is to add 'active' class to all the second/third level.
I've updated the script and now it only add class to the second level / third level accordingly.
$(this).find().addClass();
DEMO
I am using stopPropegation to aid me in the way my dropdowns work.
I am using it for multiple dropdowns to help me keep the dropdown open but if the user clicks anywhere else on the page then it will slide up the menu.
HTML
<nav id="moo">
<ul>
<li>Item 1 <i>o</i>
<div class="dropdown">
<ul>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
</li>
<li>Item 1 <i>o</i>
<div class="dropdown">
<ul>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
</div>
</li>
</ul>
</nav>
<div class="clear"></div>
<div id="login-top">Login</div>
<div id="user">roooar</div>
CSS
ul { padding: 0px; margin: 0px; }
li { display: inline; }
nav li { position: relative; }
nav i { cursor: pointer; font-weight: bold; background-color: red;padding: 5px; }
.dropdown { display: none; position: absolute; border:1px solid #ccc; padding: 10px; }
.dropdown li {
display: block;
}
.clear {
clear:both;
}
#login-top {
background:blue;
padding:10px;
color:white;
margin-top:30px
}
#user {
background:pink;
margin-top:10px;
padding:50px;
}
SCRIPT
$('#login-top').click(function () {
var $user = $('#user');
if ($('#user').is(':visible')) {
$user.slideUp(300);
} else {
$user.slideUp(300);
$user.slideDown(300);
}
});
$('nav > ul > li').click(function (e) {
var $childDropdown = $(this).find('.dropdown');
if ($childDropdown.is(':visible')) {
var target = $(e.target);
if (!$(target).parents(".dropdown").length) {
$('.dropdown').slideUp(300);
}
} else {
$('.dropdown').slideUp(300);
$childDropdown.slideDown(300);
}
});
/* Anything that gets to the document
will hide the dropdown */
$(document).click(function () {
$(".dropdown").hide();
$("#user").slideUp();
});
/* Clicks within the dropdown won't make
it past the dropdown itself */
$("nav, #login-top, #user").click(function (e) {
e.stopPropagation();
});
I have 2 questions really about this.
Say if I click open the dropdown menu because I have included certain elements to be exempt from clicking elsewhere on the page - If I click anywhere else it will slide back up exactly how I want.
However, if I happen to click on the #login-top this will not make it slide up as I have added it to the code for the stopPropagation
Is there a may of making it work so that when ".dropdown" is active then you can click absolutely everywhere (including on the <div id='login'> And then when "#login" and "#user" is active you can click anywhere on "nav" and it will still slide up the div?
Is it the right thing to be doing by grouping all the classes and id's into the code:
$("nav, #login-top, #user").click(function (e) {
e.stopPropagation();
});
(I am struggling to explain this but hopefully you can see what I mean if you look at the fiddle version)
http://jsfiddle.net/susannalarsen/Nt2ZM/1/