Skip to content

fixes to glossary scrolling #30648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 52 additions & 4 deletions assets/scripts/components/instantsearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,56 @@ import { searchpageHits } from './instantsearch/searchpageHits';
import { customPagination } from './instantsearch/customPagination';
import { debounce } from '../utils/debounce';

// Helper function to handle navigation with proper anchor scrolling
function navigateToUrl(url) {
const urlObj = new URL(url, window.location.origin);

// Check if we're navigating to the same page
if (window.location.pathname === urlObj.pathname) {
window.history.pushState({}, '', url);

// Close search dropdown since we're staying on the same page
const hitsContainerContainer = document.querySelector('.hits-container');
if (hitsContainerContainer) {
hitsContainerContainer.classList.add('d-none');
}

// If there's an anchor, scroll to it
if (urlObj.hash) {
setTimeout(() => {
const targetElement = document.getElementById(urlObj.hash.substring(1));
if (targetElement) {
// Calculate offset from fixed header and any page-specific nav
const header = document.querySelector('.navbar');
const glossaryNav = document.querySelector('.glossary-nav');
let offset = 20; // Base padding

if (header) offset += header.offsetHeight;
if (glossaryNav) offset += glossaryNav.offsetHeight;

const elementTop = targetElement.getBoundingClientRect().top + window.pageYOffset;
window.scrollTo({
top: elementTop - offset,
behavior: 'smooth'
});
}
}, 50);
}
return;
}

// Check if this is a glossary page with an anchor for cross-page navigation
if (urlObj.pathname.includes('/glossary/') && urlObj.hash) {
// For cross-page navigation, store the anchor in sessionStorage and navigate
sessionStorage.setItem('glossaryScrollTarget', urlObj.hash.substring(1));
window.location.href = url;
} else {
// For other cross-page navigation, use normal navigation
window.history.pushState({}, '', url);
window.location.reload();
}
}

const { env } = document.documentElement.dataset;
const pageLanguage = getPageLanguage();
const typesenseConfig = getConfig(env).typesense;
Expand Down Expand Up @@ -294,8 +344,7 @@ function loadInstantSearch(currentPageWasAsyncLoaded) {

if (target && target.href && targetIsDescendant) {
sendSearchRumAction(search.helper.state.query, target.href);
window.history.pushState({}, '', target.href);
window.location.reload();
navigateToUrl(target.href);
}

target = target.parentNode;
Expand All @@ -319,12 +368,11 @@ function loadInstantSearch(currentPageWasAsyncLoaded) {
const page = search.helper.state.page;
const clickPosition = getSearchResultClickPosition(target.href, hitsArray, numHits, page);
sendSearchRumAction(search.helper.state.query, target.href, clickPosition);
window.history.pushState({}, '', target.href);

if (e.metaKey || e.ctrlKey) {
window.open(target.href, '_blank');
} else {
window.location.reload();
navigateToUrl(target.href);
}
}

Expand Down
49 changes: 49 additions & 0 deletions assets/scripts/datadog-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,55 @@ window.addEventListener('click', (event) => {
window.onload = function () {
getPathElement();
setMobileNav();

// Handle glossary anchor scrolling from search results
if (window.location.pathname.includes('/glossary/')) {
const scrollTarget = sessionStorage.getItem('glossaryScrollTarget');
if (scrollTarget) {
sessionStorage.removeItem('glossaryScrollTarget');
// Use requestAnimationFrame to ensure DOM is fully rendered
requestAnimationFrame(() => {
setTimeout(() => {
const targetElement = document.getElementById(scrollTarget);
if (targetElement) {
const header = document.querySelector('.navbar');
const glossaryNav = document.querySelector('.glossary-nav');
let offset = 20;

if (header) offset += header.offsetHeight;
if (glossaryNav) offset += glossaryNav.offsetHeight;

const elementTop = targetElement.getBoundingClientRect().top + window.pageYOffset;
window.scrollTo({
top: elementTop - offset,
behavior: 'smooth'
});
}
}, 300); // Longer delay for Chrome's rendering
});
} else if (window.location.hash) {
// Handle direct hash navigation with Chrome-compatible timing
requestAnimationFrame(() => {
setTimeout(() => {
const targetElement = document.getElementById(window.location.hash.substring(1));
if (targetElement) {
const header = document.querySelector('.navbar');
const glossaryNav = document.querySelector('.glossary-nav');
let offset = 20;

if (header) offset += header.offsetHeight;
if (glossaryNav) offset += glossaryNav.offsetHeight;

const elementTop = targetElement.getBoundingClientRect().top + window.pageYOffset;
window.scrollTo({
top: elementTop - offset,
behavior: 'smooth'
});
}
}, 300);
});
}
}
};

function replaceURL(inputUrl) {
Expand Down
Loading