ultrascale-playbook / src /syncHFSpacesURLHash.js
mishig's picture
mishig HF staff
add src files
8f8f7dd
raw
history blame
3 kB
const queryArg = "section";
function syncHFSpacesURLHash(){
// Check for section parameter in URL
const urlParams = new URLSearchParams(window.location.search);
const sectionId = urlParams.get(queryArg);
if (sectionId) {
// Find the element with the specified ID
const targetElement = document.getElementById(sectionId);
// scroll if the element exists
if (targetElement) {
targetElement.scrollIntoView();
history.replaceState(null, null, `#${sectionId}`);
}
}
updateHashBasedOnHashChange();
// Variables to manage throttling
let isScrolling = false;
let lastKnownScrollPosition = 0;
// Add the scroll event listener here
window.addEventListener('scroll', function() {
lastKnownScrollPosition = window.scrollY;
if (!isScrolling) {
window.requestAnimationFrame(function() {
updateHashBasedOnScroll(lastKnownScrollPosition);
isScrolling = false;
});
}
isScrolling = true;
});
// Initial hash update on page load
updateHashBasedOnScroll(window.scrollY);
}
// Function to update the URL hash based on scroll position
function updateHashBasedOnScroll(scrollPosition) {
// Get only heading elements with IDs that we want to track
const elementsWithIds = Array.from(document.querySelectorAll('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]'));
// Skip updating if there are no elements with IDs
if (elementsWithIds.length === 0) return;
// Find the element closest to the top of the viewport
let closestElement = null;
let closestDistance = Infinity;
const viewportMiddle = scrollPosition + window.innerHeight / 2;
// Iterate through all elements with IDs to find the closest one
elementsWithIds.forEach(element => {
const elementTop = element.getBoundingClientRect().top + scrollPosition;
const distance = Math.abs(elementTop - viewportMiddle);
if (distance < closestDistance) {
closestDistance = distance;
closestElement = element;
}
});
// Update the URL hash if we found a closest element
if (closestElement && closestElement.id) {
// Only update if the hash is different to avoid unnecessary history entries
if (window.location.hash !== `#${closestElement.id}`) {
// Update the URL without adding a new history entry
history.replaceState(null, null, `#${closestElement.id}`);
postMessageToHFSpaces(closestElement.id);
}
}
}
function updateHashBasedOnHashChange() {
window.addEventListener('hashchange', () => {
const elementId = window.location.hash.slice(1);
postMessageToHFSpaces(elementId);
});
}
function postMessageToHFSpaces(elementId){
const parentOrigin = "https://huggingface.co";
window.parent.postMessage({ queryString: `${queryArg}=${elementId}` }, parentOrigin);
}
export { syncHFSpacesURLHash };