In this scenario, you have several options at your disposal. However, the commonality among them is that upon clicking on a .title-arrow
element, you are able to identify which specific .title-arrow
was clicked by accessing its value through this
(and event.currentTarget
) within the event callback. Subsequently, using various DOM properties and methods like closest
or the element version of querySelector
, you can locate the other related elements.
One approach could involve iterating through all the .title-arrow
elements and attaching a click
event listener to each, followed by determining the necessary actions from there. Alternatively, utilizing event delegation might be more suitable: Attaching click
event handling only once to the container housing the various .ideanode
elements, and then discerning the required action based on event.target
.
Assuming that all the .ideanode
elements reside within a container structure similar to:
<div class="container">
<div class="ideanode">
<div class="ideanodeheader">Need</div>
<div class="content">
<div class="title">
<h3 contenteditable="True" onclick='this.focus();'>Title</h3>
</div>
<i class="fas fa-sort-down title-arrow">v</i>
<div class="maintext">
<textarea placeholder="Text" class="maintextinput"></textarea>
</div>
<i class="fas fa-sort-down maintxt-arrow">v</i>
<div class="comments">
<textarea placeholder="Comments" class="commentsinput"></textarea>
</div>
</div>
</div>
<div class="ideanode">
<div class="ideanodeheader">Need</div>
<div class="content">
<div class="title">
<h3 contenteditable="True" onclick='this.focus();'>Title</h3>
</div>
<i class="fas fa-sort-down title-arrow">v</i>
<div class="maintext">
<textarea placeholder="Text" class="maintextinput"></textarea>
</div>
<i class="fas fa-sort-down maintxt-arrow">v</i>
<div class="comments">
<textarea placeholder="Comments" class="commentsinput"></textarea>
</div>
</div>
</div>
<!-- ...and so forth... -->
</div>
Therefore, the following implementation is feasible (refer to comments):
// Single handler attached to the container
document.querySelector(".container").addEventListener("click", function(event) {
// Identifying the clicked arrow and its corresponding .ideanode, if any
const arrow = event.target.closest(".title-arrow, .maintxt-arrow");
const ideanode = arrow && arrow.closest(".ideanode");
if (!ideanode || !this.contains(ideanode)) {
// Click did not target a .title-arrow or .maintxt-arrow within an .ideanode
return;
}
if (arrow.matches(".title-arrow")) {
// A .title-arrow was clicked
titleArrowClick.call(arrow, ideanode, event);
} else {
// A .maintxt-arrow was clicked
mainArrowClick.call(arrow, ideanode, event);
}
});
function titleArrowClick(ideanode, event) {
// Applying `querySelector` to find elements within .ideanode
ideanode.querySelector(".maintext").classList.toggle("hidden");
ideanode.querySelector(".maintxt-arrow").classList.toggle("hidden");
const comments = ideanode.querySelector(".comments");
if (comments.classList.contains("hidden")){
;
} else {
comments.classList.toggle("hidden");
};
}
function mainArrowClick(ideanode, event) {
ideanode.querySelector(".comments").classList.toggle("hidden");
}
Live Example:
// Single handler attached to the container
document.querySelector(".container").addEventListener("click", function(event) {
// Identifying the clicked arrow and its corresponding .ideanode, if any
const arrow = event.target.closest(".title-arrow, .maintxt-arrow");
const ideanode = arrow && arrow.closest(".ideanode");
if (!ideanode || !this.contains(ideanode)) {
// Click did not target a .title-arrow or .maintxt-arrow within an .ideanode
return;
}
if (arrow.matches(".title-arrow")) {
// A .title-arrow was clicked
titleArrowClick.call(arrow, ideanode, event);
} else {
// A .maintxt-arrow was clicked
mainArrowClick.call(arrow, ideanode, event);
}
});
function titleArrowClick(ideanode, event) {
// Applying `querySelector` to find elements within .ideanode
ideanode.querySelector(".maintext").classList.toggle("hidden");
ideanode.querySelector(".maintxt-arrow").classList.toggle("hidden");
const comments = ideanode.querySelector(".comments");
if (comments.classList.contains("hidden")){
;
} else {
comments.classList.toggle("hidden");
};
}
function mainArrowClick(ideanode, event) {
ideanode.querySelector(".comments").classList.toggle("hidden");
}
.hidden {
display: none;
}
<div class="container">
<div class="ideanode">
<div class="ideanodeheader">Need</div>
<div class="content">
<div class="title">
<h3 contenteditable="True" onclick='this.focus();'>Title</h3>
</div>
<i class="fas fa-sort-down title-arrow">v</i>
<div class="maintext">
<textarea placeholder="Text" class="maintextinput"></textarea>
</div>
<i class="fas fa-sort-down maintxt-arrow">v</i>
<div class="comments">
<textarea placeholder="Comments" class="commentsinput"></textarea>
</div>
</div>
</div>
<div class="ideanode">
<div class="ideanodeheader">Need</div>
<div class="content">
<div class="title">
<h3 contenteditable="True" onclick='this.focus();'>Title</h3>
</div>
<i class="fas fa-sort-down title-arrow">v</i>
<div class="maintext">
<textarea placeholder="Text" class="maintextinput"></textarea>
</div>
<i class="fas fa-sort-down maintxt-arrow">v</i>
<div class="comments">
<textarea placeholder="Comments" class="commentsinput"></textarea>
</div>
</div>
</div>
<!-- ...and so on... -->
</div>