'How to make fixed header availabel at the focus an focusable element?

I have a fixed header, when user scroll to an offset 100px, a class add to header to make it fixed:

fixed-header {
    position: fixed:
    top: 0,
    left: 0,
    right: 0,
    width: 100%;
}
$( window ).on( 'scroll', function() {
    if ( $( window ).scrollTop() >= 100 ) {
      navigation.classList.add('.fixed-header');
      document.body.style.paddingTop = "100px" // prevent page jump when fixed header
    } else {
      navigation.classList.remove('.fixed-header');
      document.body.style.paddingTop = "0"
    }
});

On top of page, when user focus a link via tab key, I use focus event listener to check the fixed class in DOM to scroll focusable element to re-position it below fixed header:

const elements = [...document.querySelectorAll(
    "a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled])"
)];

header = document.body.querySelector('.header-top');  // Fixed header height: 100px

const handleFocus = (e) => {
    console.log(header.classList.contains('.fixed-header')); // This will false

    if (header.classList.contains('.fixed-header')) {
        var windowScrollTop = $( window ).scrollTop(),
        focusableScrollTop = $(e.target).offset().top;

        if (focusableScrollTop - windowScrollTop < 100) {
            window.scrollTo({ top: focusableScrollTop - 100, behavior: 'smooth' });
        }
    }
};

for (const element of elements) {
    element.addEventListener('focus', handleFocus, { once: true });
}

But focus callback handler fire before DOM repaint (when fixed class added to header), so it can not detect fixed class in DOM:

enter image description here

Wrap focus handler inside requestAnimationFrame()', don't work, if I wrap focus handler inside setTimeout()' function with 300ms, it will detect correct fixed class, but cause page scroll jump (focusable element scroll up and down).

for (const element of elements) {
    element.addEventListener('focus', setTimeout(() => {
        handleFocus()
    }, 300), { once: true });
}

Any way to make header.classList.contains('.fixed-header') come true at the focusable link focused?

I hope someone know this issue and help to fix this problem. Thank you very much.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source