2

Imagine a page with two side-by-side <div> elements like https://nodejs.org/dist/latest-v12.x/docs/api/.

The <div> on the left navigates between pages. The one on the right has the actual content.

When I press space (spacebar), the browser advances the content of the right-hand <div> by one screenful, reminiscent of the traditional UNIX pager more. (IIRC, this has been fairly standard browser behavior since NCSA Mosaic.)

However, sometimes I want to scroll the column on the left (the "navigation" column). How does the browser decide which column to scroll when space is pressed? The document.activeElement is <body>, an ancestor of both of those column <div> elements. I want to be able to change the focus using a bookmarklet (or extension)—which I will be happy to write myself, but this mechanism seems not to be governed by HTMLElement.focus() in any way that I understand.

1
  • The one on the left in node docs is position:fixed which pins it in the viewport so the right is the only part that scrolls with the window through default behavior as you suggested
    – charlietfl
    Commented Apr 4, 2021 at 0:02

2 Answers 2

2

When pressing the space bar (or arrow keys, pg-down, pg-up, etc...), the browser scrolls the closest scrollable parent of the currently active element. When you open the page, the active element is <html> and that's the element that will be scrolled (if its scrollable) and it the flow content exceeds its height (which, by default, is viewport's height).

If the currently active element is the sidebar or one of its children, pressing space will scroll the sidebar, not the <html> element. You can change the active element through various methods (clicking, pressing tab, programmatically, etc...).

5
  • I'm not really sure I understand exactly, but I can accomplish what I want. (How does scrolling <body> cause its descendant <div> to scroll?) Commented Apr 4, 2021 at 0:18
  • 1
    What do you mean by "cause its descendant <div> to scroll"? Which <div> are you talking about?
    – tao
    Commented Apr 4, 2021 at 0:25
  • When document.activeElement is the <body> and I press space, the content div (div#column1, confusingly, the one on the right) scrolls. If I focus an <a> in the navigation div (div#column2), then press space, then that div scrolls. Commented Apr 4, 2021 at 0:29
  • 1
    #column1 is not what's being scrolled. The scrollbar on the right is <body>s. #column1 is just a div inside normal flow. In this picture the highlighted element is #column1. As you can see, the scrollbar exceeds it. As a side note, #column2 is taken out of normal flow, using position: fixed. It has a sidebar because it has a set height and its own flow content exceeds its set height.
    – tao
    Commented Apr 4, 2021 at 0:34
  • 1
    @Colin, actually, I was wrong. The scrolled element is <html>, not <body>. I'll update the answer. Here's how I tested. I scrolled down and ran: document.querySelector('#column1').scrollTop // => 0, document.querySelector('body').scrollTop // => 0, document.querySelector('html').scrollTop // => 900
    – tao
    Commented Apr 4, 2021 at 0:40
2

use tabIndex attribute for manipulate it with focus()

for xmpl with provided by you page:

document.getElementById("column2").tabIndex = 0;
document.getElementById("column1").tabIndex = 0;
document.addEventListener("keydown",function(){
    if(event.ctrlKey){
        if(document.activeElement.id=="column1")
            document.getElementById("column2").focus();
        else
            document.getElementById("column1").focus();
    }
});

Not the answer you're looking for? Browse other questions tagged or ask your own question.