Here is my code:
$("#menu li:not(:first-child)").click(function () {
$(this).siblings().removeClass('active');
$menu = $(this).find('ul');
$othermenu = $(this).siblings().find('ul');
if($othermenu.is(':visible') == true) {
$othermenu.animate({opacity:'0', easing:'easeOutQuad'}, 500).css({display:'none'});
}
if($menu.is(':visible') == false) {
$(this).addClass('active');
$menu.css({display:'block'}).animate({opacity:'1', easing:'easeOutQuad'}, 500);
} else {
$(this).removeClass('active');
$menu.animate({opacity:'0', easing:'easeOutQuad'}, 500).css({display:'none'});
}
});
using this code to show/hide sub menus on click of menu. I want to change as if i clicked outside menu that time also i want to hide sub menu.
My Html Code like this
<div id="menu" class="showmenubox submenucheck">
<ul> <li><a href="#" >Home</a> </li>
<li>About
<ul ><li>
<strong>aaaa</strong>
bbb
</li>
</ul></li>
<li>Contact
<ul><li>
<strong>aaaa</strong>bbb
</li>
</ul>
</li> </ul> </div>
You want to test whats been clicked when the document is clicked...
$(document).click(function (e) {
var $container = $("#menu");
if (!$container.is(e.target) // if the target of the click isn't the container...
&& $container.has(e.target).length === 0) // nor a descendant of the container
{
$container.find('.active ul').animate({opacity:'0', easing:'easeOutQuad'}, 500).css({display:'none'});
}
});
http://jsfiddle.net/kW2Nb/
Use the code below comments.
$("#menu li:not(:first-child)").click(function (e) {
$(this).siblings().removeClass('active');
$menu = $(this).find('ul');
$othermenu = $(this).siblings().find('ul');
if($othermenu.is(':visible') == true) {
$othermenu.animate({opacity:'0', easing:'easeOutQuad'}, 500).css({display:'none'});
}
if($menu.is(':visible') == false) {
$(this).addClass('active');
$menu.css({display:'block'}).animate({opacity:'1', easing:'easeOutQuad'}, 500);
} else {
$(this).removeClass('active');
$menu.animate({opacity:'0', easing:'easeOutQuad'}, 500).css({display:'none'});
}
/**
* Bind click event on document
* It will hide menu which is currently open and unbind click event on document
*
*/
var me = $(this);
$(document).click(function(e) {
$menu.animate({opacity:'0', easing:'easeOutQuad'}, 500).css({display:'none'});
$(document).unbind("click");
me.removeClass('active');
});
$menu.click(function(e) {
e.stopPropagation();
});
e.stopPropagation();
});
Related
I have a website where I am not able to change the HTML, I can only inject JavaScript and CSS. The website has a dropdown menu that doesn't work properly on Android. The parent menu is also a link, and when people click it they are taken to the link on the parent instead of opening the child/submenu.
The HTML (simplified)
<ul id="menu">
<li>
Parent menu ▼
<ul>
<li>Submenu link</li>
<li>Submenu link</li>
<li>Submenu link</li>
</ul>
</li>
<li>
Parent menu link
</li>
</ul>
And I have this jQuery:
var topmenuclicked == 0;
$("#menu > li a").click(function(event){
event.preventDefault();
if (topmenuclicked == 0) {
topmenuclicked = 1;
} else {
topmenuclicked = 0;
window.location.href = $(this).attr('href');
}
});
It's a bit messy and not the best way to solve this, but my main problem is with selecting only the a elements that have a submenu.
With the code as it is now I have to click all parent menu links twice and I'm not sure why.
So I need to be able to say something like $("#menu > li:has(ul) a) but I don't believe that works.
Use children("ul").length of li element
$("#menu > li a").click(function(event){
//use $(this).parent().children("ul").length
if($(this).closest("li").children("ul").length) {
event.preventDefault();
// the clicked on <li> has a <ul> as a direct child
}
if (topmenuclicked == 0) {
topmenuclicked = 1;
} else {
topmenuclicked = 0;
window.location.href = $(this).attr('href');
}
});
the previous answer won't work, cause submenu is not inside of A tag, but the rest is good.
Here is how can you fix it:
$('#menu > li a').on('click', function (event) {
if ($(this).next('ul').length) {
event.preventDefault();
// Parent link clicked
} else {
// Nested link clicked
// The ELSE part can be removed if custom logic is not needed
}
});
Another option can be:
$('#menu > li > a').on('click', function (event) {
event.preventDefault();
// Parent link clicked
});
$('#menu > ul a').on('click', function (event) {
// Nested link clicked
});
You can use parents for this. Also, use .on instead of .click
$('#menu').on('click', 'li a', function(event){
event.preventDefault();
var topmenuclicked = 0;
if($(this).parents('ul').length == 1) {
topmenuclicked = 1;
}
console.log('topmenuclicked -> ', topmenuclicked)
// do your stuff here
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul id="menu">
<li>
Parent menu ▼
<ul>
<li>Submenu link</li>
<li>Submenu link</li>
<li>Submenu link</li>
</ul>
</li>
<li>
Parent menu link
</li>
</ul>
put > before a. See below
var topmenuclicked == 0;
$("#menu > li > a").click(function(event){
event.preventDefault();
if (topmenuclicked == 0) {
topmenuclicked = 1;
} else {
topmenuclicked = 0;
window.location.href = $(this).attr('href');
}
});
In part because of #Love-Kesh his solution I came up with this that seems to be working.
$("#menu > li a").click(function(event){
// save parent in variable
var clickedlinkparent = $(this).parent();
// check if parent has any ul element as children
if (clickedlinkparent.children('ul').length) {
// prevent the link from opening
event.preventDefault();
// if link has not been clicked, do nothing
if (topmenuclicked == 0) {
topmenuclicked = 1;
// if link has already been clicked, go to href
} else {
topmenuclicked = 0;
window.location.href = $(this).attr('href');
}
}
});
Goal
clicking on a member of the <ul> selects/deselects it.
if class=allSearch is selected any other li's that are already selected are de-selected.
if allSearch is selected and then notAllSearch is selected, allSearch is deselected.
Problem
Goal 3 is not working, which doesn't make sense to me because it should be (and is) basically the same code used in Goal 2.
Here's the code:
HTML
<ul class="menu vertical" id="searchMenu">
<li id="allSearch" class="allSearch selected">All</li>
<li id="notAllSearch" class="notAllSearch">User</li>
<li id="notAllSearch" class="notAllSearch">Artists</li>
<li id="notAllSearch" class="notAllSearch">Events</li>
</ul>
JS:
$(document).ready(function() {
$('#searchMenu li').click(function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
}
else if ($(this).hasClass('notAllSearch')) {
$('#allSearch').removeClass('selected')
$(this).addClass('selected');
}
else if ($(this).hasClass('allSearch')) {
$('#notAllSearch').removeClass('selected')
$(this).addClass('selected');
}
else
$(this).addClass('selected');
});
})
Try this : instead of ID work on CLASS for this
$(document).ready(function() {
$('#searchMenu li').click(function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
}
else if ($(this).hasClass('notAllSearch')) {
$('.allSearch').removeClass('selected')
$(this).addClass('selected');
}
else if ($(this).hasClass('allSearch')) {
$('.notAllSearch').removeClass('selected')
$(this).addClass('selected');
}
else
$(this).addClass('selected');
});
});
Here is the pen to test
Following is my HTML,
<div class="container">
<ul class="navbar">
<li class="nb-link"><a>Home</a></li>
<li class="dropdown">
<a>CBSE</a>
<ul class="dropdown-menu">
<li>10th Standard</li>
<li>12th Standard</li>
</ul>
</li>
<li class="dropdown">
<a>Engineering</a>
<ul class="dropdown-menu">
<li>JEE - Main</li>
<li>JEE - Advanced</li>
</ul>
</li>
</ul>
I have 2 dropdowns . When I click one, it comes down. But when I click another, even that comes down without closing the previous one . This creates an overlap. The way I'm handling this using JS is as follows
$(document).ready(function() {
$('.dropdown').click(function() {
var $this = $(this);
if ($this.children('.dropdown-menu').hasClass('open')) {
$this.removeClass('active');
$('.navbar').$this.children('.dropdown-menu').removeClass('open');
$this.children('.dropdown-menu').fadeOut("fast");
}
else {
$this.addClass('active');
$this.children('.dropdown-menu').addClass('open');
$this.children('.dropdown-menu').fadeIn("fast");
}
});
});
How can I achieve a functionality using JS such that the previous dropdown closes when I click a new dropdown ? Also, the dropdowns should close when anywhere on the page is clicked ?
can try this
$(document).ready(function() {
$('.dropdown').click(function() {
var $this = $(this);
$('.dropdown').not($this).removeClass('active')
$('.dropdown-menu').not($this.find('.dropdown-menu')).removeClass('open');
$this.toggleClass('active');
$this.find('.dropdown-menu').toggleClass('open');
});
});
Working Demo
this is a function you can use if selectors is not target
// function for if selectors not target
function actionwindowclick(e , selector , action){
if (!$(selector).is(e.target) // if the target of the click isn't the container...
&& $(selector).has(e.target).length === 0) // ... nor a descendant of the container
{
action();
}
}
and you can use it in window click event like this
$(window).on('click', function(e){
actionwindowclick(e , ".dropdown , .dropdown-menu" , function(){
$('.dropdown').removeClass('active')
$('.dropdown-menu').removeClass('open');
});
});
Working Demo
Note: I think you may need to
event.stopPropagation()
while you trying to click on .dropdown-menu itself
$('.dropdown-menu').click(function(e) {
e.stopPropagation()
});
Try:
$(document).ready(function() {
$('.dropdown').click(function() {
var $this = $(this);
$this.children('.dropdown-menu').toggleClass('open');
if ($this.children('.dropdown-menu').hasClass('open')) {
$this.removeClass('active');
$this.children('.dropdown-menu').fadeOut("fast");
}
else {
$this.addClass('active');
$this.children('.dropdown-menu').fadeIn("fast");
}
});
});
I have multiple toggle elements on my page. I am trying to get them closed when clicking on the outside of the div element. the script i have now works veyr well with multiple elements but it also closes the div when clicking on inside of the div
<ul>
<li class="menuContainer">
<a class="top" href="#">Menu</a>
<div class="sub">
<a class="top" href="google.com">item in dropdown menu with valid url when clicked here div.sub should stay close</a>
</div>
</li>
<li class="menuContainer">
<a class="top" href="#">Menu</a>
<div class="sub">
<a class="top" href="#">item in dropdown menu when clicked here div.sub should stay open</a>
</div>
</li>
$(document).ready(function(){
$('li.menuContainer').each(function() {
var $dropdown = $(this);
$("a.top", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.sub", $dropdown);
$div.toggle();
$("li.menuContainer div.sub").not($div).hide();
$( "#effect" ).hide();
return false;
});
$("li.menuContainer div.sub").on("click", function (event) {
event.stopPropagation();
});
});
$(document).on("click", function (){
$("li.menuContainer div.sub").hide();
});
});
what i want to do is to stop closing div when clicked inside of it. Any help please?
I think you are looking for e.stopPropagation();. Use it in an event on the child items.
This will stop the event from propagating to the parent div.
In your code the problem is inside the following function, now corrected:
$('html').click(function(event){
var ele = event.target.tagName + '.' + event.target.className;
if (ele != 'DIV.sub') {
$("li.menuContainer div.sub").hide();
}
});
Like you can see now when you click on whatever html element a check is done to prevent the undesired action.
use this code
$("li.menuContainer > a.top").click(function(e) {
e.preventDefault();
$div = $(this).next("div.sub");
$("li.menuContainer div.sub").not($div).slideUp();
$div.slideDown();
});
instead of
$('li.menuContainer').each(function() {
var $dropdown = $(this);
$("a.top", $dropdown).click(function(e) {
e.preventDefault();
$div = $("div.sub", $dropdown);
$div.toggle();
$("li.menuContainer div.sub").not($div).hide();
return false;
});
});
and about
$('html').click(function(){
$("li.menuContainer div.sub").hide();
});
you can use
$(window).on('click',function(e){
if (!$("li.menuContainer").is(e.target) // if the target of the click isn't the container...
&& $("li.menuContainer").has(e.target).length === 0) // ... nor a descendant of the container
{
$("li.menuContainer div.sub").slideUp();
}
});
Working Demo
Update:
$("div.sub > a.top").on('click',function(e) {
e.preventDefault(); // prevent page from reloading
e.stopPropagation(); // prevent parent click
alert('Here We Are :)');
});
Working Demo
Unfortunately I am having issues with the disappearing of the drop down. I'm currently using toggleClass to add/remove the class on click but I also need this process undone when the menu is blurred ie: clicking anywhere else on the page etc. Here is my jquery code:
$(function() {$('#srt-btn').click(function() {$('ul.toggle-off').toggleClass('toggle-on')});});
<ul id="sort">
<li><a id="srt-btn" class="srt-title">Sort ▾</a>
<ul class="sort-menu toggle-off">
<div class="droid"></div>
<li class="top">Notes</li>
<li>Photos</li>
<li>Videos</li>
<li class="divider"></li>
<li class="btm">Make List</li>
</ul>
</li>
function toggleMenu()
{
$('ul.toggle-off').toggleClass('toggle-on');
}
$(function() {
$('#srt-btn').click(toggleMenu);
$('#srt-btn').blur(toggleMenu);
});
Working example.
you could also use stopPropagation to cancel click events
$(function() {
$('#srt-btn').click(
function(e) {
$('ul.sort-menu').slideToggle();
e.stopPropagation();
}
);
$('.sort-menu li').click(
function(e) {
$('ul.sort-menu').slideUp();
e.stopPropagation();
}
);
$(document).click(
function(){
$('ul.sort-menu').slideUp();
}
);
});
And don't forget about setting your menu options ul to position:absolute else your elements will shift
Here is a jsFiddle
You could try something like this:
var IsInside = false,
$sortMenu = $('#sort'),
$toggleOn = $('.toggle-off');
$sortMenu.on('mouseenter', '#srt-btn', function(){
IsInside = true;
}).on('mouseleave', '#srt-btn', function(){
IsInside = false;
});
$sortMenu.on('click', '#srt-btn', function(){
$toggleOn.toggleClass('toggle-on');
});
$(document).on('click', 'body', function(){
if(!IsInside) {
$toggleOn.removeClass('toggle-on');
}
});
Here a jsFiddle.