I have a sidebar and I have a button which toggles the sidebar on click. I have a jQuery function which does that. I have a new functionality now, where, if the sidebar is open and the user clicks any of the list items in the sidebar, it toggles back and some function will be excecuted.
The Problem:
When I click the li inside the sidebar, the toggle button is waiting for it's second click (my guess). So if I add toggle on clicking sidebar li, the main toggle button functionality breaks. How do I keep both without affecting each other. I hope I have made myself clear. Here is the code.
JS
// code for sidebar toggle in jQuery
$.fn.toggleClick = function () {
var methods = arguments,
count = methods.length;
return this.each(function (i, item) {
var index = 0;
$(item).on('click', function () {
return methods[index++ % count].apply(this, arguments);
});
});
};
//for opening sidebar
function openSidebar() {
$('#sg-evm-sidebar').animate({
left: 0
}, 300)
$('.container').css({
position: "fixed"
}).animate({
left: 300
}, 300)
$('.content-overlay').delay(300).show();
}
//closing sidebar
function closeSidebar() {
$('#sg-evm-sidebar').animate({
left: -300
}, 300)
$('.container').css({
position: "fixed"
}).animate({
left: 0
}, 300)
$('.content-overlay').delay(300).hide();
}
//$(".empName").on("click", function () {
// closeSidebar();
//});
// calling toggleclick here
$('.toggle-box').toggleClick(openSidebar, closeSidebar);
Here is a JS FIDDLE. I created it from my huge website. So please ignore broken images.
I've updated your fiddle: http://jsfiddle.net/qvksx30g/4/
I've added some basic logic
var sidebarOpen = false;
function toggleSidebar()
{
if (sidebarOpen)
closeSidebar();
else
openSidebar();
}
And then inside openSidebar and closeSidebar I set sidebarOpen.
I also no longer use toggleClick. Instead I'm using:
$(document).on('click', '.toggle-box', toggleSidebar)
.on('click', '.list li', closeSidebar);
You could keep track of the sidebar state (open or close) using a class on the sidebar wrapper ("close" or "open"), and then use this class to determine in your click listener if you have to call closeSidebar or openSidebar.
Related
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.
I'm trying to combine two click functions to condense the code, but i'm not sure how. Thanks!
$(document).ready(function () {
//when clicking on a link hide the navigation links
$('nav a').click(function () {
if ($(window).width() < 730) {
$('nav').toggleClass('showNav');
$('.navToggle').toggleClass('iconTop');
$('.navToggle').toggleClass('iconMiddle');
$('.navToggle').toggleClass('iconBottom');
}
});
//when clicking on icon hide and show the navigation links
//the icon is only visible when the screen size is less then 730px
$('.navToggle').click(function () {
$('nav').toggleClass('showNav');
$('.navToggle').toggleClass('iconTop');
$('.navToggle').toggleClass('iconMiddle');
$('.navToggle').toggleClass('iconBottom');
});
});
Would something like this work?
$('nav a, .navToggle').click(function () {
if ($(this).hasClass('navToggle') || $(window).width() < 730) {
$('nav').toggleClass('showNav');
$('.navToggle').toggleClass('iconTop iconMiddle iconBottom');
}
});
Basically, you check if the clicked element has the class .navToggle. If it doesn't, it check the window size before doing the action.
I have a button that does a "flyin" animation when click. But if the user clicks the button to deselect their choice i need to disable the animation.
The class changes when they have selected their choice from ".simple-button" to ".simple-button active".
jQuery(document).ready(function ($) {
$(".simple-button").on('click', function () {
//Scroll to top if cart icon is hidden on top
$('html, body').animate({
'scrollBottom': $(".view-my-beds").position().top
});
//Select item image and pass to the function
var itemImg = $(this).parent().find('img').eq(0);
flyToElement($(itemImg), $('.view-my-beds'));
});
});
It my experience, it's best to add a class on click. This means we can detect if it's in use, thus - making your problem simple to solve:
$('.simple-button').on('click', function ()
{
if (!$(this).hasClass('active')) {
$('html, body').animate({
'scrollBottom': $('.view-my-beds').position().top
});
var itemImg = $(this).parent().find('img').eq(0);
} else {
// do whatever without animation
}
})
I am using hoverIntent plugin for my horizontal drop down navigation menu as I want few millisecond delay before opening the submenu associated with current main menu. Also I have a requirement that opened menu should not get closed immediately as and when user moves mouse pointer away from currently opened menu.
Fiddle link: https://jsfiddle.net/vijayP/tbg2x5h7/6/
So I have come up with following code:
$(document).ready(function(){
var config = {
over: function () {
$(this).addClass("show");
},
timeout: 300,
out: function () {
var _this = $(this);
setTimeout(function () {
$(_this).removeClass("show");
}, 300);
}
};
$("ul.drop_menu li").hoverIntent(config);
});
Here menu is getting opened (adding show class) after 300 millsec. And on hover out; 300 millisec delay have been added to avoid sudden close of menu. This code works fine with no issue. The problem I am observing is:
Problem: If user moves away from menu then I want 300 millisec delay before closing the submenu. But if user moves cursor from 1st main menu to 2nd main menu; then I want to close 1st submenu immediately and don't want to show 2 submenu overlapped to each other. In fiddle you can see this overlapping effect when you are on 1st main menu and goes to 2nd main menu.
When you hover over an li element, you can just remove the show class from siblings. See the updated jsfiddle https://jsfiddle.net/tbg2x5h7/7/
$(document).ready(function(){
var config = {
over: function () {
$(this).siblings().removeClass("show");
$(this).addClass("show");
},
timeout: 300,
out: function () {
var _this = $(this);
setTimeout(function () {
$(_this).removeClass("show");
}, 300);
}
};
$("ul.drop_menu li").hoverIntent(config);
});
I have the following code in my JS file:
jQuery("document").ready(function (e) {
var menu = e(".menu-container");
var button = e(".menu-functions");
e(window).scroll(function () {
if (e(this)
.scrollTop() > 150) {
menu.addClass("f-nav");
button.addClass("collapse-expand");
button.addClass('collapse');
} else {
menu.removeClass("f-nav");
button.removeClass("collapse");
button.removeClass("expand");
button.removeClass("collapse-expand");
}
});
//problem area
$('#menu-functions').click(function(){
if(button.hasClass('collapse'))
{
button.addClass('expand');
button.removeClass('collapse');
}
if(button.hasClass('expand'))
{
button.addClass('collapse');
button.removeClass('expand');
}
});
});
Now I need to make it so that the part under the // problem area starts to work. I reckon there's a toggleClass in jQuery, right? Some advanced conditions could do the trick, however I'm still learning and I need some help. I also need to find a way to animate() the .menu-container div whether the button state is expand or collapse:
If the button was clicked while it had the expand class
animate the menu from bottom to top with 98px;
If the button was clicked while it had the collapse class
animate the menu from top to bottom with 98px.
EDIT - JSFIDDLE:
jsfiddle.net/rcdhnh7L
Try it like this instead. Don't use e as the var for jQuery, that's just strange. And I simplified the problem area to directly grab the elements you want instead of iterating an existing collection.
jQuery("document").ready(function ($) {
var menu = $(".menu-container");
var button = $(".menu-functions");
$(window).scroll(function () {
if ($(this)
.scrollTop() > 150) {
menu.addClass("f-nav");
button.addClass("collapse-expand");
button.addClass('collapse');
} else {
menu.removeClass("f-nav");
button.removeClass("collapse");
button.removeClass("expand");
button.removeClass("collapse-expand");
}
});
//problem area
$('#menu-functions').click(function () {
$('.menu-functions.collapse').addClass('expand').removeClass('collapse');
$('.menu-functions.expand').addClass('collapse').removeClass('expand');
});
});
Or this should work as well:
//problem area
$('#menu-functions').click(function () {
$('.menu-functions.collapse, .menu-functions.expand').toggleClass('expand collapse');
});