mobile hamburger for mobile not closing - javascript

I have 2 issues with this code:
When the submenu on mobile is dropped down the "X" is not closing it back
I sorted the problem with the anchor links (#) that are in the sub level. They close the drop down menu but don't change the "X" back to the "hamburger"
Thank you in advance for your help. The temporary file is this one: http://www.un-poco.com/navtemp
(function($) {
$.fn.menumaker = function(options) {
var cssmenu = $(this),
settings = $.extend({
title: "Menu",
format: "dropdown",
sticky: false
}, options);
return this.each(function() {
cssmenu.prepend('<div id="menu-button">' + settings.title + '</div>');
$(this).find("#menu-button").on('click', function() {
$(this).toggleClass('menu-opened');
var mainmenu = $(this).next('ul');
if (mainmenu.hasClass('open')) {
mainmenu.hide().removeClass('open');
} else {
mainmenu.show().addClass('open');
if (settings.format === "dropdown") {
mainmenu.find('ul').show();
}
}
});
cssmenu.find('li ul').parent().addClass('has-sub');
multiTg = function() {
cssmenu.find(".has-sub").prepend('<span class="submenu-button"></span>');
cssmenu.find('.submenu-button').on('click', function() {
$(this).toggleClass('submenu-opened');
if ($(this).siblings('ul').hasClass('open')) {
$(this).siblings('ul').removeClass('open').hide();
} else {
$(this).siblings('ul').addClass('open').show();
}
});
};
if (settings.format === 'multitoggle')
multiTg();
else
cssmenu.addClass('dropdown');
if (settings.sticky === true)
cssmenu.css('position', 'fixed');
resizeFix = function() {
if ($(window).width() > 768) {
cssmenu.find('ul').show();
}
if ($(window).width() <= 768) {
cssmenu.find('ul').hide().removeClass('open');
}
};
resizeFix();
return $(window).on('resize', resizeFix);
});
};
})(jQuery);
(function($) {
$(document).ready(function() {
if ($(window).width() <= 768) {
$('#cssmenu ul ul li').on('click', function() {
$("#cssmenu ul").hide();
});
}
$("#cssmenu").menumaker({
title: "",
format: "multitoggle"
});
});
})(jQuery);

The problem is with your css styling. you dropdown menu has a padding top. you can find the padding here #cssmenu > ul. The reason why the menu was not closing because the click was not fired on your x icon instead it was on your dropdown div. change the padding to margin which will move the entire div below that should work.

Because in mobile view ul dropdown list is over to hamburger menu that's why your click event not trigger.
Try to use margin instead of padding in your ul styling. See below code -
CSS-
#cssmenu > ul {
margin-top: 43px;
float: right;
}
For getting back hamburger icon on dropdown item click you need to just change your #menu-button class like below code -
JS Code -
(function($) {
$(document).ready(function() {
if ($(window).width() <= 768) {
$('#cssmenu ul ul li').on('click', function() {
// add this line only in your code might be solve your issue
$('#cssmenu').find('#menu-button').addClass('menu-opened').removeClass('menu-closed');
$("#cssmenu ul").hide();
});
}
$("#cssmenu").menumaker({
title: "",
format: "multitoggle"
});
});
})(jQuery);

Related

When clicking on toggle menu it opens but automatically closes

When I click on the toggle menu it opens properly and then it automatically closes. I don't know why it is happening. I have only a little knowledge of JS.
How can I solve this problem?
My code
if ($('.nav-menu').length) {
var $mobile_nav = $('.nav-menu').clone().prop({
class: 'mobile-nav d-lg-none'
});
$('body').append($mobile_nav);
$('body').prepend('<button type="button" class="mobile-nav-toggle d-lg-none"><i class = "icofont-navigation-menu" > < /i></button > ');
$('body').append('<div class="mobile-nav-overly"></div>'); $(document).on('click', '.mobile-nav-toggle', function(e) {
$('body').toggleClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('icofont-navigation-menu icofont-close');
$('.mobile-nav-overly').toggle();
});
$(document).on('click', '.mobile-nav .drop-down > a', function(e) {
e.preventDefault();
$(this).next().slideToggle(300);
$(this).parent().toggleClass('active');
});
$(document).click(function(e) {
var container = $(".mobile-nav, .mobile-nav-toggle");
if (!container.is(e.target) && container.has(e.target).length === 0) {
if ($('body').hasClass('mobile-nav-active')) {
$('body').removeClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('icofont-navigation-menu icofont-close');
$('.mobile-nav-overly').fadeOut();
}
}
});
}
else if ($(".mobile-nav, .mobile-nav-toggle").length) {
$(".mobile-nav, .mobile-nav-toggle").hide();
}
Now its working
if ($('.nav-menu').length) {
var $mobile_nav = $('.nav-menu').clone().prop({
class: 'mobile-nav d-lg-none'
});
$('body').append($mobile_nav);
$('body').prepend('<button type="button" class="mobile-nav-toggle d-lg-none"><i class="icofont-navigation-menu"></i></button>');
$('body').append('<div class="mobile-nav-overly"></div>');
$(document).on('click', '.mobile-nav-toggle', function (e) {
$('body').toggleClass('mobile-nav-active');
$('.mobile-nav-toggle i').toggleClass('icofont-navigation-menu icofont-close');
$('.mobile-nav-overly').toggle();
});
$(document).on('click', '.mobile-nav .drop-down > a', function (e) {
e.preventDefault();
$(this).next().slideToggle(300);
$(this).parent().toggleClass('active');
});
$(document).click(function (e) {
var container = $(".mobile-nav, .mobile-nav-toggle");
if (!container.is(e.target) && container.has(e.target).length === 0) {
// I removed the unnecessary code from here
}
});
} else if ($(".mobile-nav, .mobile-nav-toggle").length) {
$(".mobile-nav, .mobile-nav-toggle").hide();
}

JS destroy triggered function

I coded JS code to restructure html list items for responsive usage:
$(window).resize(function() {
if ($(window).width() <= 640) {
$(function resizenav() {
var lis = $('.menu-header-menu-container ul li:gt(1)').clone();
$('.menu-header-menu-container ul li:gt(1)').remove();
var newLI = $('<li class="toggle-dropdown">more+</li>')
var newUL = $('<ul class="nested"></ul>');
$('.menu-header-menu-container ul').append(newLI);
$(".toggle-dropdown a").append(newUL);
newUL.append(lis);
});
} else if ($(window).width() > 640) {
//destroy function resizenav()
}
});
Code snippet: https://jsfiddle.net/3o32rj1m/3/
I am seeking a way to destroy resizenav() and restore back the navigation original html structure. Any help is much appreciated?
I came up with a solution too... sorry for the delay. Here's the gist:
var isSmall = false;
$(window).on('load resize', function(){
if(!isSmall && $(window).width() <= 640){
var extraListItems = $('#menu-header-menu > li:gt(1)');
if(extraListItems.size() > 0){
var subList = $('<ul>').addClass('nested-list').append(extraListItems).css('display', 'none');
var toggle = $('<li>').addClass('toggle-nested-list').append("<span class='toggle-text'>more+</span>")
.on('click', function(){
subList.toggle();
if(subList.is(':visible')){ $(this).find('.toggle-text').text('less-'); }
else{ $(this).find('.toggle-text').text('more+'); }
});
toggle.append(subList).appendTo('#menu-header-menu');
}
isSmall = true;
}
else if(isSmall && $(window).width() > 640){
var listItems = $('#menu-header-menu .nested-list li');
listItems.appendTo('#menu-header-menu');
$('#menu-header-menu .toggle-nested-list').remove();
isSmall = false;
}
});
Hopefully I didn't miss anything when copying and pasting my code from jsFiddle, but I've got it all there for sure, with comments. Make sure you just resize the output frame in jsFiddle, as resizing the entire browser window has some strange effects there... https://jsfiddle.net/m4n41wkc/
Try this:
var flag = false;
var original = $('.menu-header-menu-container ul').clone().html();
function resizenav() {
var lis = $('.menu-header-menu-container ul li:gt(1)').clone();
$('.menu-header-menu-container ul li:gt(1)').remove();
var newLI = $('<li class="toggle-dropdown">more+</li>')
var newUL = $('<ul class="nested"></ul>');
$('.menu-header-menu-container ul').append(newLI);
$( ".toggle-dropdown a" ).append(newUL);
newUL.append(lis);
};
$(window).resize(function() {
if ($(window).width() <= 640) {
if(!flag) {
resizenav();
flag = true;
}
} else if ($(window).width() > 640) {
if(flag){
$('.menu-header-menu-container ul').html(original);
flag = false;
}
}
});

Mouseup event conflict with visibility toggle

I've created a function that toggles a menu based on its' visibility. I also assigned a mouseup event to the document where the menu closes if the user clicks anywhere outside of it. The problem is when the mouseup event listener is added for the document the toggle no longer works. The visibility test: $menu.is(":visible"); returns false despite the menu being in plain sight. What's going on here?
$(function() {
var $toggleMenu = $(".toggle-menu"),
$menu = $(".menu");
$toggleMenu.on("click", function(e) {
e.preventDefault();
toggleUserMenu();
});
$(document).on("mouseup", function (e) {
if (!$menu.is(e.target) && $menu.has(e.target).length === 0) {
$menu.hide();
}
});
function toggleUserMenu() {
var menuIsVisible = $menu.is(":visible");
if (menuIsVisible) {
$menu.hide();
} else {
$menu.show();
}
}
});
.toggle-menu {
color: #444;
display: inline-block;
margin-bottom: 15px;
text-decoration: none;
}
.menu {
border: 1px solid black;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Toggle Menu
<div class="menu">
Menu Item 1
Menu Item 2
Menu Item 3
</div>
One solution can be by preventing the mouseup in the conflicting area to bubble up.
$(function() {
var $toggleMenu = $(".toggle-menu"),
$menu = $(".menu");
$toggleMenu.on("click", function(e) {
e.preventDefault();
toggleUserMenu();
});
$toggleMenu.on("mouseup", function(e) {
e.preventDefault();
e.stopPropagation();
});
$(document).on("mouseup", function (e) {
if (!$menu.is(e.target) && $menu.has(e.target).length === 0) {
$menu.hide();
}
});
function toggleUserMenu() {
var menuIsVisible = $menu.is(":visible");
console.log(menuIsVisible);
if (menuIsVisible) {
$menu.hide();
} else {
$menu.show();
}
}
});
$toggleMenu.on("mouseup", function(e) {
e.preventDefault();
e.stopPropagation();
});
This will catch the mouseup that is fired along with the click on Toggle Button and stops it from bubbling up to document. preventDefault() doesn't have any specific purpose here, It came with your code that I copied :)
Here is a fiddle
you run $menu.hide twice and it is problem.
$(function() {
var $toggleMenu = $(".toggle-menu"),
$menu = $(".menu");
$toggleMenu.on("click", function(e) {
e.preventDefault();
toggleUserMenu();
});
$(document).on("mouseup", function (e) {
console.log("Event is still firing");
if (!$menu.is(e.target) && $menu.has(e.target).length === 0) {
//if you commment this the code work.
// $menu.hide();
}
});
function toggleUserMenu() {
var menuIsVisible = $menu.is(":visible");
if (menuIsVisible) {
$menu.hide();
} else {
$menu.show();
}
}
});
.toggle-menu {
color: #444;
display: inline-block;
margin-bottom: 15px;
text-decoration: none;
}
.menu {
border: 1px solid black;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Toggle Menu
<div class="menu">
Menu Item 1
Menu Item 2
Menu Item 3
</div>

Javascript Overlapping, Set Z order of Jquery

Ok I'm stuck. I am using opencart, and I have added the jquery zoom plugin so that the images can be magnified.
Since doing this it is now conflicting with the menu, I cant figure out what to do?
Is there any sort of way of setting a sort order of the jquery on the page. I have tried the JQuery topZIndex plugin but this failed to work.
PS: I am using the z-index in the css also.
I have tried:
#menu > ul > li {
position: relative; i also tried absolute
float: left;
z-index: 100;
}
For the jqzoom I am using:
$(function() {
var options =
{
zoomType: 'innerzoom',
zoomWidth: 800,
zoomHeight: 400,
showEffect:'fadeout',
hideEffect:'fadeout',
fadeoutSpeed: 'slow',
preloadImages: 'true',
preloadText: 'Loading...'
}
$(".jqzoom").jqzoom(options);
});
My problem is that the dropdown menu should go over the jqzoom image, however the drop down menu appears behind the jqzoom image. I was wondering if there is a means to set a z-index to jquery to set it to the back or something?
I have tried playing with the topZIndex() jquery plugin and used $(".jqzoom").topZIndex( { increment: 0 } ); and $(".jqzoom").topZIndex( { increment: 100 } );
The javascript for the menu is:
$('#menu ul > li > a + div').each(function(index, element) {
// IE6 & IE7 Fixes
if ($.browser.msie && ($.browser.version == 7 || $.browser.version == 6)) {
var category = $(element).find('a');
var columns = $(element).find('ul').length;
$(element).css('width', (columns * 143) + 'px');
$(element).find('ul').css('float', 'left');
}
var menu = $('#menu').offset();
var dropdown = $(this).parent().offset();
i = (dropdown.left + $(this).outerWidth()) - (menu.left + $('#menu').outerWidth());
if (i > 0) {
$(this).css('margin-left', '-' + (i + 5) + 'px');
}
});
// IE6 & IE7 Fixes
if ($.browser.msie) {
if ($.browser.version <= 6) {
$('#column-left + #column-right + #content, #column-left + #content').css('margin-left', '195px');
$('#column-right + #content').css('margin-right', '195px');
$('.box-category ul li a.active + ul').css('display', 'block');
}
if ($.browser.version <= 7) {
$('#menu > ul > li').bind('mouseover', function() {
$(this).addClass('active');
});
$('#menu > ul > li').bind('mouseout', function() {
$(this).removeClass('active');
});
}
}
$('.success img, .warning img, .attention img, .information img').live('click', function() {
$(this).parent().fadeOut('slow', function() {
$(this).remove();
});
});
});
Browsing through the jqzoom source code, the zoom popup window has a z-index of 5001. You need to set your dropdown to something higher than that.
Did you try doing:
$("#your_dropdown_menu_id").css("z-index", 99999);

jQuery - Auto Scroll gallery

I'm in a bit of trouble and need help. I basically have a carousel (scrolling) type gallery with three images. You only see one image at a time, and to see the next image, you have to click the link that relates to that image or click on the current image itself to see the next image. This would make it scroll one image along and the li containing the image gets a class of 'active'.
I've been asked to add Auto Scroll functionality and I'm a bit stuck?
They basically want it to auto scroll 1 image every 2/3 seconds if the user is not using the links to scroll the gallery.
Any help would be MASSIVELY appreciated :)
I am not allowed to use a plug-in or anything either, I have to alter the current code :S
To be honest I know this is probably a hopeless case, but if there is somebody out there that could solve this it would be really appreciated.
The scrolling/gallery functionality is towards the bottom.
$(document).ready(function() {
Cufon.replace('.section-1 h2, .section-2 h3, .follow h3, .follow h4, .overlay h3, .overlay h4');
$.friends.people.init();
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest($.friends.people.overlay.request);
});
$.friends.people = {
init: function() {
this.slide_anchors();
this.gallery.init();
$.friends.tooltips.init();
this.overlay.init();
this.label_value.init();
},
slide_anchors: function() {
$('a.down, a.up').click(function(event) {
event.preventDefault();
var speed = 400;
var target = $(this).attr('href');
var dest = $(target).offset().top;
$('html:not(:animated), body:not(:animated)').animate(
{ scrollTop: dest },
speed,
function() {
window.location.hash = target;
}
);
return false;
});
},
overlay: {
email_btn: null,
sms_btn: null,
init: function() {
this.close();
$('a.sms').click(function() {
__doPostBack($.friends.people.overlay.sms_btn, '');
$('.overlay-wrap').fadeIn(250, function(){$.friends.people.label_value.init()});
return false;
});
$('a.email').click(function() {
__doPostBack($.friends.people.overlay.email_btn, '');
$('.overlay-wrap').fadeIn(250, function(){$.friends.people.label_value.init()});
return false;
});
$('.section-2 a.sms, .section-2 a.email').click(function() {
$('a.up').click();
return false;
});
},
close: function() {
$('a.overlay-close').click(function() {
$('.overlay-wrap').fadeOut(250);
return false;
});
},
request: function() {
$.friends.people.label_value.init();
$.friends.people.overlay.close();
Cufon.replace('.overlay h3, .overlay h4');
$.friends.external_links();
}
},
label_value: {
init: function() {
$('.labelValue').each(function() {
var text = $(this).text().replace(/^\s+|\s+$/g, '');
var $textbox = $('#'+$(this).attr('for'));
if($textbox.val() == "") $textbox.val(text);
$textbox.focus(function() {
if($(this).val() == text) $(this).val("");
});
$textbox.blur(function() {
if($textbox.val() == "") $textbox.val(text);
});
});
}
},
gallery: {
i: null,
width: null,
moving: false,
speed: 500,
init: function() {
this.i = $('.section-2 .col-2 .images img').length;
if (this.i > 1) {
this.resize_div();
this.add_nav();
}
},
resize_div: function() {
this.width = $('.section-2 .col-2 .images img:first').width();
$('.section-2 .col-2 .images').width((this.i * this.width) + 'px');
},
add_nav: function() { /* rewrite this with .each() */
var html = '<ul class="image-nav">';
for (x = 0; x < this.i; x++) {
html = html + '<li></li>';
}
html = html + '</ul>';
$('.section-2 .col-2').append(html).find('li:first').addClass('active');
$('.section-2 .col-2 ul.image-nav li a').click(function() {
if (!$.friends.people.gallery.moving) {
$.friends.people.gallery.moving = true;
$.friends.people.gallery.scroll($('.section-2 .col-2 ul.image-nav li a').index(this));
}
return false;
});
$('.section-2 .col-2 .images img').click(function() {
if (!$.friends.people.gallery.moving) {
$.friends.people.gallery.moving = true;
var current = $('.section-2 .col-2 .images img').index(this);
if (current >= ($('.section-2 .col-2 .images img').length - 1)) {
var target = 0; console.log('asd');
} else {
var target = current + 1;
}
$.friends.people.gallery.scroll(target);
}
return false;
});
},
scroll: function(img) {
$('.section-2 .col-2 ul.image-nav li').removeClass('active');
$('.section-2 .col-2 ul.image-nav li:eq(' + img + ')').addClass('active');
$('.section-2 .col-2 .images').animate(
{ marginLeft: -($.friends.people.gallery.width * img) },
$.friends.people.gallery.speed,
function() {
$.friends.people.gallery.moving = false;
}
);
}
}
}
You could try using a setInterval:
window.setInterval(function() {
// calling your scrolling-to-next-image function
}, 2000);
This would call an anonymus function including your "scroll-to-next-image" function every 2 seconds.
Probably you need a clearInterval when the user starts using the "next" / "previous" buttons again.
More information on this topic can be found here: https://developer.mozilla.org/en/DOM/window.setInterval

Categories