I'm building a fully responsive accessible menu using jQuery/javascript and css.
I've got everything working fine, except for when the viewport is less than 535px and the toggle menu is displayed, a click on a parent doesn't expand the children, just links directly to that page.
I'd like it so that when you click a parent, say "Tools" for example, the children display and both the parent item and children are all clickable links.
Here's a staging site to look at: website link
Here's a sample of js:
var ww = 0;
jQuery(document).ready(function($) {
$(".menu").show();
$(".menu .currenthas-child a, .menu .has-child a").each(function() {
if ($(this).next().length > 0) {
$(this).addClass("parent");
};
});
$(".toggleMenu").click(function(e) {
e.preventDefault();
$(this).toggleClass("active");
if($(this).hasClass("active")){
//show menu
$(".menu").removeClass("hidden").fadeIn(250);
} else {
//hide menu
$(".menu").addClass("hidden");
}
});
$(".menu li ul li").click(function(e) {
if ($(".toggleMenu").hasClass("active")){
$(".menu").toggleClass("hidden");
}
});
//on click, anywhere on page, close all menu items
$(document).click( function() {
$(".menu li").each(function() {
if ($(this).hasClass("hover") || $(this).hasClass("keyhover")) {
$(this).removeClass("hover");
$(this).removeClass("keyhover");
//console.log('hover removed');
}
});
});
//Focus State - Navigation
$(".menu li").focusin(function (e) {
if (!$(this).hasClass("keyhover")) {
$(this).addClass("keyhover");
showElement($(".menu"));
}
//console.log('menu item focusin');
});
//Blur State - Navigation
$(".menu li").focusout(function (e) {
if ($(this).hasClass("keyhover")) {
$(this).removeClass("keyhover");
}
if ($(this).hasClass("hover")) {
$(this).removeClass("hover");
}
//console.log('menu item focusout');
});
//Focus State - Navigation Sub Items
$(".menu li ul li").focusin(function () {
if (!$(this).hasClass("glow")) {
$(this).addClass("glow");
}
});
//Blur State - Navigation Sub Items
$(".menu li ul li").focusout(function () {
if ($(this).hasClass("glow")) {
$(this).removeClass("glow");
}
});
//on window resize, recheck size and adjustMenu
$(window).bind('resize orientationchange', function() {
ww = viewportSize.getWidth();
adjustMenu();
//UN-COMMENT FOR DEBUG OUTPUT
//var widthTest = document.documentElement.clientWidth;
//var widthTest2 = screen.width;
//console.log("document.documentElement.clientWidth ="+widthTest);
//console.log("screen.width = "+widthTest2);
//console.log("viewport().width = "+ww);
//var mql = window.matchMedia("screen and (max-width: 47.938em)");
//console.log(mql);
});
var hideElement = function(elementToModify) {
elementToModify.addClass("hidden");
}
var showElement = function(elementToModify) {
elementToModify.removeClass("hidden");
}
var adjustMenu = function() {
if (ww <= 535) {
$(".toggleMenu").css("display", "inline-block");
if (!$(".toggleMenu").hasClass("active")) {
hideElement($(".menu"));
} else {
showElement($(".menu"));
}
$(".menu li h2.parent").unbind('click').bind('click', function(e) {
// must be attached to anchor element to prevent bubbling
e.preventDefault();
if (e.stopPropagation){
e.stopPropagation();
}
else if(window.event){
window.event.cancelBubble=true;
}
//close any sibling menu items
//$(this).parent().siblings('li').removeClass("hover");
//$(this).parent().siblings('li').removeClass("keyhover");
//handle click request
if (!$(this).parent().hasClass("hover")) {
$(this).parent().addClass("hover");
//console.log('hover added');
} else {
$(this).parent().removeClass("hover");
$(this).parent().removeClass("keyhover");
//console.log('hover removed');
}
});
}
else if (ww > 535) {
$(".toggleMenu").css("display", "none");
$(".toggleMenu").removeClass("active");
//show menu parents
showElement($(".menu"));
//hide any popped up menu sub-items
$(".menu li").removeClass("hover");
$(".menu li h2.parent").unbind('click').bind('click', function(e) {
// must be attached to anchor element to prevent bubbling
e.preventDefault();
if (e.stopPropagation){
e.stopPropagation();
}
else if(window.event){
window.event.cancelBubble=true;
}
//close any sibling menu items
$(this).parent().siblings('li').removeClass("hover");
$(this).parent().siblings('li').removeClass("keyhover");
//handle click request
if (!$(this).parent().hasClass("hover")) {
$(this).parent().addClass("hover");
//console.log('hover added');
} else {
$(this).parent().removeClass("hover");
$(this).parent().removeClass("keyhover");
//console.log('hover removed');
}
});
}
}
//initialize the menu
ww = viewportSize.getWidth();
adjustMenu();
});
I think what you want is a strange behavior for your menu. How to close the sub-menu if the second click on the main link redirects to this page ?
That said, you can do what you want like this :
$(".menu li").click(function(e) {
if (!$(this).children('ul').is('.open')) {
e.preventDefault();
$(this).children('ul').addClass('open').css({'left' : '0px'});
}
});
It's better to test if the sub-menu is visible or not but you have to change the CSS of your .sub-menu
class with display:none
in place of left: -9999px
UPDATE
You can't have a slideDown effect on your sub-menus because they have a position : absolute
attribute. So you need to deal with media queries to change that and set it just a display : none
attribute in place. This way you can use a simple slideDown
effect on click event
and prevent the event if the corresponding sub-menu is not visible.
Take a look at this sample :
$(document).ready(function(){ $(".dropdown").click(function(e) { if (!$(this).children('ul').is(':visible')) { e.preventDefault(); $(this).children('ul').slideDown(); } }); });
*, *:before, *:after { margin: 0; padding: 0; box-sizing: border-box; } ul { list-style-type: none; width: 100%; } ul li { display: block; position: relative; } ul li a { color: #fff; text-decoration: none; cursor: pointer; padding: 10px 20px; display: block; width: 100%; } ul > li > a { background: #28AADC; } ul li a:hover { background: #00648C; } ul.submenu { display: none; } ul.submenu > li > a { background: #FFBE4F; } nav > ul { width: 400px; } @media screen and (min-width:536px){ nav > ul > li { width: 33.33%; float: left; } nav > ul > li:hover ul.submenu { display:block; } ul.submenu { position: absolute; } } @media screen and (max-width:535px){ nav > ul > li { width: 100%; float: none; } }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <nav> <ul> <li class="dropdown"> <a href="http://stackoverflow.com">Nav 1</a> <ul class="submenu"> <li><a href="#">Nav 1.1</a></li> <li><a href="#">Nav 1.2</a></li> <li><a href="#">Nav 1.3</a></li> <li><a href="#">Nav 1.4</a></li> </ul> </li> <li class="dropdown"> <a href="http://stackoverflow.com">Nav 2</a> <ul class="submenu"> <li><a href="#">Nav 2.1</a></li> <li><a href="#">Nav 2.2</a></li> <li><a href="#">Nav 2.3</a></li> <li><a href="#">Nav 2.4</a></li> </ul> </li> <li class="dropdown"> <a href="http://stackoverflow.com">Nav 3</a> <ul class="submenu"> <li><a href="#">Nav 3.1</a></li> <li><a href="#">Nav 3.2</a></li> <li><a href="#">Nav 3.3</a></li> <li><a href="#">Nav 3.4</a></li> </ul> </li> </ul> </nav>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.