Я создал некоторый код, который работает как аккордеон, позволяя пользователю открывать аккордеоны (и вложенные аккордеоны).
Функциональность поиска также продемонстрирована, с автоматическим открытием любых аккордеонов, где найден термин, и их родителей.
Код полностью прокомментирован, но дайте мне знать, если он не ясен.
Благодаря SLaks за функцию поиска текста элемента без текста его потомка ( ссылка ).
Демонстрация
// Add click event to all .accordian-title
$(".accordian-title").click( function() {
// Check if this is already active
wasActive = $(this).closest(".accordian-element").hasClass("active");
// Remove all the .active siblings
$(this).closest(".accordian-wrapper").find(".accordian-element.active").removeClass("active");
// Activate the clicked .accordian-element if it wasn't active
if ( wasActive != true ) {
$(this).closest(".accordian-element").toggleClass("active");
}
});
// Launch search code after any change to input
$("#search").on('change keydown paste input', function() {
// Remove search term matching
$(".accordian-wrapper .found-term").removeClass("found-term");
// Remove all active classes
$(".accordian-wrapper .accordian-element.active").removeClass("active");
// Get search term
searchTerm = $(this).val().toUpperCase();
// Quit if search term is empty
// IT MIGHT BE A GOOD IDEA TO ADD A MINIMUM 3 CHARACTERS OR SIMILAR
if ( searchTerm == "" ) {
$(".accordian-wrapper").removeClass("searched");
return;
}
$(".accordian-wrapper").addClass("searched");
// Check anything within an accordian against the term
$(".accordian-wrapper *").each( function() {
// Get text only of this element (not children)
tempText = $(this).immediateText().toUpperCase();
// Check if search term is present in element
if ( tempText.indexOf(searchTerm) >= 0) {
// Add found-term to highlight the element with the search text
$(this).addClass("found-term");
// Activate all parent accordians to that it is visible
$(this).parents(".accordian-element").addClass("active");
}
});
});
// Get text of given element, but not it's children
// Taken from : /3058539/ispolzovanie-text-dlya-izvlecheniya-tolko-teksta-ne-vlozhennogo-v-dochernie-tegianswer-32170000
$.fn.immediateText = function() {
return this.contents().not(this.children()).text();
};
/* Styling to hide and show content on click */
.accordian-content {
display: none;
}
.accordian-element.active > .accordian-content {
display: inherit;
}
.accordian-title {
cursor: pointer;
}
/* Styling for searching content and highlighting it */
.accordian-wrapper.searched .accordian-element {
display: none;
}
.accordian-wrapper.searched .accordian-element.active {
display: inherit ;
}
.found-term {
color: red;
}
/* Just some general styling to make it look nice */
.accordian-wrapper {
border-left: 5px solid grey;
border-top: 1px dashed grey;
}
.accordian-element {
padding: 10px 0px 10px 20px;
border-bottom: 1px dashed grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Search: <input id="search">
<hr style="margin: 20px 0px;">
<div class="accordian-wrapper">
<div class="accordian-element">
<h4 class="accordian-title">Registering</h4>
<div class="accordian-content">
<p>This is an explaination text area, because I am not inside the child .accordian-wrapper I am visible when my accoridan-title is clicked!</p>
<div class="accordian-wrapper">
<div class="accordian-element">
<h4 class="accordian-title">Registration Page</h4>
<div class="accordian-content">
<p>The URL to the registration page is '/register.html'</p>
</div>
</div>
<div class="accordian-element">
<h4 class="accordian-title">Registration Form</h4>
<div class="accordian-content">
<p>The form requires you to fill out your e-mail, name and phone number.</p>
</div>
</div>
</div>
</div>
</div>
<div class="accordian-element">
<h4 class="accordian-title">How do I login?</h4>
<div class="accordian-content">
<p>Logging in is easy, you can loging at '/login.html' or use a linked social media account.</p>
</div>
</div>
<div class="accordian-element">
<h4 class="accordian-title">Some other title</h4>
<div class="accordian-content">
<p>Lorem ipsum</p>
</div>
</div>
</div>