Removing class from two elements with jQuery - javascript

I have a weird (one more time) issue on my animation.
In a nutshell, I have a picture, when I clicked on it, two div appears, and there is a close button to remove those divs. But when I click on that button, there is only one div who dissapears.
The two new divs have got a debug class and I normally remove it when I clicked on the button
$('#gallery').on('click', 'li', function(e) {
// To display the animations with position
var $this = $(this),
dataItem = $this.data('item');
// Left animation
if ( dataItem == 1 ) {
console.log( $this );
$this
.addClass('active')
.find('.info-texte')
.removeClass('hidden')
.addClass('debug');
// When animation is ended add the second part
$this.find('.debug').on('animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd', function() {
$this.find('.info-btn')
.removeClass('hidden')
.addClass('debug');
});
}
// Supprime le href event
e.preventDefault();
});
$('.btn-close').on('click', function() {
var $this = $(this);
$this
.parents()
.eq(3)
.removeClass('active')
.find('.info-texte, .info-btn')
.removeClass('debug')
.addClass('hidden');
});
You can see in action right here : http://www.jeremybarbet.com/effect/bug.html

As per my comments, your $this.parents().eq(3) is targeting the wrong element
if you change this to $this.parents('li.active')
both of your divs should dissapear:
http://jsfiddle.net/TDsCT/
EDIT
After closer inspection it is because of your click:
$('#gallery').on('click', 'li'
this is also fired when you click on the button as the button is inside your #gallery li. I have changed your code so you click on the image instead to open and then click on your button to close:
http://jsfiddle.net/TDsCT/5/

It seems the expression $this.parents().eq(3) isn't evaluating to your desired result -- the two divs on the left. Perhaps try a different set of DOM traversal methods? (e.g. $this.parents().eq(2).prev() and $this.parents().eq(2), though this would be sort of a kludge)

Related

Click event prevents mouseout from triggering

FINAL EDIT: I found a better solution and more simpler on this codepen. A demo of the working functionality.
EDIT: I found where the bug is coming from you can see an example here. When you click on lets say the About tab and hover over and out on contact the content should be hidden. But you go back to hover over About and out the content stays visible, which is not. How do I ensure the mouseout event is being triggered after clicked?
EDIT 2: So I noticed the unbind() method prevents that. When I remove it I can't seem to get the content area to stay active when clicked as the mouseout method overrides it.
I did some research on this but could not find a solution as to why on hover the removeclass does not work. I have encountered a bug with addClass() and removeClass() functions. The thing is I have those function firing on hover or mouseover/mouseout and on click so it gets a bit confusing. Here is a demo of what I'm working with: JSFiddle.
Full screen for better view.
My JavaScript can be kind of messy but ultimately the way this is suppose to work:
1. If you hover over a dot on the map the content on the left red box should reveal what's relevant to the location as well as a 'tooltip' of the location name. (this part works)
2. You mouse out it's suppose to go back to the list of locations and the tooltip disappears. Almost like a reset.
3. Now if you click on the dot, both the tooltip and the content on the left should remain active. Until you either click on the "Back to the list" link on the red box or hover over the other dots. (this also works)
The bug I encountered is if you click around the list panel and hover over a couple of the location dots after a certain while the hover state stays active when you hover over a couple of the locations (which is not suppose to happen). Everything is suppose to go back the list panel when you hover out of the location dot on the map.
$('a.location').click(function (event) {
var loc = this.id;
if ($('div.panel').hasClass('list')) {
$('div.' + loc).removeClass('current');
$('.list').addClass('current');
}
$('.list').removeClass('current');
$('div.panel.' + loc).addClass('current');
event.preventDefault();
}); //click function
$('.back-list').click(function (e) {
$('.panel').removeClass('current');
$('.list').addClass('current');
$('div.location-title.show').removeClass('show').addClass('hide');
$('div.location-title.view').removeClass('view');
e.preventDefault();
}); //back button
$('ul.locations li > a').hover(function () {
//show location hover
var dot = this.id;
$('div.location-title.' + dot).removeClass('hide').addClass('show');
}, function () {
var dot = this.id;
//hide location hover
$('div.location-title.' + dot).removeClass('show').addClass('hide');
}).click(function (event) {
var dot = this.id;
if (!$('div.location-title.' + dot).hasClass('hide')) {
$('div.location-title.' + dot).addClass('view');
} else {
$('div.location-title.' + dot).removeClass('view');
}
event.preventDefault();
});
$('.map__container > span').on({
mouseover: function () { //mouseover
var loc = $(this).attr('class');
$('.panel').siblings().removeClass('current'); //resets all classes that have current
$('.list').removeClass('current');
$('div.panel.' + loc).addClass('current');
$('div.show').removeClass('show').addClass('hide');
$('div.location-title.' + loc).removeClass('hide').addClass('show');
var asb = $('.location-title').siblings();
$('div.location-title').siblings().removeClass('view');
},
mouseout: function () { //mouseout
var loc = $(this).attr('class');
$('div.' + loc).removeClass('current');
$('div.location-title.' + loc).removeClass('show').addClass('hide');
if (!$('div.' + loc).hasClass('current')) {
$('.list').addClass('current');
} else {
$('.list').addClass('current');
}
},
click: function () {
$(this).off('mouseout');
var loc = $(this).attr('class');
$('div.location-title.show').removeClass('show').addClass('hide');
$('div.location-title.' + loc).removeClass('hide').addClass('show');
}
});
Also if you have better suggestions to clean up my JavaScript I'm all ears. Thanks so much!
If i understand right, you might want to try with the event Mouseleave, and i would use to modularize the function toggleClass:
ToggleClass function Jquery
Mouseleave explanation:
mouseleave: function () { //mouseout
var loc = $(this).attr('class');
$('div.' + loc).removeClass('current');
$('div.location-title.' + loc).removeClass('show').addClass('hide');
if (!$('div.' + loc).hasClass('current')) {
$('.list').addClass('current');
} else {
$('.list').addClass('current');
}
},
I hope this helps you. Salutations!
FINAL EDIT: I found a better solution and more simpler on this codepen. A demo of the working functionality.
My problem was in the code example above the $(this).off('mouseout'); was removing the mouseout when clicked. So if you were to hover back to that dot on the map and mouseout the 'tooltip' would stay active, it won't disappear when you mouseout, which it should disappear. I couldn't find a way to bind it again so the toggleClass() was much better. I been pulling my hair on this!
$('.map__container span').click(function(mapIcon){
mapIcon.preventDefault();
var icon = $(this).attr('class');
var panel = $(this).attr('class');
$('.panel').removeClass('clicked');
$('.location-title').removeClass('clicked');
$('.panel.' + panel).addClass('clicked');
$('.location-title.' + icon).addClass('clicked');
});
//Show bubbles over dots on map
$('.map__container span').hover(function(){
var hoverdot = $(this).attr('class');
$('.location-title.' + hoverdot).toggleClass('selected');
});
//Show bubbles on hover over anchor links
$('a.location').hover(function(){
var hoverlink = this.id;
$('.location-title.' + hoverlink).toggleClass('selected');
});
//Anchor links show panels and bubbles
$('a.location').click(function(e){
e.preventDefault();
var panel = this.id;
var icon = this.id;
$('.panel').removeClass('clicked');
$('.location-title').removeClass('clicked');
$('.panel.' + panel).addClass('clicked');
$('.location-title.' + icon).addClass('clicked');
});
//back button
$('.back-list').click(function(backButton) {
backButton.preventDefault();
$('.panel').removeClass('clicked');
$('.location-title').removeClass('clicked');
$('.list').addClass('clicked');
});

How to Show or Hide n'th div when clicking on the n'th link?

I have some set of <div>...</div> in one child of a parent. And some set of <a>click</a> buttons on other child of the same parent. When I click on the first link of child-2, the first div of the child one have to be displayed.
Here is the fiddle I used.
But, I used class name to show or hide the div. I need the script which can select n'th element automatically.
Code I used is below.
$('.box').hide();
$(".click-btn1").on('click', function() {
$('.box').slideUp('slow');
$(this).parent().parent().parent().parent().children().children(".box1").slideDown('slow');
});
$(".click-btn2").on('click', function() {
$('.box').slideUp('slow');
$(this).parent().parent().parent().parent().children().children(".box2").slideDown('slow');
});
$(".click-btn3").on('click', function() {
$('.box').slideUp('slow');
$(this).parent().parent().parent().parent().children().children(".box3").slideDown('slow');
});
Using .index() can simplify your code a lot:
$('.box').hide();
$(".click-btn").on('click', function () {
$('.box').slideUp('slow');
var i = $(this).parent().parent().index();
$('.box').eq(i).slideDown('slow');
});
This just figures out which button it is, and then slides the box at that index.
You can do this by index if your DOM elements will be in the same order:
$('.box').hide();
$(".click-btn").on('click', function() {
$('.box').slideUp('slow');
$('.total-1').children().eq($(this).parents('.single').index()).slideDown('slow');
});

Jquery - How to get elements in a list item

I have the following code:
<li class="shop-currencies">
€
£
$
R
</li>
When an item is clicked I want to set the class to the clicked item and get the ID of the item clicked. This is what I have so far:
$('.shop-currencies').click(function() {
var id = $(this).attr('id');
alert(id);
/**
* Remove the classes from the currency elements
*/
$('.shop-currencies').find('a').each(function(e) {
$(this).removeClass();
});
/**
* Set the class of the clicked element
*/
$( '#' + id).addClass('current');
});
The ID is being returned as 'undefined' How do I get the ID of the clicked link?
Thanks
You need to attach click handler to child anchor element :
$('.shop-currencies a').click(function() {
var id = $(this).attr('id');
alert(id);
/**
* Remove the classes from the currency elements
*/
$('.shop-currencies').find('a').not(this).removeClass('smclass')
/**
* Add class to current elements
*/
$(this).addClass('smclass')
});
There are a couple of options, Milind Anantwar has one, the other is to use the originally clicked element, which is passed to the event as a target property on the event argument. You can also simplify your code a lot. Please note that your bookmark anchors will cause the page to spring to the top, so also add e.preventDefault(); to any solution you choose:
$('.shop-currencies').click(function(e) {
e.preventDefault();
$('a', this).removeClass('current'); // remove related anchor current class
$(e.target).addClass('current');
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/
The one downside to this is that clicking inside .shop-currencies, but not on a currency link, will clear the current selection. Because of this you are better off targetting the links instead:
$('.shop-currencies a').click(function(e) {
e.preventDefault();
$(this).siblings().removeClass('current'); // remove related anchor current class
$(this).addClass('current');
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/1/
Which can be reduced to one line:
$('.shop-currencies a').click(function(e) {
e.preventDefault();
$(this).addClass('current').siblings().removeClass('current');
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/2/
Saving the best for last
And one last point... It is more efficient (but hardly noticeable) to add a single delegated event handler, instead of attaching 4 seperate handlers:
$('.shop-currencies').on('click', 'a', function(e) {
e.preventDefault();
$(this).addClass('current').siblings().removeClass('current');
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/3/
Final thoughts:
The IDs on the links are unnecessary if you have an appropriate this available. You can remove them from the HTML. You have the currency value you require in data-currency attributes, so you could use it like this:
$('.shop-currencies').on('click', 'a', function(e) {
e.preventDefault();
$(this).addClass('current').siblings().removeClass('current');
alert($(this).data('currency'));
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/5Lsuazvt/7/
your click, is attach to li instead of each a tag
so do $('a').click();instead
Shortest and fastest answer
$('.shop-currencies > a').click(function(){
$(this).siblings('a').removeClass('current');
$(this).addClass('current');
});
The code pen link is here, you can play with the code your self
$('.shop-currencies a').each(function() {
$(this).on("click", function(event) {
event.preventDefault();
var id = $(this).attr('id');
$('.shop-currencies a').removeClass("current");
$(this).addClass('current');
alert(id);
});
});
http://jsfiddle.net/nj37g5rm/8/

jQuery Accordion arrow icons with seperate close button

I've got an accordion with arrow icons indicating when a section is open and closed. Once the accordion is opened the arrow points down showing the content below it.
However I've created a close button that gets appended into each section. This sits at the bottom of every section in the accordion.
I want it so that once the close button is pressed the arrow changes it's state back to closed.
$(function() {
$('#accordion h3').each(function(){
var $set = $(this).nextUntil("h3");
$set.wrapAll('<div />');
});
$('#accordion').accordion({ collapsible:true, active:true, heightStyle:"content", disabled:true, animated: false});
$('.ui-accordion-header').bind('click',function(){
theOffset = $(this).offset();
$(window).scrollTop(theOffset.top - 50);
});
$('#accordion h3.ui-accordion-header').click(function(){
var _this = $(this);
$('.ui-accordion-header-icon', _this).toggleClass('ui-icon-triangle-1-e ui-icon-triangle-1-s');
_this.next().slideToggle();
return false;
});
$('.ui-accordion-content').append('Close<div class="clearfix"></div>');
$('.close').click(function(){
$(this).closest('.ui-accordion-content').toggleClass('ui-icon-triangle-1-s');
$(this).parent().slideUp('slow', function(){
$(window).scrollTop(theOffset.top - 50);
var hidecollapsebutton = true;
$('.ui-accordion-content').each(function(){
if($(this).css('display') == 'block')
{
hidecollapsebutton = false;
}
});
if(hidecollapsebutton)
{
$('.accordion-expand-all').show();
$('.accordion-collapse-all').hide();
}
});
return false;
})
});
Any help would be much appreciated. I can provide more information if it's needed. Thanks.
http://jsfiddle.net/EZT6A/
$('.close').click(function(){
$(this).closest('.ui-accordion-content').toggleClass('ui-icon-triangle-1-s');
As you could have found out yourself with a little simple debugging, $(this).closest('.ui-accordion-content') does not match any element here. (That’s because your close button is within div.ui-accordion-content, and the h3.ui-accordion-header is the previous sibling of that div element.)
Simple to fix: Go up to parent div (.ui-accordion-content), get previous h3 (.ui-accordion-header), and then the span (.ui-accordion-header-icon) element within it:
$(this).parents('.ui-accordion-content')
.prev('.ui-accordion-header')
.find('.ui-accordion-header-icon')
.removeClass('ui-icon-triangle-1-s')
.addClass('ui-icon-triangle-1-e');
http://jsfiddle.net/EZT6A/2/
I'd try changing click to on:
$(document).on("click", ".close", function(){
//change arrow state
});
It's because not every .close element exist as you binding click event.

click elsewhere

i have problem with click event. click to another element with event(click), doesn't count like click elsewhere. I want active one element or none.
demo: http://jsfiddle.net/WP4RH/
code:
$('span').click(function(){
var $this = $(this);
if($this.hasClass('active')){
$this.removeClass('active')}
else $this.addClass('active');
$('div').click(function(){
if (!$this.has(this).length) {
$this.removeClass('active');
}
});
return false;
});
Add this at the beginning of your span event handler:
$('.active').removeClass('active');
Demo
This is assuming that you want multiple clicks on the same span to retain active. If you don't want that, then let me know and I can modify the code.
​
For starters, You should move the div handler outside and then removeClass based on div element.
$('span').click(function(e) {
e.stopPropagation();
$(this).parent().find('span').removeClass('active');
$(this).toggleClass('active');
});
$('div').click(function() {
$(this).find('span').removeClass('active');
});
DEMO: http://jsfiddle.net/WP4RH/1/
Don't bind a click handler inside a click handler, just check if the target is the div or the span inside the click handler instead. Also, when adding the active class to this, just remove it on any sibling span :
$('span').on('click', function(){
$(this).toggleClass('active').siblings('span').removeClass('active');
});
$('div').on('click', function(e){
if (e.target == this) $('span').removeClass('active');
});
FIDDLE
​
If you want to keep the toggle-off functionality when the span itself has been clicked, then you can use the following. Also, note that you're binding an event handler each time a span is clicked.
http://jsfiddle.net/WP4RH/7/
$("span").click(function() {
$(this).siblings("span").removeClass("active"); // remove from other spans
$(this).toggleClass("active"); // toggle this span
return false;
});
​
$("div").click(function() {
$(this).find("span").removeClass("active"); // remove from all spans
});

Categories

Resources