responsive submenu open on click not working - javascript

I have converted my first HTML to WordPress website and have a responsive sub menu which is not opening properly on mobile because obviously there is no hover functionality. I have looked up solutions and have come to nothing as my JavaScript knowledge is non existent therefore copying and pasting code from examples on here is not getting me the result I want to achieve.
The menu I am trying to fix is on the following website:
https://www.piogroup.in/wordpress/
I have 2 parents which are "about" and "products" and they are not clickable links. So far I have tried the following code:
$(document).ready(function(){
$("#menu-item-74").off("click").on("click", function() {
$(".sub-menu").fadeToggle("slow");
});
})
$(document).ready(function(){
$("#menu-item-72").off("click").on("click", function() {
$(".sub-menu").fadeToggle("slow");
});
})
and then added this as well:
var $handle = $('.sub-menu').prev();
var opened = 0;
$handle.on('click', function(e){
if (opened) {
window.location.href = $(this).attr('href');
} else {
e.preventDefault();
e.stopPropagation();
$('.sub-menu').slideToggle();
opened = 1;
}
});
$('html').on('click', function(){
if (opened) {
$('.sub-menu').slideToggle();
opened = 0;
}
});
I am not sure if I am meant to put up any other files but can do so.

#R Alexander if I understand you correctly, Your sub menu is not working on mobile devices. Below code may be help you out.
minWidth = $(window).width();
if(winWidth < 768){
$(".menu-main-menu-container li").click(function(){
$(".menu-main-menu-container li ul").slideToggle();
$(".menu-main-menu-container li ul").parent().siblings().children(".menu-main-menu-container li ul").slideUp();
});
}

I went through your code and there are some logical inconsistencies.
First of all you should change this as follows:
var $handle = $('.sub-menu').prev();
var opened = 0;
$handle.on('click', function(e) {
if (opened) {
window.location.href = $(this).attr('href');
} else {
e.preventDefault();
e.stopPropagation();
$(this).next().slideToggle();
opened = 1;
}
});
This makes the particular clicked element to slideToggle instead of all the .sub-menu elements.
Then to emulate the closing of the drop downs use this:
$('html').on('click', function() {
if (opened) {
$('.sub-menu').slideUp();
opened = 0;
}
});

Related

jQuery slidetoggle keeps toggling after window resize/ready combined

I want to add slidetoggle only when screen size is less than 768px. I also want this to work when user for some reason would resize the window manually.
I have come across a bug with jQuery where my dropdown menu will keep toggling after I resize the window. I've looked up this issue and tried adding return false; to click function and adding position: relative; overflow:hidden; to toggleable div(these should be a workaround according to some forums). No luck there. What causes this bug. I will include the whole function with the click function
//Call function on ready and window resize
$(document).ready(navigationMobile);
$(window).on('resize', navigationMobile);
function navigationMobile() {
const windowWidth = $(window).width();
if (windowWidth < 768) {
//Remove href from main link and add it as a "all" link in menu
$(".js-second-title").each(function () {
const currentHref = $(this).attr('href');
$(this).removeAttr('href');
if ($(this).siblings('ul').find('.js-all-link').length === 0) {
$(this).siblings('ul').prepend(`<li><a class="js-all-link" href="${currentHref}">All</a></li>`);
}
});
//When clicked on main link open menu
$(".js-second-title").click(function () {
$(this).siblings('.js-menu').slideToggle();
$(this).toggleClass('js-open');
});
} else {
//Add href back to main link
$('.js-second-title').each(function () {
if ($(this).attr('href') === undefined) {
const allHref = $(this).siblings('ul').find('.js-all-link').attr('href');
$(this).attr('href', `${allHref}`);
$(this).siblings('ul').find('.js-all-link').remove();
}
});
}
}
Cheers!
I don't exactly know what is causing this bug. But I came up with this workaround.
//Remove href from main link and add it as a "all" link in menu
$(".js-second-title").each(function () {
$(this).addClass('js-closed');
const currentHref = $(this).attr('href');
$(this).removeAttr('href');
if ($(this).siblings('ul').find('.js-all-link').length === 0) {
$(this).siblings('ul').prepend(`<li><a class="js-all-link" href="${currentHref}">All</a></li>`);
}
});
//When clicked on main link open menu
$(document).on("click", '.js-second-title.js-closed', function (e) {
$(this).removeClass('js-closed');
$(this).siblings('.js-menu').slideDown();
$(this).addClass('js-open');
});
$(document).on("click", '.js-second-title.js-open', function (e) {
$(this).siblings('.js-menu').slideUp();
$(this).removeClass('js-open');
$(this).addClass('js-closed');
});
So here I am basically extening SlideToggle function. Before I call slide functions on click I give each js-second-title classes an extra class .js-closed so the browser is aware that the menu is closed. After that I call slideDown function when I click on closed menu title and slideUp when I click on open menu title.
I do not think that this is the best or most sematic solution so I would like to keep this topic open.

Menu in appme theme is not synching with hashing id in wordpress

I am using appme theme on wordpress and everything is working good except for the active menu.
https://themes.athenadesignstudio.com/?theme=appme_wp
if you click on the link and click on the menu, you can see that it's not syncing with what it is clicked. For ex: if you click on feature, home will be active, if you click on screen shot, feature will be active and behaves different on different browser as well.
In the main.js file of appme folder, go to this line and as you can see the scrollTop: h-offset, so for a work around, i have changed it to scrollTop: (h-offset)+10. This will scroll the section a little more and we are set like this untill fix.
//Menu
menu:function() {
//Slick nav
jQuery(".main-navigation").slicknav({
prependTo:"#responsive-menu",
label:"",
closeOnClick:true
});
//Submenu
jQuery(".nav li").on("mouseenter", function() {
jQuery(this).children("ul").stop().slideDown(200);
});
jQuery(".nav li").on("mouseleave", function() {
jQuery(this).children("ul").stop().slideUp(200);
});
//Header menu
jQuery(document).on("click", "#navigation ul li a, #responsive-menu ul li a", function() {
try {
var id = jQuery(this).attr("href");
var h = parseFloat(jQuery(id).offset().top);
var offset = parseInt(jQuery("body").data("offset"), 10);
jQuery("body, html").stop().animate({
scrollTop:(h-offset)+10
}, 800);
return false;
} catch(err) {}
});
//Sticky navigation
if (AppMeOptions.navigation==="sticky") {
jQuery(window).scroll(function() {
if (jQuery(window).scrollTop()>200) {
jQuery(".navbar").addClass("sticky-header");
} else {
jQuery(".navbar").removeClass("sticky-header");
}
});
}
},

Getting left nav link to stay open and active

Currently I have a left nav menu that works:
$('.navContainer li div').click(function () {
var $t = $(this);
var $next = $t.next('.navtoggle');
$('.navtoggle').not($next).slideUp('active');
$next.slideToggle(400);
});
The problem is, the links on the last level need to be highlighted based on the page that is on and for the nav to stay open. The script above, once clicked, will load the corresponding page and close the navigation. I have tried using the cookies and couldn't get it to work. I've tried using document ready, and it works until the page reloads and it just resets. So I am kinda stuck. I've tried:
$(document).ready(function () {
$('.navContainer .navtoggle li a').click(function (e) {
$(e.target).addClass('current');
});
});
.navContainer .navtoggle li a, is the last links to be used to keep it activated. I'm adding class 'current' since active is being used in the navigation. This will change the link color and thats it. I've also tried a:target and a:active, but everything just keeps getting reset.
I was able to find an answer here http://www.itworld.com/article/2832973/development/setting-an-active-menu-item-based-on-the-current-url-with-jquery.html and change a couple things to make this work. Wanted to give most of the credit to that webpage but I was able to make it work using this as the base. The final code is:
$(function () {
setNavigation(); });
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
$(".navContainer .navtoggle li a").each(function () {
var href = $(this).attr('href');
if (path.substring(0, href.length) === href) {
$(this).closest('li a').addClass('current');
$(this).closest('.navtoggle').css('display', 'block');
}
}); }

jQuery: click event can't work

I'm trying to change the area and the button value by clicking the different Tabs.
Here's my question:
First loading the page, the button effect is working, but after clicking the other Tabs, it can't work.
On clicking the second Tab, then clicking the area button, you'll find it can't work.
Here's part of my code:
$(document).ready(function () {
var _showTab = 0;
$('ul.tabs').each(function () {
$(this).find('li').each(function (k) {
if (k != 0) {
$($(this).find("a").attr("href")).hide();
} else {
$(this).addClass('active').append("<span class='tr_icon'></span>");
}
})
});
$('ul.tabs li').click(function () {
var $this = $(this),
_clickTab = $this.find('a').attr('href');
$this.addClass('active').append("<span class='tr_icon'></span>").siblings('.active').removeClass('active').children().remove('span');
// $(_clickTab).stop(false, true).fadeIn().siblings().hide();
paidChange();
areaChange();
return false;
}).find('a').focus(function () {
this.blur();
});
});
Here's all of my code:
Sorry for my poor English, and I hope you'll understand what I mean.
document.on click will trigger on dynamically added tabs.
Change
$('ul.tabs li').click(function() { });
to
$(document).on("click", 'ul.tabs li', function(){});

How to close an open collapsed navbar when clicking outside of the navbar element in Bootstrap 3?

How can I close an open collapsed navbar on clicking outside of the navbar element? Currently, the only way to open or close it is by clicking on the navbar-toggle button.
See here for an example and code:
So far, I have tried the following which doesn't seem to work:
jQuery(document).click(function() {
});
jQuery('.navbar').click(function(event) {
jQuery(".navbar-collapse").collapse('hide');
event.stopPropagation();
});
Have a look that:
$(document).ready(function () {
$(document).click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$("button.navbar-toggle").click();
}
});
});
Your fiddle works with that: http://jsfiddle.net/52VtD/5718/
Its a modified version of this answer, which lacks the animation and is also a tiny bit more complicated.
I know, invoking the click() isn't very elegant, but collapse('hide') did not work for me either, and i think the animation is a bit nicer than adding and removing the classes hardly.
The accepted answer doesn't appear to work correctly. It only needs to check if "navbar-collapse" has the "in" class. We can then fire the collapse method as expected by using our reference to the navbar.
$(document).click(function (event) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$navbar.collapse('hide');
}
});
Using this works for me.
$(function() {
$(document).click(function (event) {
$('.navbar-collapse').collapse('hide');
});
});
The solution I decided to use was taken from the accepted answer here and from this answer
jQuery('body').bind('click', function(e) {
if(jQuery(e.target).closest('.navbar').length == 0) {
// click happened outside of .navbar, so hide
var opened = jQuery('.navbar-collapse').hasClass('collapse in');
if ( opened === true ) {
jQuery('.navbar-collapse').collapse('hide');
}
}
});
This hides an opened collapsed nav menu if the user clicks anywhere outside of the .navbar element. Of course clicking on .navbar-toggle still works to close the menu too.
Converted nozzleman's answer for Bootstrap 4(.3.1):
$(document).ready(function () {
$(document).click(
function (event) {
var target = $(event.target);
var _mobileMenuOpen = $(".navbar-collapse").hasClass("show");
if (_mobileMenuOpen === true && !target.hasClass("navbar-toggler")) {
$("button.navbar-toggler").click();
}
}
);
});
Placed in the ngOnInit().
When the document is loaded, this code waits for click events. If the mobile menu dropdown is open (i.e. the collapsible part of the navbar has the "show" class) and the clicked object (target) is not the mobile menu button (i.e. does not have the "navbar-toggler" class), then we tell the mobile menu button it has been clicked, and the menu closes.
stopPropagation() is not always the best solution. Rather use something like:
jQuery(document.body).on('click', function(ev){
if(jQuery(ev.target).closest('.navbar-collapse').length) return; // Not return false
// Hide navbar
});
I think it's dangerous to assume that you never want to listen to any other event from the .navbar. Which is impossible if you use stopPropagation().
I had a scenario where I had plain text and I didn't want the panel to close if a user clicks on the plain text on accident. The other answers here will close the panel even if you click on the text of an item that isn't a link.
To fix this I added on to Paul Tarr's answer by wrapping the solution in a check to see whether or not the click occurred anywhere inside:
if ($(event.target).parents(".navbar-collapse").length < 1) { }
The full code would become:
$(document).click(function (event) {
if ($(event.target).parents(".navbar-collapse").length < 1) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle")) {
$navbar.collapse('hide');
}
}
});
In this demo fiddle you can see that if you click on a non-link inside of the panel it won't collapse it.
For latest Bootstrap, this is the correct answer.
$(document).click(function (event) {
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("show");
if (_opened === true && !clickover.hasClass("navbar-toggler")) {
$navbar.collapse('hide');
}
});
It reads if .navbar-collapse has the word show in classes (which means menu is opened) and hides the navbar when you click/tap anywhere.
I've added a condition to #nozzleman's answer to check if the tap or click has been made on any element within the menu, and if that's the case, not to collapse it.
$(document).ready(function () {
$(document).click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle") && clickover.parents('.navbar-collapse').length == 0) {
$("button.navbar-toggle").click();
}
});
});
The following code works for me and the advantage is that on small screens, it does not hide the .collapse when you click on its nav parent with .navbar .navbar-expand classes:
$(document).click(function (e) {
if($('.collapse').hasClass('show') && !$('nav').is(e.target) && $('nav').has(e.target).length === 0){
$('.navbar-toggler').click()
}
})
Vanilla Javascript.
Working on Bootstrap 5.2.
window.onload = function () {
document.addEventListener("click", function (event) {
// if the clicked element isn't child of the navbar, you must close it if is open
if (!event.target.closest("#navbar_id") && document.getElementById("navbarSupportedContent").classList.contains("show")) {
document.getElementById("hamburger_menu_button").click();
}
});
}
https://jsfiddle.net/j4tgpbxz/
You just need to add an id to the navbar element, and then check if the clicked element is a child of that same navbar and the content you want to hide (dropdown) is being shown.
For Bootstrap 4
Bootstrap 4 doesn't have an in class. This is Coffeescript.
$(document).click (e)->
#console.log e.target
unless $('#toggle-button').has(e.target).length || $('#toggle-menu').has(e.target).length
$('#toggle-menu').collapse('hide')
So basically, unless you click the button or the menu, close the menu.
Note: Strange, on iOS clicking on text doesn't register a click event, nor a mouseup event. Clicking on an image does fire events though.
For Bootstrap 4:
$(document).click(function(event) {
$(event.target).closest(".navbar").length || $(".navbar-collapse.show").length && $(".navbar-collapse.show").collapse("hide")
});
$(document).click(function (event) {
if ($('.navbar-collapse').attr('aria-expanded') == "true") {
$('.navbar-collapse:visible').click();
}
});
$(window).click(function (e) {
if ($(e.target).closest('.codehim-dropdown').length) {
return;
}
if ($(e.target).closest(offCanvas).length) {
return;
}
//check if menu really opened
if ($(hamburger).hasClass("active")) {
closeMenu();
}
$(dimOverlay).fadeOut();
$(".menu-items").slideUp();
$(".dropdown-heading").removeClass("active");
});
I had some problems with some answers here, and I would like to also be able to close the expanded menu on demand. So I did it with a simple function, and simulating the click.
function closeMenu(){
element = document.getElementById('nav_top');
if(element){
if(element.classList.contains('show')){
document.getElementById('navbar_toggler').dispatchEvent(new CustomEvent('click'));
}
}
}
$(document).ready(function () {
$(document).click(function (event) {
closeMenu();
});
});
Using this method you can close it when clicked outside, but also you can call the closeMenu() at any time from any other function.
I know its quite awhile for the answer. But I think the answer here could helps.
Lets say the condition: if user want to close the navbar when click outside but not when user click any element inside of the navbar
use the event.target and target the element's closest classname whether its has the navbar class or not. If yes which means user is clicking element inside of the navbar and not to close the navbar.
$(function() {
$(document).click(function (event) {
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse collapse show");
if (_opened === true && clickover.closest('.navbar').length === 0) {
$(".navbar-collapse").collapse('hide');
}
});
});

Categories

Resources