Add table of content based on H2 tag in html content.
<div class="toc" style="position: fixed; top: 0; right:0">
<h2>Table of conetent</h2>
<?php
/// get html from a field.
$content = get_field( 'the_content' );
preg_match_all( '@<h2.*?>(.*?)<\/h2>@', $content, $matches );
$index=0;
?>
<ul class="table-toc">
<?php foreach ($matches[1] as $match) : ?>
<li> ‐
<a href="javascript:void(0);" class="guide-heading-link" data-index="<?php echo $index; ?>" >
<?php echo $match;?>
</a>
</li>
<?php $index++; endforeach; ?>
</ul>
</div>
// jquery code
<script type="text/javascript">
jQuery(document).ready(function(){
var elements = jQuery("#single_content h2");
jQuery('.guide-heading-link').click(function(){
var index = jQuery(this).attr('data-index');
jQuery('html, body').animate({
scrollTop: jQuery(elements[index]).offset().top-jQuery("#wp-megamenu-additional-menu").height()
}, 2000);
jQuery(this).parent().addClass('active').siblings().removeClass('active');
return false;
});
/* code to auto scroll table of content */
var active_index=0;
var scrol_amt=0;
var myContainer = jQuery('ul.table-toc');
var final_diff=jQuery(document).height();
var passed_up_index=-1;
const callbackOnScroll = ( ) => {
var elem_position=[];
var elements = jQuery("#single_content h2");
elements.each(function(index){
elem_position.push(jQuery(this).offset().top);
if( (jQuery(this).isOnTop()) ){
passed_up_index=index;
}
});
var window_scroll_amt = jQuery(window).scrollTop()+jQuery("#wp-sticky-menu").height()+20;
var new_active_index=-1;
for (var i = 0; i < elem_position.length; i++) {
if( (window_scroll_amt>=elem_position[i] )&& (window_scroll_amt<elem_position[i+1]) ){
new_active_index=i;
}else if(window_scroll_amt>elem_position[i]){
new_active_index=i;
}
}
if(new_active_index!=-1){
link_element = jQuery("ul.table-toc > li").find(`[data-index='${new_active_index}']`);
link_element.parent().addClass('active').siblings().removeClass('active');
passed_up_index=new_active_index;
}else if(new_active_index==-1){
link_element = jQuery("ul.table-toc > li").find(`[data-index='0']`);
link_element.parent().addClass('active').siblings().removeClass('active');
passed_up_index=0;
}
/// last element passed the threesold
li_elem = jQuery("ul.table-toc > li");
var link_position=[];
li_elem.each(function(index){
link_position.push( jQuery(this).offset().top );
if(jQuery(this).hasClass('active')){
if( (jQuery(this).position().top>jQuery("ul.table-toc").height())||(jQuery(this).position().top<50) ){
if(active_index != index){
//scroll up
if(active_index>index){
console.log("scroll up");
scrol_amt = scrol_amt+jQuery(this).position().top-jQuery("ul.table-toc").height();
}
///scroll down
if(active_index<index){
console.log("scroll down");
scrol_amt = scrol_amt+jQuery(this).position().top-jQuery("ul.table-toc").height();
}
active_index = index;
myContainer.animate({
scrollTop: scrol_amt
});
}
}
}
}); /// end of li each loop
}
var t = false;
jQuery(window).scroll(function(event){
clearTimeout(t);
t = setTimeout(callbackOnScroll, 500);
}); // end of scroll
}); /// end of document ready
jQuery.fn.isOnTop = function(){
var istop = jQuery(this).offset().top - jQuery(window).scrollTop();
var menuHeight = jQuery("#wp-sticky-menu").height();
if( (istop<=menuHeight+20)&&(istop>=-10)){
return true;
}else{
return false;
}
}
</script>