Skip to content

Instantly share code, notes, and snippets.

@alexiglesias93
Last active July 16, 2021 09:04
Show Gist options
  • Save alexiglesias93/9d1f01ed045f0fd761047c7981a0c1e8 to your computer and use it in GitHub Desktop.
Save alexiglesias93/9d1f01ed045f0fd761047c7981a0c1e8 to your computer and use it in GitHub Desktop.
Simplified loadMore
/**
* Init
*/
document.addEventListener('DOMContentLoaded', () => loadMore({ collectionSelector: '#blog-posts' }));
/**
* Loads all the paginated items from a collection.
* @param params.collectionSelector The selector of the collection.
* @param params.targetSelector The selector of the target where all items will be appended.
*/
const loadMore = async ({ collectionSelector }: { collectionSelector: string }) => {
const totalCollectionItems: HTMLDivElement[] = [];
const domParser = new DOMParser();
/**
* Loads the items from the next page.
* @param nextButton
*/
const loadNextPageItems = async (nextButton: HTMLAnchorElement) => {
const response = await fetch(nextButton.href);
const rawPage = await response.text();
const page = domParser.parseFromString(rawPage, 'text/html');
collectItems(page);
};
/**
* Collects the items from the loaded page.
* @param page
*/
const collectItems = async (page: Document = document) => {
const collectionListWrapper = getCollectionElement(collectionSelector, 'wrapper', page);
if (!collectionListWrapper) return;
const collectionItems = collectionListWrapper.querySelectorAll<HTMLDivElement>('.w-dyn-item');
collectionItems.forEach((collectionItem) => totalCollectionItems.push(collectionItem));
const nextButton = collectionListWrapper.querySelector<HTMLAnchorElement>('.w-pagination-next');
if (nextButton) await loadNextPageItems(nextButton);
};
/**
* Appends the items to the target.
*/
const populateItems = () => {
const collectionList = getCollectionElement(collectionSelector, 'list');
if (!collectionList) return;
totalCollectionItems.forEach((collectionItem) => collectionList.appendChild(collectionItem));
const paginationWrapper = document.querySelector<HTMLDivElement>('.w-pagination-wrapper');
if (paginationWrapper) paginationWrapper.remove();
};
/**
* Init
*/
await collectItems();
populateItems();
};
/**
* This helper is intended to allow users setting the selector to either the Collection List Wrapper or the Collection List elements.
* This way there will never be any misunderstanding about the setup.
* @param selector The selector of the element.
* @param element The requested element.
* @param page The page document.
* @returns The specified collection element.
*/
const getCollectionElement = (selector: string, element: 'wrapper' | 'list', page: Document = document) => {
const collectionElement = page.querySelector<HTMLDivElement>(selector);
if (!collectionElement) return;
if (element === 'wrapper') return collectionElement.closest<HTMLDivElement>('.w-dyn-list');
return (
collectionElement.querySelector<HTMLDivElement>('.w-dyn-items') ||
collectionElement.closest<HTMLDivElement>('.w-dyn-items')
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment