jQuery activate href if element on top - javascript

I have a simple menu, everytime i click an element the others fadeOut and the clicked one goes up if it's not the first element, and after that i activate the href of the link.
To activate the link i need to make sure that the element is in the top of the page, after the addClass slideUpSm the clicked item gets new position top but i think the position top needs to be refreshed because the addClass slideUpSm gets the css top 0
setTimeout(function() {$('.main-nav li').addClass('slideUpSm')}, 1200);
After that, i can activate the window location, i have tried the hasClass methode and also tried to check if the new position top equals zero, here is my attempt https://jsfiddle.net/n37kgv4r/
setTimeout(function() {window.location = href}, 100);

If you just want to hide the other links and navigate to only the clicked node, we dont need to use the css top. We can achieve this with simple jquery code.
$(document).ready(function(){
$('.main-nav li a').click(function(e){
$(this).parent().addClass('show');
$('.main-nav li').not('.show').slideUp(1200);
var obj = $(this);
setTimeout(function(){
//remove the alert
alert("Navigating to "+ obj.attr('href'));
window.location.href=obj.attr('href');},2000)
return false;
});
});
a {
text-decoration: none;
color: black;
}
.main-nav {
position: relative;
}
.main-nav li {
position: sticky;
display: flex;
font-size: 60px;
line-height: 43px;
letter-spacing: -3px;
margin-bottom: 11px;
transition: all 2s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<ul class="main-nav">
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>

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>

menu close on click on body page

i have created a dropdown menu which opens on clicking the nav button. But i couldn't find a way to close the dropdown menu when the mouse clicks on the body of the page.
I you can figure it out, please help me
(function(){
var bodyEl = $('body'),
navToggleBtn= bodyEl.find('.nav-toggle-btn');
navToggleBtn.on('click', function(e){
bodyEl.toggleClass('active-nav');
e.preventDefault();
});
})();
active-nav is created within css and linked with menu and body
You can bind click event to body, then check if the event is generated from a particular element using event.target
var bodyEl = $('body');
navToggleBtn = bodyEl.find('.nav-toggle-btn');
$('body').on('click', function (e) {
if ($(e.target).hasClass("nav-toggle-btn")) {
bodyEl.toggleClass('active-nav');
e.preventDefault();
e.stopPropagation();
}
else
{
//close the menu here
}
});
I don't know if it is the right solution, but I would add a div element that covers the entire page.
The menu is on top of that div, but the rest is below. If you click the div, it closes itself and the menu.
So basically, it's a lightbox (as for showing images), but without the shade. Or width a shade, because it will make your menu stand out a little more, and it will fit the expectations of disabling clicks on specific elements in the body.
Another advantage of having an extra element instead of just capturing clicks on the main level on the body, it that it won't interfere with other event handlers on the body itself, which could capture the click and therefor have unexpected results for someone who just wants to close the menu.
A rough example can be found below:
$('header > ul > li').on('click', function() {
// Deactive all menu items
$('ul.active').removeClass('active');
// Activate the one clicked.
$(this).closest('li').addClass('active');
// If there is no lightbox setup a new one.
var box = $('.lightbox');
if (box.length == 0) {
// It's just a div with a class.
$('<div>')
.prependTo($('body'))
.addClass('lightbox')
.on('click', function() {
// Lightbox clicked? Remove it, and deactivate the menu.
$('.lightbox').remove();
$('li.active').removeClass('active');
});
}
});
li {
padding: 1em;
}
header > ul > li {
display: inline-block;
vertical-align: top;
position: relative;
background-color: #eee;
}
li > ul {
display: none;
background-color: #ddd;
position: absolute;
top: 100%;
left: 0;
}
li.active > ul {
display: block;
}
.lightbox {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0, 0.2); /* Just for show */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<header>
Header, page title
<ul>
<li>Main
<ul>
<li>sub</li>
<li>sub</li>
<li>sub</li>
<li>sub</li>
</ul>
</li>
<li>Other</li>
<li>About</li>
</ul>
</header>
<section>
Main content
</section>

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();

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/

Jquery Drop Down menu blinks only on IE

I am starting a Jquery drop down menu for a new project and it is working as expected on Google Chrome, Firefox, Safari but of course it is giving me some headache on Internet Explorer.
here's the thing,
See this page
http://www.universidadedoingles.com.br/dev/index.ASP
on mouse over the menu HOME, the drop down appers, when you move over the links in IE you see some flashes of the background, which doesn't happens on Chrome and ETC.
here's the js coda I am using to do the dd menu.
<script type="text/javascript">
$(document).ready(function() {
$("ul.mainmenu li.menuhome").mouseover(function(){
$(".arrow-spacer").show(); //When mouse over ...
//Following event is applied to the subnav itself (making height of subnav 150px)
$(this).find('.submenu').show().animate({height: '150px', opacity:'1'},{queue:false, duration:300})
});
$("ul.mainmenu li.menuhome").mouseout(function(){ //When mouse out ...
//Following event is applied to the subnav itself (making height of subnav 0px)
$(this).find('.submenu').hide().animate({height:'0px', opacity:'0'},{queue:false, duration:200})
});
//menu itembackground color animation
$("li").hover(function() {
$(this).animate();},
function() {
$(".arrow-spacer").hide();
});
});
</script>
That's it, I guess it may be simple, but it's been weeks and I still can't get it to work.
Thanks a lot.
I noticed that the anchor <a> tags have a margin on them. My first thing would be to try using padding instead. IE doesn't treat a hover in the margin the same way as other browsers.
in some cases it helps to set a z-index on elements that should placed in top of other elements.
In your case I would try to set the z-index on <ul class="submenu">
No blinks anymore! I changed one word hide() to stop (), now there is no blinking on iE. but...
After you show the menu 1 time, everytime you get your mouse below the link or close the link, the menu shows up again.
check this
www.universidadedoingles.com.br/dev
you'll be able to see its behavior
The thing is that the focus to <li> is lost when you mouse over an <a> element.
Here is something you could use to overcome this. I avoided using the <a> tag, instead I used a JavaScript function to send the user to the preferred location. I used JavaScript rather than jQuery hoping to make it more self-explanatory.
<script type="text/javascript" src="jquery.js" ></script>
<script type='text/javascript'>
$(document).ready(function() {
$('#n li').hover(function() {
$('ul', this).slideDown(200);
$(this).children('a:first').addClass('h');
}, function() {
$('ul', this).slideUp(200);
$(this).children('a:first').removeClass('h');
});
});
function gotoPage(pnumber){
var goto;
if(pnumber==1){
goto="home.html";
}else if(pnumber==2){
goto="watsnew.html";
}else if(pnumber==3){
goto="aboutus.html";
}else if(pnumber==4){
goto="contactus.html";
}
window.location.href=goto;
}
</script>
<style type="text/css">
#n {
padding: 0;
list-style: none;
padding-left: 15px;
padding-right: 15px;
width:5em;
}
#n li {
/*display:inline;*/
background: none;
position: relative;
z-index: 1;
font-weight:bold;
margin: 0 auto;
}
#n li .h {
background-color: #fff;
border-left: 1px solid #CF3;
border-right: 1px solid #CF3;
color: #576482;
height:20px; }
#n ul {
position: absolute;
display: none;
margin: 0; padding: 0;
list-style: none
padding-bottom: 3px;
width:200px;
}
#n ul li {
list-style-type:none;
padding:10px;}
#n ul li:hover {
background:#960;}
</style>
<div>
<ul id="n">
<li>MENU
<ul >
<li value="1" onclick="gotoPage(this.value)">HOME</li>
<li value="2" onclick="gotoPage(this.value)">WATS NEW</li>
<li value="3" onclick="gotoPage(this.value)">ABOUT US</li>
<li value="4" onclick="gotoPage(this.value)">CONTACT US</li>
</ul>
</li>
<ul>
</div>

Categories