So I have some dropdown menus, and I listen for the touchstart event to show them, but the problem is that I don't know when to close them, since I have 2 dropdown menus on the page the problem is that..if a user clicks on a dropdown menu and I display it and after that clicks on another...that gets displayed to.
$(document).ready(function() {
$('nav ul li.sub-menu > a,nav ul li.sub-menu2 > a').bind( "touchstart",function(){
$(this).parent().find('ul').toggle();
$(this).parent().addClass('active_page');
});
});
Any ideas how to close it, when it's best to close it? :-?
The solution was to add an overlay div with position absolute.
$(document).ready(function() {
$('nav ul li.sub-menu > a,nav ul li.sub-menu2 > a').click(function(){
$(this).parent().find('ul').toggle();
$('body').prepend('<div class="overlay" />');
$('.overlay').css({'width' : $('body').css('width'), 'height' : $('body').css('height')});
$(this).parent().addClass('active_page');
return false;
});
$('.overlay').live('touchstart',function(){
$(this).remove();
$('.drop').each(function(){
if($(this).find('ul').css('display') == 'block')
{
$(this).find('ul').toggle();
}
});
//$('nav ul li.sub-menu2 > ul,nav ul li.sub-menu > ul').toggle();
return false;
});
});
Related
I've created a navigation bar with sub menus, using Bootstrap v4.2.1. Hovering OnClick are implemented through Javascript. Problem is whenever I load the page and hover over a submenu item, the menu opens up but appears right below the item. When I click the menu, it disappears and reappears on the right side of the submenu. Ideally, I'd want to have the submenu appear at the right side of the dropdown menu, not appear at the bottom upon initial hover. I'm suspecting that there might be something I might've missed in my Javascript but I could be wrong. Any help/advice would be greatly appreciated.
Here's my fiddle: https://jsfiddle.net/fzev07tb/
//Script to toggle navbar dropdown
$(document).ready(function() {
$('.navbar .dropdown-item').on('click', function(e) {
var $el = $(this).children('.dropdown-toggle');
var $parent = $el.offsetParent(".dropdown-menu");
$(this).parent("li").toggleClass('open');
if (!$parent.parent().hasClass('navbar-nav')) {
if ($parent.hasClass('show')) {
$parent.removeClass('show');
$el.next().removeClass('show');
$el.next().css({
"top": -999,
"left": -999
});
} else {
$parent.parent().find('.show').removeClass('show');
$parent.addClass('show');
$el.next().addClass('show');
$el.next().css({
"top": $el[0].offsetTop,
"left": $parent.outerWidth() - 4
});
}
e.preventDefault();
e.stopPropagation();
}
});
$('.navbar .dropdown').on('hidden.bs.dropdown', function() {
$(this).find('li.dropdown').removeClass('show open');
$(this).find('ul.dropdown-menu').removeClass('show open');
});
});
//Script for OnHover OnClick NavBar Item -->
jQuery(function($) {
if ($(window).width() > 769) {
$('.navbar .dropdown').hover(function() {
$(this).find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();
}, function() {
$(this).find('.dropdown-menu').first().stop(true, true).delay(100).slideUp();
});
$('.navbar .dropdown > a').click(function() {
location.href = this.href;
});
}
});
I have been working on navigation bar and the strangest issue is occurring.
Please use the JSFiddle link to see what I mean.
To duplicate the error:
Run the code when the desktop view is active i.e. when the navigation links are in a line.
Then resize the screen till the "click me" is displayed.
Then press it.
Now run the code while you see the "click me" and press it again.
JS information
jQuery(document).ready(function($) {
// UserCP
$('.rotate').on('click', function() {
$(this).toggleClass("down");
});
$('.nav-start').on('click', function() {
$("#nav2").removeClass("hidden");
$('#nav2 li a').stop().slideToggle('100');
return false;
});
$(document).ready(function() {
$('#nav2 li a').stop().slideToggle('100');
});
$('body').on('click', function() {
$('#nav2 li a').stop().slideUp('100');
});
$("#nav2 li a").click(function(e) {
e.stopPropagation();
});
$(document).click(function(event) {
if (!$(event.target).closest('#nav2 li a').length) {
if ($('#nav2 li a').is(":visible")) {
$('html, body').on('click', function() {
$('#nav2 li a').stop().slideUp('100');
});
};
};
});
});
FIXED - UPDATED JSFiddle! Thanks #Louys Patrice Bessette #Titus #Rick
You are using two click events on this "Click me" li...
(One on .navstart and one on .rotate)
It may not be an issue, but this make the code harder to read.
Then, when you slideToggle(), if you want the submenu to slide down, it has to be hidden.
Because, since you remove the hidden class (probably usefull on load), the submenu is visible.
A Toggle hides it.
I simplified your script to this.
Have a look at this updated Fiddle.
$(document).ready(function() {
// Show submenu on "Click me"
$('.nav-start').on('click', function() {
$('.rotate').toggleClass("down");
$("#nav2").removeClass("hidden");
var subNav = $('#nav2 li a');
if(subNav.css("display")=="block"){
subNav.stop().slideUp('100');
}else{
subNav.stop().slideDown('100');
}
return false;
});
$("#nav2 li a").click(function(e) {
e.stopPropagation();
});
// Hide submenu on document click
$(document).click(function(event) {
if (!$(event.target).closest('#nav2 li a').length && $('#nav2 li a').is(":visible")) {
$('#nav2 li a').stop().slideUp('100');
};
});
});
So I have this code from a previous question: http://jsfiddle.net/928Dj/4/
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
$(this).next('ul').toggle();
});
I was wondering if anyone could tell me how I allow it to still be toggled open and closed, but also make it so if one menu is open and I click to open another menu, it closes the first one, meaning only one menu can be open at any time.
Try to hide the opened ul elements first and then toggle the current element,
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function (e) {
var cache = $(this).next('ul');
$('#filter ul:visible').not(cache).hide();
cache.toggle();
});
DEMO
You can hide all the visible submenus before showing the current one as follows
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
var ul = $(this).next('ul');
$('ul li ul:visible').not(ul).hide();
ul.toggle();
});
Demo
This is the best way. You can also try this:
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function(e) {
$(this).next('ul').toggle();
$(this).parent().siblings().find('.opt').hide();
});
Fiddle
I am not sure toggleClass is the best way to do this, but I have a accordion menu and I am attempting to alternate the icon/image on the right side from a RIGHT arrow to a DOWN arrow.
The first click on the 3 menu items shows the DOWN image (.icon-03) but when I switch between the accordion items it does not go back to the RIGHT arrow image/class (.icon-04).
thoughts?
/* Accordion */
$(document).ready(function () {
$('#accordionFAQ > li > a').click(function(e){
if ($(this).attr('class') != 'active'){
$('#accordionFAQ li ul').slideUp();
$(this).next().slideToggle();
$('#accordionFAQ li a').removeClass('active');
$(this).addClass('active');
//add down arrow
$('> span', this).toggleClass('icon-03 icon-04');
//prevent page reload
e.preventDefault();
}
});
});
Demo JS Fiddle: http://jsfiddle.net/957Fs/
First of all, $(this).attr('class') != 'active' is very inefficient (and possibly fails to work altogether), use $(this).hasClass('active') instead.
After your comment, I re-added the classes - the following should work:
$('#accordionFAQ > li > a').click(function(e){
if (! $(this).hasClass('active') ){
$('.active')
.find('span').toggleClass('icon-03 icon-04')
.end().removeClass('active')
.next().slideUp();
$(this).find('span').toggleClass('icon-03 icon-04')
.end().addClass('active')
.next().slideDown();
//prevent page reload
e.preventDefault();
}
});
When I look at the JSFiddle example it works for me, so I guess it's updated already. I'd like to make a suggestion though: it's perhaps a good idea to just toggle a class (e.g. 'is-active') on your list items and handle the rest with pure CSS. For example:
var $faq = $('#accordionFAQ');
$faq.on('click', '> li > a', function (event) {
$(this).parent().toggleClass('is-active');
});
In your CSS you could do something like this:
#accordionFAQ > li > a span {
// width, height etc
background-position: x y;
}
#accordionFAQ > li.is-active > a span {
background-position: x y;
}
Just an idea; hope it's helpfull.
/* Accordion */
$(document).ready(function () {
var accordionFAQ = $('#accordionFAQ');
// let's use jQuery's .on() rather than .click()
accordionFAQ.find('a').on({
click:function(e){
// prevent the default action
e.preventDefault();
// setup some variables
var that = $(this);
// close open ULs
accordionFAQ.find('ul').slideUp();
// remove .active from other controller
accordionFAQ.find('.active').removeClass('active');
// add .active to clicked controller and show UL
that.addClass('active').next().slideDown();
// remove .right from span
accordionFAQ.find('.right').removeClass('right');
// add .right to current controller's span
that.find('span').addClass('right');
}
});
});
Then, you can have span's default image be the left arrow. and when you add a .right class, it will override the default image with a right arrow using CSS.
hope this helps.
I am using a jQuery Accordion for my sidebar navigation. Currently I have 2 links which both have 'children' beneath them.
Here is my jsFiddle: http://jsfiddle.net/6Eh8C/
You'll notice that when you click 'About Us', the Gallery closes. This shouldn't happen. Gallery should only close when I click 'Gallery'.
How do I fix this?
Here is my jQuery:
jQuery(function($) {
$('#accordion > li > a').click(function (e) {
if ($(this).next('ul').length == 0) {
// link is for navigation, do not set up accordion here
return;
}
// link is for accordion pane
//remove all the "Over" class, so that the arrow reset to default
$('#accordion > li > a').not(this).each(function () {
if ($(this).attr('rel')!='') {
$(this).removeClass($(this).attr('rel') + 'Over');
}
$(this).siblings('ul').slideUp("slow");
});
//showhide the selected submenu
$(this).siblings('ul').slideToggle("slow");
//addremove Over class, so that the arrow pointing downup
$(this).toggleClass($(this).attr('rel') + 'Over');
e.preventDefault();
});
$('.slides_item').children('div').css('background','#ededed')
});
Many thanks for any pointers :-)
I think you just want to remove one line:
$('#accordion > li > a').not(this).each(function () {
if ($(this).attr('rel')!='') {
$(this).removeClass($(this).attr('rel') + 'Over');
}
// Remove this line, you don't want to slide up other uls.
// $(this).siblings('ul').slideUp("slow");
});
Example: http://jsfiddle.net/6Eh8C/1/