Displaying menu over an image - javascript

I have a sliding menu that should be displayed over an image, actually a logo. However, when it does, it is shifted as if the text of the menu wanted to avoid touching the image.
See :
the problem in image http://fruityhotchocolate.com/m.png
(note: the website is in french)
I deal with the event as follows:
$("nav>#menu>ul>li").hover(function(e) {
$("ul",this).css("display","block");
});
Thanks.

You don't need javascript, you can do it with CSS:
Add the following code:
#menu>ul>li>ul {
display: none;
list-style: none;
}
#menu>ul>li:hover>ul {
display: block;
}
Moreover, you should use child selectors (>) instead of descendant selectors:
#menu>ul
#menu>ul>li>ul
#menu>ul>li>ul>li
#menu>ul>li>ul>li>a
#menu>ul>li>a, #menu>ul>li>a:hover, #menu>ul>li>a:visited

Basically, what happens is that the li expands to the same width as the ul because it does not have a fixed width. Try:
$(document).ready(function() {
$('#menu ul').children('li').each(function () {
$(this).css('width', $(this).css('width'));
});
});

Try it with CSS:
<div class="content">
<img src="https://www.google.com.br/images/srpr/logo3w.png​​​​​​​​​​" />
<ul class="menu">
<li>Item 1</li>
</ul>
</div>
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
CSS:
.content {
position: relative;
}
.content:hover .menu {
display: block;
}
.menu {
position: absolute;
display: none;
}
Demo: http://jsfiddle.net/nfKc4/

Related

How to animate clicked li from its current position to top position and hide all li

I have list of different list items so when i click on specific item from list it should move from its current position to top position using jquery animate and at the same time hide remaining list items using jquery.
$(document).ready(function() {
$(".menu").click(function() {
$("li").animate({
top: '2px'
}, 'slow');
});
});
ul>li {
list-style-type: none;
line-height: 34px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li>Account</li>
<li>Profile</li>
<li>History</li>
</ul>
You can show click element by adding addClass and css to added class and simultaneously you can hide others li by jquery hide(). Hope it helps. I'm just adding the animation to it.
$(document).ready(function() {
$("li").click(function() {
$(this).addClass('top');
$('li').hide();
});
});
ul>li {
list-style-type: none;
line-height: 34px;
}
.top{
display:inline-block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Account</li>
<li>Profile</li>
<li>History</li>
</ul>
Inorder to animate top the element has to be able to take the css property top. So far I made the element to be capable enough to take the property top and I animated it to top while reducing the opacity using transition. These jquery this are done for the sibling li elements of the clicked one.
$(document).ready(function() {
$(".menu li").click(function() {
$(this).siblings('li').animate({
top: '-60px'
}, 'fast');
$(this).siblings('li').css({
'opacity': '0'
});
});
});
ul>li {
list-style-type: none;
line-height: 34px;
position: relative;
top: 10px;
transition: all 2s ease;
}
.menu {
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="menu">
<li>Account</li>
<li>Profile</li>
<li>History</li>
</ul>

All sub-menus are showing up on click

I want to only show the sub-menu that is the child of the clicked li and button when it is clicked. Currently the click and show and hide are working but the code below shows both the sub-menus on click, I want only the child sub-menu of the li button to show on click.
<ul id="menu-main-menu" class="nav-menu">
<li class="menu-item">Menu link
<button aria-expanded="false" class="dropdown-toggle"></button>
<ul class="sub-menu">
<li class="menu-item">link1</li>
<li class="menu-item">link1</li>
</ul>
</li>
<li class="menu-item">Menu link 2
<button aria-expanded="false" class="dropdown-toggle"></button>
<ul class="sub-menu">
<li class="menu-item">link1</li>
<li class="menu-item">link1</li>
</ul>
</li>
</ul>
<div class="site-content"></div>
jQuery:
jQuery(document).ready(function ($) {
$("#menu-main-menu").on('click', 'button', function (event) {
$('ul.sub-menu').appendTo('.site-content');
if($('ul.sub-menu:visible').length)
$('ul.sub-menu').hide();
else
$('ul.sub-menu').show();
});
});
CSS:
#menu-main-menu ul.sub-menu {
display: none;
}
ul.sub-menu {
display: none;
position: absolute;
z-index: 200000;
top: 0;
left: 1.5%;
right: 1.5%;
margin: 0 auto 0 auto;
padding: 20px;
list-style: none;
}
ul.sub-menu li {
width: 24%;
display: inline-block;
padding: 8px 9px;
text-align: center;
}
ul.sub-menu .toggled-on {
display: block;
}
.site-content {
display: block;
position: relative;
}
Solution: So the solution here was to not use appendTo(), as I had to put the element back where it came from when toggled off. The solution was to merely toggle the menu item using correct position: absolute CSS for the .sub-menu and $()on('click' to toggle it.
jQuery('#menu-main-menu').on('click', 'button', function(event) {
if($(this).closest("li.menu-item").children("ul.sub-menu").length > 0)
{
$(this).closest("li.menu-item").children("ul.sub-menu").slideToggle('fast');
return false;
}
});
See it working here: http://jsfiddle.net/abdqt6d9/
The problem is that you are writing incorrect selectors for your jquery:
$('ul.sub-menu')
That means it will grab all matching elements within the page.
What you need to do is grab the corresponding li. Within your click(), the $(this) becomes the button that is clicked. Using .parent() will give you the li element. From there, search for your corresponding sub-menus within the li_element:
var $li_element = $(this).parent()
var $sub_menu = $li_element.find(".sub-menu")
if ($li_element.find(".sub-menu:visible").length > 0) {
$sub_menu.hide()
} else {
$sub_menu.show()
}
The other problem is that perhaps your styling for your sub-menu is above the buttons. so once you show it, you can no longer press the button. So you need to restyle your sub-menus.
$("ul.sub-menu") will apply to all the sub-menus, so you need to change it to only look for the sub-menu within the buttons parent. You can do this using .closest (or just .parent()) and then .find
//closest("li") will find the closest parent that is an li
//find(".sub-menu") will find the sub-menu within
$(this).closest("li").find(".sub-menu").show();
If you your button is always going to be before the sub-menu you can slim it down to just .next(".sub-menu")
$(this).next(".sub-menu").show();

Mouse hover using jQuery keeps bouncing

I am trying to make a show content on mouseover and make it stay visible while the mouse is hovered on the list since I am planning to put a button there, but when I do hover, hidden content kept bouncing for some reason.
jQuery code
$('li.employers').mouseover(function () {
$('.employer_content').show("slow");
$(this).addClass("bluehover");
});
$('li.employers').mouseout(function () {
$('.employer_content').hide("fast");
$(this).removeClass("bluehover");
});
HTML
<li class="employers">
<div>employer</div>
<div class="employer_content">some content.</div>
</li>
<li class="court">
<div>court</div>
<div class="court_content">some content.</div>
</li>
http://jsfiddle.net/zLdnnxnh/3/
You can use only CSS to show/hide the contents.
You can take advantage of :hover class in CSS.
Demo using CSS only
.whatwedo {
padding: 20px;
color: #fff;
max-width: 480px;
margin: 0 auto;
}
ul li {
list-style-type: none;
}
ul > li {
background-color: #08588c;
display: inline-block;
width: 100%;
cursor: pointer;
float: left;
max-width: 100px;
padding: 10px;
}
.whatwedo {} ul.wwd_list {
padding: 0;
margin: 0;
}
.employer_content,
.court_content,
.companies_content,
.labor_content {
display: none;
clear: right;
}
.bluehover {
background-color: #01395d;
}
.content {
padding-top: 10px;
display: none;
}
.wwd_list li:hover .content {
display: block;
}
<div class="whatwedo">
<ul class="wwd_list">
<li class="employers">
<div>employer</div>
<div class="content">some content.</div>
</li>
<li class="court">
<div>court</div>
<div class="content">some content.</div>
</li>
<li class="companies">
<div>companies</div>
<div class="content">some content.</div>
</li>
<li class="laborunion">
<div>labour union</div>
<div class="content">some content.</div>
</li>
</ul>
</div>
CSS Demo with Animation
If you still want to use jQuery:
You are using mouseover event that is causing the handler to run when the mouse is moved over the element, use mousein instead
Use hover instead of mousein and mouseout
Your code is not flexible, you can optimize your code as follow
Use stop() to stop the previous animations
Demo
$('.wwd_list li').hover(function() {
$(this).find('div.content').stop().show("slow");
$(this).addClass("bluehover");
}, function() {
$(this).find('div.content').stop().hide("slow");
$(this).removeClass("bluehover");
});
.whatwedo {
padding: 20px;
color: #fff;
max-width: 480px;
margin: 0 auto;
}
ul li {
list-style-type: none;
}
ul > li {
background-color: #08588c;
display: inline-block;
width: 100%;
cursor: pointer;
float: left;
max-width: 100px;
padding: 10px;
}
.whatwedo {} ul.wwd_list {
padding: 0;
margin: 0;
}
.employer_content,
.court_content,
.companies_content,
.labor_content {
display: none;
clear: right;
}
.bluehover {
background-color: #01395d;
}
.content {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<div class="whatwedo">
<ul class="wwd_list">
<li class="employers">
<div>employer</div>
<div class="content">some content.</div>
</li>
<li class="court">
<div>court</div>
<div class="content">some content.</div>
</li>
<li class="companies">
<div>companies</div>
<div class="content">some content.</div>
</li>
<li class="laborunion">
<div>labour union</div>
<div class="content">some content.</div>
</li>
</ul>
</div>
You can use hover instead of mouseover and mouseout. Something like this:
$('li.employers').hover(function () {
$('.employer_content').show("slow");
$(this).addClass( "bluehover" );
console.log('mouse in');
}, function() {
$('.employer_content').hide("slow");
$(this).removeClass( "bluehover" );
console.log('mouse out');
});
Here's an example
How about this?
You can use stop() to stop the animation and continue the new animation from where it has stopped
$('.employer_content').stop().show("slow");
$('.employer_content').stop().hide("slow");
As recommended by others, use mouseenter than mouseover
Replace mouseover function with mouseenter and mouseout with mouseleave.
You can see this fiddle is working.
http://jsfiddle.net/ebilgin/zLdnnxnh/7/
Try using mouseenter and mouseleave instead:
From https://api.jquery.com/mouseover/:
This event type can cause many headaches due to event bubbling. For
instance, when the mouse pointer moves over the Inner element in this
example, a mouseover event will be sent to that, then trickle up to
Outer. This can trigger our bound mouseover handler at inopportune
times. See the discussion for .mouseenter() for a useful alternative.
$('li.employers').mouseenter(function () {
$('.employer_content').show("slow");
$(this).addClass("bluehover");
});
$('li.employers').mouseleave(function () {
$('.employer_content').hide("fast");
$(this).removeClass("bluehover");
});
http://jsfiddle.net/zLdnnxnh/5/
Just remove fast from your hide function. It is WORKING. Check this fiddle: http://jsfiddle.net/zp3jr43u/
The JavaScript code should like the following.
$('li.employers').mouseover(function () {
$('.employer_content').show("slow");
$(this).addClass("bluehover");
});
$('li.employers').mouseout(function () {
$('.employer_content').hide();
$(this).removeClass("bluehover");
});
Somehow the mouseover event gets triggered multiple times. I got it working by using the .stop() method before toggling the element.
http://jsfiddle.net/zLdnnxnh/4/
There's no need to have separate classes for each list item you have. Even with these separate classes the code below should get you up and running with ease.
$('.wwd_list li').hover(function () {
$('div:last-child',this).show("slow");
$(this).addClass( "bluehover" );
}, function(){
$('div:last-child',this).hide("slow");
$(this).removeClass( "bluehover" );
});
Note the fact that you only need to use one hover function instead of mouse in and mouse out. This works because you have two divs in the wwd_lsit class and the last one just so happens to be the one you want to target. So be careful with this if you ever want to change something!
Replace mouseover with mouseenter and mouseout with mouseleave.
See a more factorised form :
$('li').on({
mouseenter: function() {
jQuery("div.content", this).show('slow');
$(this).addClass( "bluehover" );
},
mouseleave: function() {
jQuery("div.content", this).hide('fast');
$(this).removeClass( "bluehover" );
}
});
(content class has been added to each content divs)
See the updated fiddle

Trigger completely separate div based on hover of other div

Is it possible to trigger changes to CSS of an element that is completely unrelated to the hovered div?
I have a CSS hover effect on a dropdown menu, that I also want to trigger the opacity of a div right at the bottom of the page to create a background overlay effect.
This is the CSS I'm using:
#overlay {
background:rgba(0,0,0,0.5);
position:absolute;
top:120px;
left:0;
z-index:0;
height:120%;
width:100%;
visibility:hidden;
opacity:0;
}
#menu-main-menu li.menu-parent-item:hover ul.sub-menu,
#menu-main-menu li.menu-parent-item:hover #overlay {
visibility:visible;
opacity:1;
}
The hover of the sub menu works fine, but the div #overlay is right at the bottom of the page, and doesn't get called when it's hovered.
I've tried all kinds of alternatives such as :hover > #overlay, :hover + #overlay, but nothing seems to trigger it. I also can't seem to find a definitive answer to the question.
Is it possible?
Yes. You can load this style in a php file and then use jQuery to apply the css when your div has been hovered on.
No there is no way to select parent element in css and that means that you cannot move up in hierarchy.
<ul class="hover-parent">
<li></li>
</ul>
<div>Something here</div>
<div class="target"></div>
From this point :
.hover-parent li:hover you cannot go up (to ul or div).
Selectors which you tried to use are "next":
A>B - This will select only direct B children of A
A+B This will select B immediately preceded by A
Here you can find W3C documentation of CSS selector
http://www.w3.org/TR/CSS2/selector.html#adjacent-selectors
And demos:
http://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048
Notice that it will be really confusing for user that different part off app/page is changing when he is hovering something else. Bad UX idea.
You're going to have to use JavaScript to do this.
Your posted selector #menu-main-menu li.menu-parent-item:hover #overlay is looking for #overlay somewhere inside of an ancestor element of li.menu-parent-item that is somewhere inside of an ancestor element with an id of #menu-main-menu.
Using the child selector > will not work as the overlay element is not a child of the list element you're hovering in your menu from what you have described and from comment responses.
As #Paulie_D has pointed out the two target elements, the element to be hovered and the overlay element, need to adjacent siblings to use the sibling selector +. From what you have described and the comment responses they are not adjacent siblings.
I have setup a basic example for you using jQuery. This example displays the overlay as long as you are hovering any element in the .main-menu element.
HTML
<ul class="main-menu">
<li>Item One</li>
<li>Item Two</li>
<li>Item Three
<ul class="sub-menu">
<li>Sub Item One</li>
<li>Sub Item Two</li>
<li>Sub Item Three</li>
<li>Sub Item Four</li>
<li>Sub Item Five</li>
</ul>
</li>
</ul>
<main>
Content here.
</main>
<footer>
<div class="overlay">This is my overlay.</div>
</footer>
CSS
body {
margin: 25px auto;
width: 500px;
}
ul,
li {
margin: 0;
padding: 0;
}
main {
min-height: 300px;
}
footer,
.overlay {
height: 50px;
}
footer {
position: realative;
background-color: yellow;
}
.main-menu {
list-style: none;
height: 50px;
}
.main-menu > li {
float: left;
padding: 0 10px;
position: relative;
}
.main-menu > li:hover .sub-menu {
display: block;
}
.sub-menu {
display: none;
list-style: none;
position: absolute;
left: 10px;
width: 150px;
}
.overlay {
display: none;
text-align: center;
}
jQuery
$overlay = $('.overlay');
$('.main-menu > li').hover(
// when hovered
function() {
$overlay.css('display','block');
},
// when NOT hovered
function() {
$overlay.css('display','none');
}
);
jsFiddle: http://jsfiddle.net/ednf2pzq/
Edit
You could simplify the jQuery hover selector to .main-menu.
jQuery
$('.main-menu > li').hover(
// same code as before
);
jsFiddle: http://jsfiddle.net/ednf2pzq/1/

Fading one div out and another one in, in it's place

There are 3 divs and 3 links.
Only one div should be displayed at a time. When user clicks on a link for one of the other divs, the current one should fade out and the selected one should fade in, in place of the previous div.
Here is the code at the moment:
Javascript
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
switches = $('#switches > li');
slides = $('#slides > div');
switches.each(function(idx) {
$(this).data('slide', slides.eq(idx));
}).click(
function() {
switches.removeClass('active');
slides.removeClass('active').fadeOut('slow');
$(this).addClass('active');
$(this).data('slide').addClass('active').fadeIn('slow');
});
});
</script>
CSS
<style style="text/css">
ul {
list-style: none;
}
li:hover {
text-decoration: underline;
}
#switches .active {
font-weight: bold;
}
#slides div {
display: none;
}
#slides div.active {
display: block;
}
.outer {
position: absolute;
}
.outer div {
width: 600px;
height: 300px;
}
#uno {
background-color: red;
}
#dos {
background-color: blue;
}
#tres {
background-color: green;
}
</style>
HTML
<ul id="switches">
<li class="active">First slide</li>
<li>Second slide</li>
<li>Third slide</li>
</ul>
<div class="outer" id="slides">
<div class="active" id="uno">
First div.
</div>
<div id="dos">
Second div.
</div>
<div id="tres">
Third div.
</div>
</div>
You can view the page here:
http://dl.dropbox.com/u/6920023/proofOfConcept.html
I'm attempting to use standard Jquery to do this, but clearly there is something wrong with my javascript code.
Can you spot what's wrong and how to fix it?
Your CSS defines a div that's not active as hidden. So as soon as you remove the active class, it will be hidden immediately.
So, remove this entry:
#slides div {
display: none;
}
And add something like this on page load:
$(function() {
$('#slides div:not([class="active"])').hide();
}); // will hide inactive slides initially but not always
The issue is that you use slides.removeClass('active').fadeOut('slow');. So first it will remove the active class, which means (according to your CSS) that it will be a regular div, thus with the property display: none;.
So your div is automatically hidden. It's only afterwards that you do your fadeOut('slow'), on a hidden div thus.
Better would be to do something like:
$('div.active').fadeOut(1000).delay(1000).removeClass('active');
$(this).delay(2000).fadeIn(1000).delay(1000).addClass('active');
This works, if I understand the question correctly.
The issue is that you can't fade in an element that is hot hidden or unchcanged.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
switches = $('#switches > li');
slides = $('#slides > div');
switches.each(function(idx) {
$(this).data('slide', slides.eq(idx));
}).click(
function() {
switches.removeClass('active');
slides.removeClass('active').fadeOut('slow').hide();
$(this).addClass('active');
$(this).data('slide').addClass('active').fadeIn('slow');
});
});
</script>

Categories