Reputation: 1491
I have a long list of team members; when a user clicks a CTA on an individual member, a class is added to a modal box that sets it visible. However, currently every single modal window opens at the same time as they're all using the same classes.
I am wondering if it's possible to look to add the new class to the specific team member that was pressed, I know this is possible through giving each their own class and having multiple of the same jQuery functions - but this isn't really a solution I want to go down as there are a lot, and more will be added in the future (meaning I'll have to update the Js code for them).
Note: I'm using WordPress so am able to use PHP variables and the like.
$('.modal-toggle').on('click', function(e) {
e.preventDefault();
$('.modal').toggleClass('visible');
});
.main {
position:relative;
}
article {
background: red;
position: relative;
border-top: 2px solid red;
display: flex;
align-items: center;
margin-bottom: 20px;
width: 100%;
height: 180px;
}
img {
height: auto;
width: 180px;
}
.content {
padding: 30px 35px;
}
h3 {
font-weight: 400;
margin-bottom: 10px;
text-decoration: underline;
font-size: 22pt;
line-height: 28pt;
}
& > span {
font-style: italic;
}
aside {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 25px;
}
div.button {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: $red;
width: 35px;
height: 35px;
}
.modal {
position: absolute;
z-index: 10;
top: 0;
left: 0;
width: 100%;
height: 100%;
visibility: hidden;
}
.modal-overlay {
position: fixed;
z-index: 5;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
visibility: hidden;
opacity: 0;
transition: visibility 0s linear 0.3s, opacity 0.3s;
}
.modal.visible {
visibility: visible;
}
.modal.visible .modal-overlay {
opacity: 1;
visibility: visible;
transition-delay: 0s;
}
.modal.visible .modal-window {
transform: translate(-50%, -50%);
opacity: 1;
}
.modal-window {
position: absolute;
z-index: 11;
top: 50%;
left: 50%;
transform: translate(-50%, -100%);
opacity: 0;
transition: all 0.3s 0.15s;
background: $white;
border-top: 2px solid red;
width: 900px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
<article class="team-member filter-result result-1">
<img src="https://via.placeholder.com/85" alt="" />
<div class="content">
<h3>Name</h3>
<aside>
<div class="modal-toggle button" href="#">CLICK</div>
</aside>
</div>
</article>
<div class="modal">
<div class="modal-overlay modal-toggle"></div>
<div class="modal-window">
<h1>Lorem Ipsum</h1>
</div>
</div>
<article class="team-member filter-result result-2">
<img src="https://via.placeholder.com/85" alt="" />
<div class="content">
<h3>Name</h3>
<aside>
<div class="modal-toggle" href="#">CLICK</div>
</aside>
</div>
</article>
<div class="modal">
<div class="modal-overlay modal-toggle"></div>
<div class="modal-window">
<h1>Lorem Ipsum</h1>
</div>
</div>
<article class="team-member filter-result result-3">
<img src="https://via.placeholder.com/85" alt="" />
<div class="content">
<h3>Name</h3>
<aside>
<div class="modal-toggle" href="#">CLICK</div>
</aside>
</div>
</article>
<div class="modal">
<div class="modal-overlay modal-toggle"></div>
<div class="modal-window">
<h1>Lorem Ipsum</h1>
</div>
</div>
</div>
Upvotes: 0
Views: 50
Reputation: 327
Quick solution is to place .modal
in the same article
parent of modal-toggle
. This way you can adjust your listener to target the .modal
corresponding to the .modal-toggle
that was clicked.
$('.modal-toggle').on('click', function(e) {
e.preventDefault();
//this way
$(this).siblings('.modal').toggleClass('visible');
// or this way or other ways too
$(this).parent().find('.modal').toggleClass('visible');
});
Upvotes: 2
Reputation: 1075755
Yes, you can traverse the DOM to find the modal:
$('.modal-toggle').on('click', function(e) {
e.preventDefault();
$(this).closest("article").next().toggleClass('visible');
});
$(this)
gets a jQuery wrapper for just the element that was clicked, .closest("article")
finds its wrapping article
element, and .next()
goes to the element after it (the modal).
It would be better if the article
and the modal were both in the same wrapper element because using .next()
is a bit fragile (what if you add an element between the article
and the modal
?). Then you could do .closest("the-container").find(".modal")
. If you can't do that, you can mitigate it slightly by using .nextAll(".modal").first()
instead:
$('.modal-toggle').on('click', function(e) {
e.preventDefault();
$(this).closest("article").nextAll(".modal").first().toggleClass('visible');
});
The jQuery object from .nextAll
is in order from the nearest matching following sibling to the furthers, so first
reliably gets the first one.
This is all covered in the traversing section of the jQuery API documentation, which is very thorough.
Upvotes: 3