Search code examples
infinite-scrollhugo

how to connect infinite scrolling to a page on hugo?


there is a code that pulls up content from md files

{{ define "main" }}

<div class="responsive-margins xl:pt-32 " x-data="{
  data: {},
  filterApplied: false,
  selectedStudy(id) {
    let selected = false;

    if (!this.data.studies) {
      return false;
    }

    this.data.studies[id].forEach(category => {
      if (!! this.data.categories[category].selected) {
        selected = true;
      }
    });

    return selected;
  },
  selectedCategoryType(category) {
    if (!this.data.categories || !this.data.categories[category]) {
      return '';
    }
    return this.data.categories[category].selected;
  },
  toggleCategory(category) {
    console.log(this.data);
    this.data.categories[category].selected = !this.data.categories[category].selected;

    let isFiltered = false;      
    for (let c in this.data.categories) {
      if (this.data.categories[c].selected) {
        isFiltered = true;
        break;
      }
    }

    this.filterApplied = isFiltered;
  },
  clearAll() {
    this.filterApplied = false;
    for (let category in this.data.categories) {
      this.data.categories[category].selected = false;
    }
  },
}"
  x-init="data = (await (await fetch('./index.json')).json())">

    <p class="text-header-1-mobile xl:text-header-1 font-bold pt-24 pb-8">Newsroom 
        <span class="text-base-mobile xl:text-header-5 font-normal ml-4"><a class="underline" href="mailto:">Contact us for media enquiries</a>
        </span>      
    </p>
    
    <div class="pb-20">
      <div class="flex flex-wrap gap-1 xl:gap-2 responsive-margins mb-5">
        <span class="mr-5 text-base cursor-pointer" :class="!filterApplied ? 'border-2 bg-dark text-white py-2 px-5 rounded-full' : 'border-2 py-2 px-5 rounded-full'" @click="clearAll()">All</span>
        {{ range $taxonomyname, $taxonomy := .Site.Taxonomies }}
          {{ with $.Site.GetPage (printf "/%s" $taxonomyname) }}
            {{ if eq $taxonomyname "categories" }}
              {{ range $key, $value := $taxonomy }}
                <div
                class="mr-5 cursor-pointer"
                @click="toggleCategory('{{.Page.Title}}')" 
                :class="selectedCategoryType('{{.Page.Title}}') == true ? 'border-2 bg-dark text-white py-2 px-3 rounded-full' : 'border-2 py-2 px-3 rounded-full'" 
                >{{.Page.Title}}</div>
              {{ end }}
            {{ end }}
          {{ end }}
        {{ end }}
      </div>
    </div>

    <div id="wrapper" class="infinite-scroll">
    {{ range first 5 .Pages }}
      <div class="my-item content xl:grid xl:grid-cols-2 gap-20 pb-40" x-show="!filterApplied || selectedStudy('{{ .File.UniqueID }}')">
        <div>
          <a class="cursor-pointer" 
          href="{{ .Params.link }}">  
            <img class="w-full h-auto" src="{{ .Params.preview | absURL }}" alt="">
          </a>
        </div>
        <div>
          <a class="cursor-pointer" 
          href="{{ .Params.link }}">  
            <div class="flex flex-col gap-4">
              <div class="green-bar hidden xl:block"></div>
              <h4 class="text-header-2-mobile xl:text-header-2 font-bold pt-8">{{ .Params.name }}</h4>
              <p class="text-base-mobile xl:text-header-5">{{ .Params.description }}</p>
              <div class="text-base-mobile xl:text-blog-metadata pt-8 flex">
                <p class="xl:pt-0 pt-1.5">{{ .Params.author }} | <span class="ml-1">{{- .Date.Format "Jan 2, 2006" -}}</span> </p>
              </div>
            </div>
          </a>
        </div>
      </div>
 
    {{ end }}


  </div>
{{ end }}

at the moment it outputs the first five posts of all, but I can't figure out how to enable infinite scrolling when the user has reached the end of the page

I tried to connect via plugins, but they request additional parameters in the form of the address of the next page to be loaded. But there is no address, since the content is a continuous stream

please help me, I've been struggling with this for a very long time


Solution

  • this is not a completely correct infinite scroll, but it works I added this script

    var posts = document.querySelectorAll('[id=post]');
    var endOfContent = document.getElementById('endOfContent');
    var t = 9
    
    // Display first 10 posts
    for(let i = 0; i <= t; i++) {
      posts[i].classList.remove('hidden');
    } 
    
    window.addEventListener('scroll', (event) => {    
      // Print next 6 posts after reaching the end 
      if (endOfContent.offsetTop * 0.8 <= window.scrollY) {
        for(let i = t + 1; i <= t + 6; i++) {
          posts[i].classList.remove('hidden');
        }
        t = t + 6;
      }
    });
    

    and wrapped the content necessary for scrolling in a separate div and added a counter to the daughter div and added a block with id=“endOfContent”

    {{ range $index, $element := .Pages }}
    <div class="hidden" id="post">
      <div data-page="{{ $index }}">  scroll content  </div>
    </div>
    {{ end }}
    <div id="endOfContent"></div>