Web Design Web Development

Add table of content based on H2 tag

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>

Leave a Reply

Your email address will not be published. Required fields are marked *


CAPTCHA Image
Reload Image