jQuery .on() doesn't fire on click but instantly - javascript

When I click a button, I change its ID and apply a new style to it by adding a class toMenu. What I wanted to do is, when I click the button with the new ID menu, that it adds another class menuTransition. But what now happens is that it already adds the class menuTransition when I click the button with the old ID #button. But what it's supposed to do, is not add the class menuTransition until the button with the new ID #menu is clicked.
Here's my code:
$(document).ready(function() {
$("#button").click(function(){
$("#button").addClass("toMenu")
$("#button").attr("id","menu");
});
});
$(document).on("click", "#menu", function() {
$("#menu").addClass("menuTransition");
});

What you're seeing is a bit of a race condition. With your button click event handler you're adding a class and an ID to your button. Then with your delegated event handler you're looking for any clicks on the document, even those that bubble up from descendant elements, and adding a class there as well. One way to handle this is to add a small (~ 1 msec) delay to short-circuit this race that would normally occur with your example code.
$(document).ready(function() {
$("#button").click(function() {
$("#button").addClass("toMenu")
setTimeout(function() {
$("#button").attr("id", "menu");
}, 1)
});
});
$(document).on("click", "#menu", function() {
$("#menu").addClass("menuTransition");
});
.toMenu {
font-weight: bold;
}
.menuTransition {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">
button
</button>
By adding the 1 millisecond delay, the ID is added after the click on the button has reached the document event handler, so that event handler only fires after the first click on the button.

You should not be changing the ID. Element IDs are intended to be static. You can use a class to tag the current state of the button / menu and make it behave accordingly (and at the same time avoid the inefficient delegated event handler on $(document):
$(document).ready(function() {
$("#menubutton").on('click', function() {
var $this = $(this);
if ($this.hasClass('toMenu')) {
$this.addClass('menuTransition');
} else {
$this.addClass('toMenu');
}
});
});

Related

Create Toggle Button Using jQuery

I want to use just ONE button to control Opening and Closing an Off-Canvas Menu. So I created a Button with OpenButton class which open menu, after clicking, I remove OpenButton class and add CloseButton class, These all work like a charm, But When I call Click Event on CloseButton It doesn't work, What is the problem ?
This is my code :
$('.OpenButton').click(function() {
$(this).addClass('CloseButton');
$(this).removeClass('OpenButton');
});
$('.CloseButton').click(function() {
alert('Close');
});
Since you're adding the class dynamically, you need to use event delegation to register the same with the event handler mechanism,
$(document).on('click', ".CloseButton", function() {
alert('Close');
});
Hope this helps!
That is because the click event is bound at runtime. Since .CloseButton does not exist when the code is executed, no click event will be bound to it. One solution is to use $(document).on('click', '.CloseButton', function() {...}) to do that, but that is considered resource intensive and unnecessarily heavyhanded.
I would recommend that you do not change the class of the button instead. If you want to modify the style or appearance of the button when it's open/close, you can do it by adding classes instead of swapping classes, for example:
$('.button').click(function() {
$(this).toggleClass('is-open');
});
In this case, you can you also store the state of the button in jQuery's data object. That will abstract reading the state of an object from the DOM based on it's class:
$(function() {
$('.button').click(function() {
// Store state
if ($(this).data('is-open')) {
$(this).data('is-open', false);
alert('closing!');
} else {
$(this).data('is-open', true);
alert('opening!');
}
// Toggle class
$(this).toggleClass('is-open');
$('.toggleTarget').toggleClass('is-hidden');
});
});
.is-hidden {
display: none;
}
.button {
background-color: steelblue;
color: #fff;
display: inline-block;
padding: 10px;
}
.button.is-open {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Toggle
<div class="toggleTarget is-hidden">I am content that is toggled.</div>

Attach second click-event to an element after class name has been changed

I have a div with a class name a. I attach a click-event to this div like
$('.a').on('click', function() {
$(this).removeClass('a').addClass('b');
})
After this; element's class name changes from a to b. I want to attach second click event on .b like
$('.b').on('click', function() {
$(this).removeClass('b').addClass('c');
})
First click event works fine however second one does not fire. See my JSfiddle.
Attach the click even to a higher element in the DOM - when you change the class, the event bubbling up will change, e.g.
$("body").on("click", ".b", function() {
$(this).removeClass('b').addClass('c');
});
You can add the second event after the first one has fired:
$('.a').on('click', function() {
$(this).removeClass('a').addClass('b');
$('.b').on('click', function () { /* ... */ });
})
You're running the .b code at the beginning, when the element doesn't have class b. Try adding the new onClick handler in the code for your first onClick.
Code:
$('.a').on('click', function() {
$(this).removeClass('a').addClass('b');
$('.b').on('click', function() {
$(this).removeClass('b').addClass('c');
})
})
$(".a").click(function() {
$(this).removeClass("a").addClass("b");
$(".b").click(function() {
$(this).removeClass("b").addClass("c");
})
})

How to remove class after it been added

So I need a little bit of help. I'm playing around with addClass and removeClass and I can't seem to remove a class after it's set. What I basically want is:
When someone clicks an h3, it adds to its parent div class
When someone clicks a div with added class, class needs to be removed
First step I got out of way and it's working
$(function(){
$('div h3.itemTitle').on('click', function(){
$(this).parent().addClass('active').siblings().removeClass('active');
});
});
Now when I define:
$(function(){
$('div.active').on('click', function(){
$(this).removeClass('active');
});
});
It does nothing, as if it doesn't see classes. It sets only those set in onload...
Help, anyone?
The child element "h3.itemTitle" already had a click event listener on it and the parent can't actually capture the click event.
Your $('div.active').on('click', ...) never actually fires because you click the h3 not the div.
I recommend this approach: http://jsfiddle.net/c3Q6Q/
$('div h3.itemTitle').on('click', function () {
// saves time not to write $(this).parent() everything so i store in a _parent var
var _parent = $(this).parent();
if (_parent.hasClass('active')) {
_parent.removeClass('active');
} else {
_parent.addClass('active').siblings().removeClass('active');
}
});
Try
$('body').on('click','div.active', function(){$(this).removeClass('active');});
Instead of
$('div.active').on('click', function(){$(this).removeClass('active');});
I would go with this way:
$('div').on('click', function(e){
var el = e.target;
if($(el).is('h3') && $(el).hasClass('itemTitle')){
$(this).parent().addClass('active').siblings().removeClass('active');
}else if($(el).is('div') && $(el).hasClass('active')){
$(this).removeClass('active');
}
});
Not sure why every is talking about elements generated outside of the initial DOM load.
Here's a JSFiddle showing that it works: http://jsfiddle.net/H25bT/
Code:
$(document).ready(function() {
$('.itemTitle').on('click', function() {
$(this).parent().addClass('active').siblings().removeClass('active');
});
/* $('.parent').on('click', function() {
$(this).removeClass('active');
}); */
$('.clicky').on('click', function() {
$(this).parent().removeClass('active');
});
});
The reason it's not working for you is that if you put the removeClass click event on the parent div itself, clicking on the child text causes a conflict with which click handler to use, and it won't work out. Code works fine if you don't assign the click to the parent div itself.

Change class but click not recognizing the new class

I have the following html:
<div class="showMap" id="mapVis" style="cursor:pointer">(Show map)</div>
<div id="map">hello world</div>
Div #map is hidden as shown below (there's a reason for hiding it this way, it holds a google map), then I want to click (Show map) and the div appears. This is ok. Then I change the class and the html of the #mapVis div and want the next click to hide #map - but it doesn't. Honestly I don't know what its doing but its as if it ignores the new class and reverts to the actions as if previous class was still attached to the #mapVis div.
Here's the JQuery:
var map2 = $('#map');
map2.css('position','absolute').css('left','-9999em');
$('.showMap').click(function(){
map2.hide().css('position','relative').css('left','0em').slideDown();
$('#mapVis').removeClass('showMap').addClass('hideMap').html('(Hide map)');
});
$('.hideMap').click(function(){
map2.css('position','absolute').css('left','-9999em');
$('#mapVis').removeClass('hideMap').addClass('showMap').html('(Show map)');
});
Here's a fiddle
Since your selectors have to be evaluated dynamically you need to use event delegation.
When you use normal event registration the selectors are evaluated only at the time of event registration and any changes done on the element will not reflect in the registered handlers.
var map2 = $('#map');
map2.css('position', 'absolute').css('left', '-9999em');
$(document).on('click', '.showMap', function () {
console.log('hey2');
$('#map').hide().css('position', 'relative').css('left', '0em').slideDown();
$('#mapVis').removeClass('showMap').addClass('hideMap').html('(Hide map)');
});
$(document).on('click', '.hideMap', function () {
console.log('hey');
$('#map').hide();
$('#map').css('position', 'absolute').css('left', '-9999em');
$('#mapVis').removeClass('hideMap').addClass('showMap').html('(Show map)');
});
Demo: Fiddle
jsfiddle: http://jsfiddle.net/7At32/
this is a sample, BUT you can modify to your requirement
$('#mapVis').click(function () {
if ($(this).hasClass("showMap")) {
$('#map').show();
$(this).removeClass('showMap').addClass('hideMap').html('(Hide map)');
} else {
$('#map').hide();
$(this).removeClass('hideMap').addClass('showMap').html('(Show map)');
}
});

Click event is not working for dynamically changed class in jquery

I have two class .btnn and .sleep_avail sometimes i changes the css of a anchor from .btnn to .sleep_avail
Now i have two function for anchor click
$('.btnn').click(function () {
alert('yes btn');
});
And Second one is
$('.sleep_avail').click(function () {
alert('yes sleep');
});
Now when i click on the anchor with class sleep_avail which is changed dynamically from btnn class the event written for btnn raised and i get response accordingly. But what i need is that the event for sleep_avail should be raised. Kindly help.
Anytime, you use dynamically created tags, you must use
$(document).on('#event','#selector',function () {...});
so here
$(document).on('click','.sleep_avail',function () {...});
Because event handlers bind to the currently elements, they have to exist on the page when .on()is called
Here is the working DEMO http://jsfiddle.net/ARBdU/
$(document).on('click','.btnn, .sleep_avail',function () {
if($(this).hasClass('btnn'))
{
...
}
else if($(this).hasClass('sleep_avail'))
{
...
}
});
try
$(document).on('click','.sleep_avail',function () {

Categories