'Turning an unordered list Table of Contents into a dropdown menu with JS/jQuery/CSS [duplicate]
I have an automatically generated table of contents that is an unordered list:
<ul class="elementor-toc__list-wrapper"><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-0" class="elementor-toc__list-item-text elementor-toc__top-level elementor-item-active">How AP Exams Are Scored</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-1" class="elementor-toc__list-item-text elementor-toc__top-level">What Are AP Scores Used for?</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-2" class="elementor-toc__list-item-text elementor-toc__top-level">What is Advanced Placement® and Credit?</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-3" class="elementor-toc__list-item-text elementor-toc__top-level">What AP Exam Scores Do Colleges And Universities Accept?</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-4" class="elementor-toc__list-item-text elementor-toc__top-level">AP Exam Score Distribution</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-5" class="elementor-toc__list-item-text elementor-toc__top-level">Frequently Answered Questions (FAQs)</a></div></li></ul>
I want this list to turn into a dropdown on mobile (below 768px). I want to either use jQuery on pageload to generate a dropdown menu (<option...) based off of this ul li, and then show/hide accordingly on mobile/desktop,
Or if possible I want to turn it into a dropdown menu with just CSS.
the code I'm using that needs to be improved (keep in mind I'm using WP rocket that defers JS, and delays JS execution, which I'm trying to work around):
<script type="text/javascript">
// Table of Contents (ToC) code - new April 19 2022
document.addEventListener("DOMContentLoaded", function(event) {
// console.log("document ready");
runWhenJqueryIsLoaded();
function runWhenJqueryIsLoaded() {
if( window.jQuery ) {
jQuery(window).on("resize", function (e) {
checkScreenSize();
});
// Table of Contents (ToC) code
function convertTOCtoDropdown() {
//first, store original non-mobile TOC so we can reverse back to it
window.originalTOC = jQuery("#TOC .elementor-toc__list-wrapper");
jQuery(function() {
jQuery("#TOC ul.elementor-toc__list-wrapper").each(function() {
var $select = jQuery("<select />");
jQuery(this).find("a").each(function() {
var $option = jQuery("<option />");
$option.attr("value", jQuery(this).attr("href")).html(jQuery(this).html());
$select.append($option);
});
jQuery(this).replaceWith($select);
});
// make mobile dropdown ToC function
jQuery("#TOC select").change(function() {
var cTarget = jQuery(this).val();
window.location.hash = cTarget;
});
jQuery("#TOC select").wrap("<div class='dropdown-container stickyDropdown' id='section-nav-mobile'></div>" );
});
}
function checkScreenSize(){
var newWindowWidth = jQuery(window).width();
// if the screen is smaller than 768, and if mobile dropdown does not exist
if ((newWindowWidth < 768) && (jQuery(".dropdown-container").length == 0)) {
// show mobile dropdown, hide desktop ToC
convertTOCtoDropdown();
makeMobileDropdownSticky();
// console.log('convert to dropdown, and make sticky');
}
// if screen is larger than 768, and if mobile dropdown exists in DOM
else if ((newWindowWidth > 768) && (jQuery(".dropdown-container").length !== 0) && (jQuery("#TOC .elementor-toc__list-wrapper").length == 0)) {
jQuery(".elementor-toc__header").show();
jQuery(".dropdown-container").replaceWith(window.originalTOC);
}
}
function makeMobileDropdownSticky() {
jQuery(window).scroll(function() {
if (jQuery(document).scrollTop() > jQuery(".elementor-background-overlay").height() - jQuery(".stickyDropdown").height() ) {
jQuery('.stickyDropdown').css('position', 'fixed');
jQuery('.stickyDropdown').css('top', jQuery("#ast-mobile-header").height());
jQuery(".stickyDropdown").css("width", jQuery("#contentsColumn").width());
}
else {
jQuery('.stickyDropdown').css('position', 'relative');
jQuery('.stickyDropdown').css('top', '');
jQuery('.stickyDropdown').css('width', '');
}
});
}
checkScreenSize();
} else {
// wait 50 milliseconds and try again.
window.setTimeout( runWhenJqueryIsLoaded, 250 );
}
}
});
</script>
Solution 1:[1]
You mean something like this?? Resize it to 768px I would go to something similar like this and add the query to your existing one. Let me know if this is what you mean.Note that this doesnt need to be a button it can be anything you want and style whatever you want it to be.
$('.questions>button').click(function(){
$('.elementor-toc__list-item-text-wrapper').toggle();
});
button#questions{display:none;}
@media only screen and (max-width:768px){
button#questions {display:inline;}
.elementor-toc__list-item-text-wrapper {
display:none;
}
li.elementor-toc__list-item {list-style-type:none;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="questions"><button id="questions">For More Quetions</button>
<ul class="elementor-toc__list-wrapper">
<li class="elementor-toc__list-item">
<div class="elementor-toc__list-item-text-wrapper">
<i class=""></i>
<a href="#elementor-toc__heading-anchor-0" class="elementor-toc__list-item-text elementor-toc__top-level elementor-item-active">How AP Exams Are Scored</a>
</div>
</li>
<li class="elementor-toc__list-item">
<div class="elementor-toc__list-item-text-wrapper">
<i class=""></i>
<a href="#elementor-toc__heading-anchor-1" class="elementor-toc__list-item-text elementor-toc__top-level">What Are AP Scores Used for?</a>
</div>
</li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-2" class="elementor-toc__list-item-text elementor-toc__top-level">What is Advanced Placement® and Credit?</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-3" class="elementor-toc__list-item-text elementor-toc__top-level">What AP Exam Scores Do Colleges And Universities Accept?</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-4" class="elementor-toc__list-item-text elementor-toc__top-level">AP Exam Score Distribution</a></div></li><li class="elementor-toc__list-item"><div class="elementor-toc__list-item-text-wrapper"><i class=""></i><a href="#elementor-toc__heading-anchor-5" class="elementor-toc__list-item-text elementor-toc__top-level">Frequently Answered Questions (FAQs)</a></div></li></ul>
</div>
Solution 2:[2]
I got it done like this:
window.onload = function(){
console.log("document ready");
function populateMobileTOC() {
jQuery( "#TOC ul li" ).each(function( i, item ) {
jQuery('#mobileTOCselect').append(jQuery('<option>', {
value: jQuery (this).find("a").attr("href"),
text : jQuery( this ).text()
}));
});
jQuery("#mobileTOCselect").change(function() {
var cTarget = jQuery(this).val();
window.location.hash = cTarget;
});
}
checkScreenSize();
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Crystal |
Solution 2 |