I have made a "Table of contents menu" on my Drupal 9 website. Here a link to a page with the menu. I use the "Paragraphs module" to add headers to my content and use views to display these as anchor links in a block. I use JavaScript to create some extra space, so the menu block doesn't overlap with the headers after clicking the anchor link. Furthermore, I use JavaScript to make the menu (details element) close when clicking outside the menu. I cannot write JavaScript and use pieces of code that I found online.

I would also like the menu (details element) to close after clicking the anchor link.

Here the HTML of the menu:

<details class="views-element-container settings-tray-editable block block-views block-views-blocktoc-toc" id="block-views-block-toc-toc-3" data-drupal-settingstray="editable" data-once="details">
  <summary class="block__title">Table of content<span class="summary"></span></summary>
  <div class="block__content">
  <div><div class="toc view view-toc view-id-toc view-display-id-toc js-view-dom-id-f3863ecde8c5164c6465d301061ed61af898565766b8b54c284fef42b4d9fd92">
  <div class="view-content">
<div class="toc__item-container odd">
    <div class="toc__h2-wrapper">
      <a class="toc__h2" href="#426">Things to do in Phrae</a>
<div class="toc__item-container even">
    <div class="bullet-point">
      <a class="toc__h3" href="#427">Drive the Small and Large Phrae Loop on a motorcycle</a>

<!-- more menu items follow -->

And here the JavaScript I use (I add the JS in my theme):

Drupal.behaviors.smoothScroll = {
  attach: function (context, settings) {
    // Your custom JavaScript goes inside this function...
    // This JS prefents overlap off the menu over the titles/anchor links by putting
    // the content lower by the height of the menu (#block-views-block-toc-toc-3) + 36px
    // https://www.youtube.com/watch?v=iGUSTyG-CYw
    const navigationHeight = document.querySelector('#block-views-block-toc-toc-3').offsetHeight;

    document.documentElement.style.setProperty('--scroll-padding', navigationHeight + 36 + "px");

    // When clicking outside menu. Close menu.
    var details = [...document.querySelectorAll('details')];
      document.addEventListener('click', function(e) {
        if (!details.some(f => f.contains(e.target))) {
          details.forEach(f => f.removeAttribute('open'));
        } else {
          details.forEach(f => !f.contains(e.target) ? f.removeAttribute('open') : '');

Thanks for the help!



Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.