Reputation: 783
I've made an little design with circles that expand when clicking on them. I've multiple circles and want to be able to click and expand on one circle at a time and then the other circle closes.
Here's a codeply of my example: https://www.codeply.com/p/7QdDsEF9ul
And here's the jQuery snippet:
$('.product1').click(function () {
$('#product1').toggleClass('expand');
$('.hidden#1').toggleClass('show');
$('.hidden#2').removeClass('show');
$('#product2').removeClass('expand');
});
$('.product2').click(function () {
$('#product2').toggleClass('expand');
$('.hidden#2').toggleClass('show');
});
As you can see this is not going to be very efficient, especially if I add more circles. Is there an easier way of doing this?
Upvotes: 0
Views: 41
Reputation: 1403
Get rid of the id
and just use the class .product
, then itereate through all
$('.product').each(function(i,v){
console.log({i:i,v:v,'$(this)':$(this)});
$(this).on('click',function(){
$(this).toggleClass('expand');
$(this).find('.hidden').toggleClass('show');
})
});
In your current html, this is what you said product DOM looks like:
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product2">
<div class="circle" id="product1">
<h2>Title 1</h2>
<div class="hidden" id="2"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
By changing just this line:
<div class="circle" id="product1">
to:
<div class="circle product">
you can iterate through all and toggle classes for itself and its child '.hidden'
The $(this)
keyword has special meaning inside callback functions like .each()
, however i also left in the function(i,v)
which means function(index,value)
so you can even use those, as i showed via console.
Showing only one product circle at a time
I left everything as the simple toggleClass()
that you shared above, though if you wanted to be more explicit you can use hasClass()
checks, and can also have only one visible product circle at all times by adding this to first line of the click handler:
$('.product.expand').removeClass('expand').find('.hidden').removeClass('show');
Working Snippet/Fiddle
Codeply needs you to create account and doesnt include code inside post in case service goes down in future, so i moved this inside a stackoverflow snippet so you can see working code.
$('.product').each(function(i,v){
// console.log({i:i,v:v,'$(this)':$(this)});
$(this).on('click',function(){
// $('.product.expand').removeClass('expand').find('.hidden').removeClass('show');
$(this).toggleClass('expand');
$(this).find('.hidden').toggleClass('show');
})
});
// $('.product1').click(function() {
// $(this).nextAll('.hidden:first').toggleClass('show');
// });
a {
font-size: 2.25em;
}
.active {
color: #6bd627;
}
.circle {
width: 150px;
height: 150px;
background-color: #00aae8;
border-radius: 50%;
justify-content: center;
align-items: center;
display: flex;
transition: all 0.3s ease-in-out;
position: absolute;
}
.circle h2 {
color: #fff;
font-size: 0.7em;
margin-bottom: auto;
margin-top: 55px;
}
.expand {
height: 248px !important;
background-color: #6bd627 !important;
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-left-radius: 0%;
border-bottom-right-radius: 0%;
transition: all 0.3s ease-in-out;
position: absolute;
}
.hidden {
display: none;
opacity: 0;
transition: all 0.3s ease-in-out;
}
.show {
display: block !important;
position: absolute;
opacity: 1;
transition: all 0.3s ease-in-out;
}
.link {
font-size: 0.5em;
color: #000;
}
ul, ol {
margin: 0;
}
li {
margin-bottom: -0.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<div class="container-fluid s1" style="margin-bottom:400px;">
<div class="container py-5">
<div class="row py-5 align-items-end">
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product1">
<div class="circle product">
<h2>Title 1</h2>
<div class="hidden" id="1"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product2">
<div class="circle product">
<h2>Title 1</h2>
<div class="hidden" id="2"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product1">
<div class="circle product">
<h2>Title 1</h2>
<div class="hidden"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
Upvotes: 0
Reputation: 371019
Since the div
that needs to be shown is a descendant of the .circle
which has its class changed when shown, you can avoid having to fiddle with the child div by using the CSS rule .expand div
instead. This way, changes to the parent with .expand
will be sufficient.
Give all the <a>
s a common class, maybe product
, and on click, check to see if its child (the .circle
) has the expand
class or not. If it does, remove .expand
from all elements - otherwise, remove expand
from all elements but then add it to the .circle
child:
$('.product').click(function() {
const $circle = $(this).children();
if ($circle.hasClass('expand')) {
$('.expand').removeClass('expand');
} else {
$('.expand').removeClass('expand');
$circle.addClass('expand');
}
});
a {
font-size: 2.25em;
}
.active {
color: #6bd627;
}
.circle {
width: 150px;
height: 150px;
background-color: #00aae8;
border-radius: 50%;
justify-content: center;
align-items: center;
display: flex;
transition: all 0.3s ease-in-out;
position: absolute;
}
.circle h2 {
color: #fff;
font-size: 0.7em;
margin-bottom: auto;
margin-top: 55px;
}
.expand {
height: 248px !important;
background-color: #6bd627 !important;
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-left-radius: 0%;
border-bottom-right-radius: 0%;
transition: all 0.3s ease-in-out;
position: absolute;
}
.hidden {
display: none;
opacity: 0;
transition: all 0.3s ease-in-out;
}
.expand div {
display: block !important;
position: absolute;
opacity: 1;
transition: all 0.3s ease-in-out;
}
.link {
font-size: 0.5em;
color: #000;
}
ul,
ol {
margin: 0;
}
li {
margin-bottom: -0.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid s1">
<div class="container py-5">
<div class="row py-5 align-items-end">
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product">
<div class="circle">
<h2>Title 1</h2>
<div class="hidden"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product">
<div class="circle">
<h2>Title 1</h2>
<div class="hidden" id="2"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
<div class="col-sm text-center">
<img src="https://placehold.it/300x300" class="pb-3 img-fluid" />
<a href="javascript:void(0)" class="d-flex justify-content-center mt-0 product">
<div class="circle">
<h2>Title 1</h2>
<div class="hidden"><br>
<ul class="list-unstyled">
<li class="list-item"><span class="link">Top Picks</span></li>
<li class="list-item"><span class="link">By Brand</span></li>
<li class="list-item"><span class="link">By Price</span></li>
</ul>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
You don't need any IDs or numeric-indexed classes now.
Upvotes: 1