Find first scrollable parent

Viewed 52202

I have this situation in which I need to scroll an element into the viewport. The problem is that I don't know which element is scrollable. For example, in Portrait the body is scrollable and in Landscape its an other element (and there are more situation which change the scrollable element)

Now the question, given an element which needs to be scrolled into the viewport, what is the best way to find its first scrollable parent ?

I've setup a demo here. With the button you can toggle between two different situations

<div class="outer">
    <div class="inner">
        <div class="content"> 
            ...
            <span>Scroll me into view</span>
        </div>
    </div>
</div>

The body is scrollable or .outer

Any suggestions ?

9 Answers

Using google chrome dev tools, when you've scrolled partially down the page, inspect the page, select the DOM node that you think might be the one that is being scrolled. Then pull up the console (hit ESC from within the Elements tab of the dev tools) and type $0.scrollTop. This will print out the current scroll position of that element. If it is NOT 0 then you will know that that is the element that is being scrolled.

Building upon further on the @Web_Designer's answer,

If you are passing the jQuery object for that element and are getting the following error,

Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'

Then try passing just the Dom Node element which btw resides at array key 0 if the element is a single element. Eg.

getScrollParent(jQuery("#" + formid)[0])

this is what I have so-far that seems to work across web component custom element shadowRoots; we might expand it further to add a scroll event handler once scrolling starts to unload this handling and track a specific node's scroll event

function scroller(node){ return node.scrollTop }
function handler(event){
        const path = event.composedPath();
        const scrollNode = path.find(scroller);
        const scrollNodes = path.filter(scroller);
        console.warn('scroll!',{scrollNode, scrollNodes});
}
window.addEventListener('mousewheel', handler, {capture: true});
window.addEventListener('keydown', handler, {capture: true});

This is the way to find what you want.

document.addEventListener('scroll', (e) => {
    console.log(e.target.scrollingElement.scrollTop);
})
Related