Sub-menu navigation toggle bug - javascript

I have a main navigation menu with a sub-menu that appears on hover, the problem I have is that on hovering on and off the menu sub-menu flickers between the slide and fade states provided by its function (menuHover) - I have a fiddle which is viewable here
The function itself is:
///<summary>
///drop down menu navigation
///</summary>
var menuHover = {
//initialise our function
init: function(){
var menuItem = $(".navItem");
//each menu item
menuItem.each(function(){
//checks to see if we have sub-navigation items
var $this = $(this),
hasSub = $this.children(".subNav"),
isSub = hasSub.length > 0;
//toggle visibility on sub items when hovered
if(isSub){
$this.hover(
//on hover
function(){
hasSub.slideDown("fast");
},
// off hover
function(){
hasSub.fadeOut(350);
});
}
});
}
};
Any help would be gratefully appreciated!

Stop using JS for menus! Use CSS instead!
The basics: http://www.seoconsultants.com/css/menus/tutorial/
Example I made(Copyrighted, do not just copy it): http://tinkerbin.com/W0iL32hh

Related

How to change which ionicon is displayed upon menu toggle

What I'm trying to do is have the 'menu-outline' ionicon display on my website, until it is clicked and the menu is toggled, where the 'close-outline' icon will replace it, and vice versa. I'm using jQuery.
I know you can toggle classes, but my ionicons are not defined by their classes, but by their names:
<a class="menu-button js-menu-button"><ion-icon name="menu-outline"></ion-icon></a>
My jQuery so far only toggles the menu but does nothing with the icon:
$(".js-menu-button").click(function() {
var nav = $(".js-main-nav");
var icon = $(".js-menu-button ion-icon");
/* appear and disappear */
nav.slideToggle(200);
});
Is there any way I can toggle the name of the icon? Or is there another way to do this? Thanks for any suggestions.
You can toggle the name of the icon like this:
$(".js-menu-button").click(function() {
var nav = $(".js-main-nav");
var icon = $(".js-menu-button ion-icon");
if (icon.attr("name") == "menu-outline") {
icon.attr("name", "close-outline");
}
else {
icon.attr("name", "menu-outline")
}
/* appear and disappear */
nav.slideToggle(200);
});
Another possibility is this:
$(".js-menu-button").click(function() {
var nav = $(".js-main-nav");
var icon = $(".js-menu-button ion-icon");
icon.attr('name', function(index, attribute){
return attribute == "menu-outline" ? "close-outline" : "menu-outline";
});
/* appear and disappear */
nav.slideToggle(200);
});

From Hover to click in wordpress menu

I used a theme that I changed , now I want to show sub menu onClick and not on hover, I'm not good at javascript but I think that this code is about the navigation menu:
//top menu works only on 1 level, the other submenus are hidden from css
//on tablets, wide level 3 submenus may go out of screen
var tdMenu = {};
(function(){
'use strict';
tdMenu = {
//submenu items (used on unbind)
_itemsWithSubmenu: null,
//main menu (used on unbind)
_mainMenu: null,
//on touch - when you click outside the menu it will close all menus
_outsideClickArea: null,
_outsideClickExcludedAreas: '#td-header-menu .sf-menu, #td-header-menu .sf-menu *, .menu-top-container, .menu-top-container *',
//added when menu is open
_openMenuClass: 'sfHover',
_openMenuBodyClass: 'td-open-menu',
/*
* initialize menu
*/
init: function() {
//get menu items
var mainMenu = jQuery('#td-header-menu .sf-menu'),
menus = jQuery('#td-header-menu .sf-menu, .top-header-menu'),
menuLinks = menus.find('.menu-item-has-children > a, .td-mega-menu > a');
//add dropdown arrow on items with submenu
menuLinks.append('<i class="td-icon-menu-down"></i>');
//main menu width adjustment (top menu will use css)
mainMenu.supersubs({
minWidth: 10, // minimum width of sub-menus in em units
maxWidth: 20, // maximum width of sub-menus in em units
extraWidth: 1 // extra width can ensure lines don't sometimes turn over
});
//add sf-with-ul class to all anchors
menuLinks.addClass('sf-with-ul');
//add sf-js-enabled class
menus.addClass('sf-js-enabled');
//hide all submenus
menuLinks.parent().find('ul').first().css('display', 'none');
//set unbind items
tdMenu._mainMenu = mainMenu;
tdMenu._itemsWithSubmenu = menuLinks;
tdMenu._outsideClickArea = jQuery(window).not(tdMenu._outsideClickExcludedAreas);
//initialize menu
tdMenu._setHover(menuLinks, mainMenu);
},
How can I change to to be onclick?
I'm not very good at Javascript
Try to change :
tdMenu._setHover(menuLinks, mainMenu);
into :
tdMenu._setOnClick(menuLinks, mainMenu);
Or something like that, you can try to find the correct method in the theme library

What is wrong with this code, trying a click menu?

So there is a left side vertical menu. And it has a small options button. When clicked, it should open a div which will have various filter options. Now, i need it to appear when clicked, and disappear when either the options button is clicked again, or the user clicks anywhere outside the div.
So i have the following code.
//options filter menu animation
$('#optionsmenu').hide(); //hides the menu
$('.optionsfilters').click(function(e){
var $this = $('#optionsmenu');
$this.show();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
$(':not(.optionsfilters)').click(function(e){
$('#optionsmenu').hide();
});
The HTML is
<div id="sidebartitle">
<h2>Organisation</h2>
<a id="optionsfilters" class="optionsfilters">Options</a>
</div>
<div id="optionsmenu" class="optionsfilters">
<h3>Add New</h3>
<ul>
<label>Year</label>
<select>
<option>2000</option>
<option>2001</option>
<option>2002</option>
<option>2003</option>
<option>2004</option>
<option>2005</option>
</select>
</ul>
</div>
Its not working together, i.e. the two javascript functions, the first one works alone, when the second one is commented out. The second one works, if i comment out the hide part, and add an alert message. But together, they don't work.
Whats the conflict?
Ok there are a few things you will want to do:
1) If you want the original button to close the menu you will want to use .toggle() rather than .show()
2) You will want to detect a click on the document, to hide the options menu. Which will not be called if it is the options menu that is clicked due to the e.stopPropagation(); (point 4 below).
$(document).click(function() {
$('#optionsmenu').hide();
});
3) You also want to check (as both have the same class) that the .optionsfilters that was clicked was not the filters themselves (otherwise this will stop you clicking an option).
if( e.target !== this ) {
return;
}
4) Use e.stopPropagation(); to stop the event bubbling up to the parents (or document).
This should be what you are looking for:
$('#optionsmenu').hide(); //hides the menu
$('.optionsfilters').click(function(e){
e.stopPropagation();
if( e.target !== this ) {
return;
}
var $this = $('#optionsmenu');
$this.toggle();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
$(document).click(function() {
$('#optionsmenu').hide();
});
Here is the working fiddle: http://jsfiddle.net/lee_gladding/pny4vq26/
Here you go
//options filter menu animation
var filters = $('.optionsfilters');
var options = $('#optionsmenu');
options.hide(); //hides the menu
filters.click(function(e){
$('#optionsmenu').toggle();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
_this.css('top', top);
_this.css('left', left);
});
$(document).click(function(e) {
if (!filters.is(e.target) && filters.has(e.target).length === 0) {
options.hide();
}
});
http://jsfiddle.net/6e86hdwc/
a classic demonstration of stopPropagation in jQuery (http://api.jquery.com/event.stoppropagation/)
here is a fiddle that simplify this: http://jsfiddle.net/ymzrocks/98082xk7/1/
in short:
$('.optionsfilters').click(function(e)
{
e.stopPropagation(); // or elese it will fire the parent event
var $this = $('#optionsmenu');
$this.show();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
The problem is mainly that both your click handlers run and one shows the menu then the other one hides it.
Why? Because that's not a good selector. Until you reach the element with the class .optionsfilters your click goes through body, #sidebartitle and then it reaches the element a. And since the parents of that element don't have the class .optionsfilters, it will hide the menu.
So I changed the code a little. First of all don't use the class as a click handler. Use the IDs
$('#optionsfilters').click(function (e) { // ID of options
var $this = $('#optionsmenu');
$this.toggle(); // toggle show/hide when click on it
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
The you need to check when you click outside of the #optionsmenu. For that you attach a click handler on document and check the e.target
$(document).click(function (e) {
if (!$(e.target).closest('.optionsfilters').length)
$('#optionsmenu').hide();
});
If the e.target itself is not .optionsfilters and is not a child of a parent with that class then you hide the menu.
Working example below.
//options filter menu animation
$('#optionsmenu').hide(); //hides the menu
$('#optionsfilters').click(function (e) {
var $this = $('#optionsmenu');
$this.toggle();
var left = $('#sidebar').css('width'),
top = $(this).offset().top;
$this.css('top', top);
$this.css('left', left);
});
$(document).click(function (e) {
if (!$(e.target).closest('.optionsfilters').length) $('#optionsmenu').hide();
});
#optionsmenu{
background:lightblue;
}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="sidebartitle">
<h2>Organisation</h2>
<a id="optionsfilters" class="optionsfilters">Options</a>
</div>
<div id="optionsmenu" class="optionsfilters">
<h3>Add New</h3>
<ul>
<label>Year</label>
<select>
<option>2000</option>
<option>2001</option>
<option>2002</option>
<option>2003</option>
<option>2004</option>
<option>2005</option>
</select>
</ul>
</div>
Be careful using :not for any other elements, because if - for example - you click the dropdown, the sidebar hides again, which I doubt you want to happen.
It'd be better to define areas you want to make the sidebar hide when clicked, like the main content area.
Also since you use the class .optionsfilters on your sidebar menu, when you click in there the sidebar will hide again.
Try this
JS Fiddle.
I can't understand, but if your menu is hide (first instruction in your js), how can you click on it for show it?
EDIT: Didn't noticed the class attriute on previous div. My fault.

Close an active state on a button when pressing a secondary button

I am having issues in closing the active state on my footer button. When you click footer it will slide a hidden div pushing the fix div up and changing the word footer to close, with a background color for its active state. Once you click close the div will slide down and the wording will change back to footer and the active state is hidden.
The issue
when I click the menu button it does not change the active state on the footer button. The div will slide down but the wording will not change from close to footer and the background color will not change.
The JS
$('#more').click(function () {
var open = $('header').is('.open');
$('#footerPanel')['slide' + (open ? 'Up' : 'Down')](400);
$('header').animate({
bottom: (open ? '-' : '+') + '=120'
}, 400, function () {
$('header').toggleClass('open');
});
});
$('#menu').click(function () {
if ($('header').is('.open')) {
$('header').removeClass('open').animate({'bottom': "-=120"});
$('#footerPanel').slideUp(400);
}
});
$('.footerButton').click(function(){
var $this = $(this);
$this.toggleClass('footerButton');
if($this.hasClass('footerButton')){
$this.text('Footer');
}
else
{
$this.text('Close');
}
$(this).toggleClass('activetoggle');
});
My Fiddle.
How can I fix this issue?
I added the following function as a callback for the animate function when clicking your menu button. It will check to see if the footer button is in the active state, and if so will update accordingly, otherwise it will leave it be.
function () {
var $footer = $('.activetoggle');
if ($footer.length)
$footer
.toggleClass('activetoggle footerButton')
.text('Footer');
}
Updated Fiddle

Controling Menu Text Overflow in Jquery

I am new to JQuery. I'm using a menu bar shown in the following link
http://tympanus.net/Tutorials/UIElements/LargeDropDown/
The source code can be downlloaded from
http://tympanus.net/codrops/2010/07/14/ui-elements-search-box/
I have attatched the code and files to my project.
The problem is that when i first open the page, it showing the contents in the right way as shown in the image below
and on mouse enter the list item expands and shows the sub details below correctly
but when i move the mouse away from the item, the text overflows and comes down. if it is a single word then there is no problem but it there are two or more words this happens. You can see this in the image below
I'm also giving the javascript code
<!-- The JavaScript -->
<script type="text/javascript" src="Styles/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
/**
* the menu
*/
var $menu = $('#ldd_menu');
/**
* for each list element,
* we show the submenu when hovering and
* expand the span element (title) to 510px
*/
$menu.children('li').each(function () {
var $this = $(this);
var $span = $this.children('span');
$span.data('width', $span.width());
$this.bind('mouseenter', function () {
$menu.find('.ldd_submenu').stop(true, true).hide();
$span.stop().animate({ 'width': '510px' }, 300, function () {
$this.find('.ldd_submenu').slideDown(300);
});
}).bind('mouseleave', function () {
$this.find('.ldd_submenu').stop(true, true).hide();
$span.stop().animate({ 'width': $span.data('width') + 'px' }, 300);
});
});
});
</script>
Can you please help me out???
You could try to add a min-width via CSS for your li (W3School min-width). The following code affects all your li coming after your ul with the id ldd_menu.
#ldd_menu li {
min-width:200px
}
You could also use for only one specific li.
<li style="min-width:200px">
Or via jquery in your each-block (jQuery CSS)
$span.css("min-width", "200px");

Categories