jquery single click not working properly - javascript

I managed to remove the attribute element of a list item but I am struggling to do the following: When I click on a list item,it should add a class called important,otherwise, the class must not exist.
I tried this using jQuery:
$(document).ready(function (){
var origHref = $('ul#primary-menu > li.menu-item-has-children > a').attr('href');
//alert(origHref);
var clicks = 0;
$('ul#primary-menu > li.menu-item-has-children > a').removeAttr("href").data("origHref",origHref);
$('ul#primary-menu > li.menu-item-has-children').click(function(){
clicks++;
if(clicks === 1){
$('ul#primary-menu > li.menu-item-has-children').addClass('important');
}
else if(clicks > 1){
alert("you clicked twice");
}
});
});
Problem: When I inspect the element and click on the list for the first time,nothing happens.Only when I click for the second time that the class is added.
NOTE: I wanna do that for mobile devices only,so no need to worry about screens wider than 800 pixels.
Please help.

Do a if based on the class not a global variable, prevent the default click event :
$('ul#primary-menu > li.menu-item-has-children').click(function(e) {
if ($(window).width() < 800) {
if (!$(e.target).closest('ul').is('.sub-menu')) {
e.preventDefault();
if (!$(this).hasClass('important')) {
$(this).addClass('important')
//toggle the menu
} else {
//redirect if second click
window.location = $(this).find('a').attr('href');
}
}
}
});

Related

cannot close accordion toggle after open

I can't make my accordion close. It opens on click, however when I click back it doesn't close.
Here is my code:
MYPRO.accordion = function () {
var $acpanel = $(".accordion > .accordion-content"),
$acsnav = $(".accordion > .accordion-title > a");
$acpanel.hide().first().slideUp("easeOutExpo");
// $acsnav.first().addClass("active");
$acsnav.on('click', function () {
var $this = $(this).parent().next(".accordion-content");
if ($this.addClass("active")){
$acsnav.removeClass("active");
$acpanel.first($this).slideDown();
$(this).parent().next().slideDown("easeOutExpo");
}
else
{
$acpanel.first($this).slideUp();
$(this).parent().next().slideUp("easeInExpo");
//$acsnav.removeClass('active').slideUp("easeInExpo");
}
return false;
}); }
Every time you click, $this.addClass("active") returns a jQuery object, so the if will allways evaluate as true, and slide down the tab, never reaching the else statements.
Try something like:
var $acpanel = $(".accordion > .accordion-content"),
$acsnav = $(".accordion > .accordion-title > a");
$acpanel.slideDown("easeOutExpo");
$acsnav.addClass("active");
$acsnav.on('click', function(e) {
if ($acsnav.hasClass("active")) {
$acsnav.removeClass("active");
$acpanel.show().slideUp("easeInExpo");
} else {
$acsnav.addClass("active")
$acpanel.hide().slideDown("easeOutExpo");
}
});
This way you'll first check if its active. If so, slide up and remove the active class. If not active, slide down and remove the active class.
Here is a JSFiddle.
Edit: Updated code and added JSDFiddle.

Scrolling Add Class Over Value Only Once

I stumbled upon an issue with a menu that I want to open by adding a "Open" class when scrolled above certain value. The issue is that I want it to open only ONCE after that value so it appears for the user, and then is up to the user to open and close it by a toggle.
I used this method:
<script type="text/javascript">
jQuery(function() {
//caches a jQuery object containing the header element
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop();
if (scroll >= 1150) {
jQuery(".menubar").addClass("open");
}
});
});
</script>
The issue is that after the 1150 value, it keeps poping up after every scroll within this value.
How do I make it stop and make this event happen only once?
Thank you in advance!
Check if the class is already existing. Or use a variable if the class changes too easily:
var isOpened = false;
jQuery(function() {
//caches a jQuery object containing the header element
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop();
// The original if statement, testing for `.hasClass()`
// if (scroll >= 1150 && !$(".menubar").hasClass()) {
if (scroll >= 1150 && !isOpened) {
isOpened = true;
jQuery(".menubar").addClass("open");
}
});
});
You can set a flag and then just check against that flag.
jQuery(function() {
var menuBarOpenedOnce = 0;
//caches a jQuery object containing the header element
jQuery(window).scroll(function() {
var scroll = jQuery(window).scrollTop();
if (scroll >= 1150 && menuBarOpenedOnce === 0) {
jQuery(".menubar").addClass("open");
menuBarOpenedOnce = 1;
}
});
});

Restore scroll position after mobile menu is closed

I'm having a mobile menu that opens and closes using jquery by adding a css class that has display:block while the menu div has display:none.
The jquery code has a part where it is supposed to close the menu when a click is registered outside the menu div. Everything works execept the: $("body").scrollTop(scrollpos) . This was supposed to scroll the user back where he left off after the scrollTop(0) took place and the menu has closed, but it does not scroll at all the scroll is stuck at the top. Any help will be appreciated. Thank you.
EDIT: Here is an example: https://jsfiddle.net/mufwwudj/
$(function () {
var menutoggle = $(".menu-toggle");
var sidenav = $(".side-nav");
menutoggle.click(function () {
var scrollpos = $('body').scrollTop();
if (!$("body").hasClass("m-nav-open")) {
$("body").scrollTop(0).addClass("m-nav-open");
}
$(document).mouseup(function (e){
if (!sidenav.is(e.target) && sidenav.has(e.target).length === 0 && !menutoggle.is(e.target) && menutoggle.has(e.target).length === 0){
if ($("body").hasClass("m-nav-open")) {
$("body").scrollTop(scrollpos).removeClass("m-nav-open");
}
}
});
});
});
One problem here is that you are assigning a new mouseup event every time the menutoggle.click function runs.
$(document).mouseup(function (e){
if (!sidenav.is(e.target) && sidenav.has(e.target).length === 0 && !menutoggle.is(e.target) && menutoggle.has(e.target).length === 0){
if ($("body").hasClass("m-nav-open")) {
$("body").scrollTop(scrollpos).removeClass("m-nav-open");
}
}
});
Only the first one passes the conditional, even though each one will fire and scrollpos will always equal whatever it was in the first mouseup event listener.
I don't know how you are testing it, or what the HTML looks like but if you are at the top of the page the first time you click it, scrollpos in the mouseup event will always be 0.
Try assigning the mouseup event once, and putting scrollpos outside both so it can be accessed in both.
$(function () {
var menutoggle = $(".menu-toggle");
var sidenav = $(".side-nav");
var scrollpos;
menutoggle.click(function () {
scrollpos = $('body').scrollTop();
if (!$("body").hasClass("m-nav-open")) {
$("body").scrollTop(0).addClass("m-nav-open");
}
});
$(document).mouseup(function (e){
if (!sidenav.is(e.target) && sidenav.has(e.target).length === 0 && !menutoggle.is(e.target) && menutoggle.has(e.target).length === 0){
if ($("body").hasClass("m-nav-open")) {
$("body").scrollTop(scrollpos).removeClass("m-nav-open");
}
}
});
});
function ScrollOnTopo() {
window.scrollTo(0, 0); //It scrolls page at top
}
This function may be useful to you.

Change specific hyperlink location

I have a menu that has submenus that drop down on a hover, however I am making it responsive and I need it the submenus to drop on a click. I have accomplished this by targeting screensize.
What i need to do is stop the anchor tag with the class of stopLink from executing on a click and just have the submenu drop instead of a page redirect
NOTE: * you may ask why do you even need a hyperlink for the first element anyways, it is non-negotiable with my client
HTML
<ul class="mainMenu">
<li>
Home
</li>
<li>
Products
<ul class="subMenu>
<li>P1</li>
<li>P2</li>
<li>P3</li>
</ul>
</ul>
jquery - works but blocks ALL LINKS
$('.mainMenu > li').unbind().click(function (e) {
e.preventDefault();
location.href = "javascript:void(0);";
$(this).find('.subMenu').stop().slideToggle(400);
return;
});
jquery - what i think needs to happen*
$('.mainMenu > li').unbind().click(function (e) {
$('.stopLink').each(function(e)
e.preventDefault();
location.href = "javascript:void(0);";
});
$(this).find('.subMenu').stop().slideToggle(400);
});
Update
Also tried to target it specifically based on browser size
var $w = window.innerWidth || document.documentElement.clientWidth;
if ($w < 1025) {
$('.stopLink').each(function (e) {
e.preventDefault();
location.href = "javascript:void(0);";
});
} else {
$('.stopLink').each(function (e) {
e.preventDefault();
location.href = "/products.html";
});
}
if ($w > 1025) {
$('.mainMenu > li').unbind().hover(function () {
$(this).find('.subMenu').stop().slideToggle(400);
});
} else {
$('.mainMenu > li').unbind().click(function (e) {
$(this).find('.subMenu').stop().slideToggle(400);
});
}
thought the above code would work for sure but no dice :(
Have you tried this?
$('.mainMenu > li.stopLink').unbind().click(function (e) {
e.preventDefault();
location.href = "javascript:void(0);";
$(this).find('.subMenu').stop().slideToggle(400);
return;
});
If you just use .click() and e.preventDefault() along with the check for the width of the screen you get this fiddle.
if(w < 1025) {
$('a.stopLink').click(function (e) {
e.preventDefault();
$('ul.subMenu').slideToggle(400);
return;
});
}

jQuery button toggle

I have a button that toggles a menu popup. I have can make the menu disappear if you click outside of the menu but now my button toggle does not work. If I click the button again the menu stays up. How can I make the menu disappear if you toggle the button or if you click off the container?
jsFiddle: http://jsfiddle.net/PPcfN/
$('.quicklinks-rollover').click(function () {
$('.quicklinks').toggle();
});
$(document).mouseup(function (e) {
var container = $(".quicklinks");
if (container.has(e.target).length === 0) {
container.hide();
}
});
The mouseup function has to take care of the click on the button (quicklinks-rollover).
If fixed the whole thing here:
http://jsfiddle.net/8VUnq/1/
$(document).mouseup(function (e) {
var popup = $('#quickLinksPopup'),
button = $('#quickLinksToggle');
if (popup.is(':visible')
&& !popup.is(e.target)
&& !button.is(e.target)
&& popup.has(e.target).length === 0
&& button.has(e.target).length === 0) {
popup.toggle();
}
});
Keep in mind those two things:
Use IDs to refer to the items quicker and prevent multiple popup conflicts
Using a mouse event on the whole page is not recommended as the event will get triggered very frequently, try using an alternative method such as adding a close button in the popup, or to be more effective, think about adding the mouseup listener on the show of the popup and removing it on the hide.
You can determine the state of the popup with: $(popup).is(':visible') or is(':hidden').
Try :
var $quicklinks = $('.quicklinks');
var msOverLinks = false;
$('.quicklinks-rollover').click(function () {
$quicklinks.toggle();
});
$quicklinks.mouseenter(function() {
msOverLinks = true;
}).mouseleave(function() {
msOverLinks = false;
});
$(document).mouseup(function (e) {
if( ! msOverLinks ) {
$quicklinks.toggle();
}
});
You can do this Normal hide and show method. Because mostly toggle() function wont works in proper manner...
put your HTML button with attribute p="closed" by default:
<button class="quicklinks-rollover" p="closed" title="Quick Links">toggle</button>
Change Your Jquery:
$('.quicklinks-rollover').click(function () {
var a = $(this).attr("p");
var container = $(".quicklinks");
if(a=="closed"){
container.show();
$(this).attr("p","open");
}else{
container.hide();
$(this).attr("p","closed");
}
});
$(document).mouseup(function (e) {
var container = $(".quicklinks");
if (container.has(e.target).length === 0) {
container.hide();
}
});
The reason for this behavior, the mouseup() is binded when I perform the click() on the div. You can check this behavior by adding console.log message in .mouseup event.
So instead try like below.
$('.quicklinks-rollover').on('click', function (e) {
$('.quicklinks').toggle();
e.stopImmediatePropagation();
});
$(document).click(function (e) {
var container = $(".quicklinks");
console.log(container.has(e.target).length);
if (container.has(e.target).length === 0) {
container.hide();
}
});
Working Fiddle

Categories