'Issue with click function not working after toggle
Sorry the title is vague, I'm not sure how best to describe this.
I have a function which should do the following:
If a menu link has children:
- preventDefault on the parent link
- Open a submenu on parent link click
- Close submenu on close button click
- Back to step 1
If a menu link has no children:
- Follow the link as usual, no preventDefault
The problem I'm having is that this works as expected on opening your first submenu, but when you close that submenu all the parent links are now showing default behaviour, i.e. preventDefault isn't doing anything. Same thing happens if you go back in your browser history to the menu, basically as soon as the click function has happened once, it won't happen again until you reload or visit a new page.
Here's my script currently:
$(function() {
var $parent = $('.menu-box > li');
$parent.click(function(e) {
if ($(this).find('.child').length) {
e.preventDefault(); // Don't follow the parent link if there are children
showContent($(this));
$('.menu-box .sub-menu').append('<span class="close left-arrow"></span>'); // Add close button to submenu
$('.menu-box .close').click(function() {
hideContent();
e.preventDefault(); // Make sure preventDefault is still in place after you close the submenu
}); // Close submenu on click
function showContent(elem){ // Submenu open
$parent.unbind('click'); // Stop preventDefault() on submenu items
hideContent();
elem.find('.content').addClass('expanded');
elem.addClass('cover');
}
function hideContent(){ // Submenu closed
$('.menu-box .content').removeClass('expanded');
$parent.removeClass('cover');
e.preventDefault(); // Make sure preventDefault is still in place after you close the submenu
}
} else {
//do nothing
}
});
});
I've chucked preventDefault all over the place as you can see... But nothing stops the parent links from being active.
To summarise, links should only be active if they're: A. Parents with no children, or B. Links within a submeny
Any thoughts?
Here's the site if you want to poke around the menu (sidebar): http://phpstack-305166-2611865.cloudwaysapps.com/
UPDATE:
Thanks to @Ashitaka I've now got .off('click') to stop the issue above, however now the click function on the close submenu button doesn't work. I would have thought the subsequent .on('click') specifically for the close button would turn it back on again but alas.
$(function(){
$('.menu-box > li').on('click', function(e){
if($(this).find('.child').length){
e.preventDefault(); // Don't follow the <a>
showContent($(this)); // Show the submenu instead
}else{
// Follow the <a>
}
});
});
function showContent(elem){
elem.off('click'); // Stop preventDefault on submenu items
hideContent(elem);
elem.find('.content').addClass('expanded');
elem.addClass('cover');
elem.find('.close').on('click' , function(){ // Hide content on click /*This now doesn't work because of unbind('click') above*/
hideContent($(this));
});
}
function hideContent(elem){
elem.find('.content').removeClass('expanded');
elem.removeClass('cover');
}
UPDATE 2:
Changing hideContent($(this)) to hideContent(elem) works, but only if the item hasn't already been clicked once before.
$(function(){
$('.menu-box > li').on('click', function(e){
if($(this).find('.child').length){
e.preventDefault(); // Don't follow the <a>
showContent($(this)); // Show the submenu instead
}else{
// Follow the <a>
}
});
});
function showContent(elem){
elem.off('click'); // Stop preventDefault on submenu items
hideContent(elem);
elem.find('.content').addClass('expanded');
elem.addClass('cover');
elem.find('.close').on('click' , function(){ // Hide content on click
hideContent(elem);
});
}
function hideContent(elem){
elem.find('.content').removeClass('expanded');
elem.removeClass('cover');
}
So if I click, for example, 'About' (which has children) we go to the submenu and the close toggle works correctly, and if I then click a different parent, e.g. 'Products', that submenu and toggle work correctly, but the original 'About' now doesn't open the submenu.
This is kind of acceptable, because if a user has already looked at a submenu and closed it, they're less likely to want to revisit it. But I'd really like to get this sorted...
Solution 1:[1]
You have issues regarding binding all over the code.
Try this :
function showContent(elem){ // Submenu open
elem.unbind('click'); // Stop preventDefault() on submenu items
hideContent(elem);
elem.find('.content').addClass('expanded');
elem.addClass('cover');
}
function hideContent(elem){ // Submenu closed
elem.find('.content').removeClass('expanded');
elem.removeClass('cover');
}
$(function() {
$('.menu-box > li').click(function(e) {
if ($(this).find('.child').length) {
e.preventDefault(); // Don't follow the parent link if there are children
showContent($(this));
$(this).find('.sub-menu').append('<span class="close left-arrow"></span>'); // Add close button to submenu
$(this).find('.close').click(function() {
hideContent($(this));
e.preventDefault(); // Make sure preventDefault is still in place after you close the submenu
}); // Close submenu on click
} else {
//do nothing
}
});
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |