How to scroll down to an element just after loading the webpage that contains it?

I am trying to develop a web browser user script which will scroll down my viewpoint all the way down to a certain element in a very long webpage, each time I load that webpage.

// ==UserScript==
// @name         Scroll Down to Element
// @match        example.com/my-webpage
// ==/UserScript==

document.querySelector('#edit-actions').scrollIntoView();

This works from console but not from the user script manager; if I run it from the console then the web browser will scroll down to the element but if I load the webpage no such scroll down will occur.

Using only the user script manager, I have also tried to wrap the code in a load event handler to try to load the code after everything else was loaded (HTML, CSS, JavaScript).

// ==UserScript==
// @name         Scroll Down to Element
// @match        example.com/my-webpage
// ==/UserScript==

window.addEventListener('load', () => {
    document.querySelector('#edit-actions').scrollIntoView();
});

This didn’t work too; after loading the webpage, no such scroll down will occur.


How to scroll down to an element just after loading the webpage that contains it?

This did work from the user script manager:

// ==UserScript==
// @name         Scroll Down to Element
// @match        example.com/my-webpage
// ==/UserScript==

window.setTimeout( () => {
    document.querySelector('#layout-builder').scrollIntoView();
}, 1000);

I am probably in one of these strange scenarios were the load event isn’t counted but one second timeout is counted.
How will you explain this?

Hi @bendqh1, the element in question might not be the from the start but get created programmatically with JS, in which case a load event listener won’t (neccessarily) help. You can have a look at the page source to check.

PS: Another possibility would be that your user script is getting executed only after the load event already got fired. Does

window.addEventListener('load', console.log)

log anything?

1 Like

Hello there :slight_smile:

I have checked the webpage’s HTML source and indeed the CSS ID #edit-actions isn’t there so it get’s created automatically, but shouldn’t load event cover that as well (cover all non-timed-out script assets as well)?

I do want my script to be executed after the load event is fired.

window.addEventListener('load', console.log)

undefined

Well not necessarily; the element might get created asynchronously, or the script might get loaded asynchronously itself.

That would be the output of executing the line in the console, I meant you should add it to your user script.

1 Like

Oh, I confused with console.log().

Well, after adding this to the script and fully reloading the webpage with the console on, I got:

Event {isTrusted: true, type: ‘load’, target: document, currentTarget: Window, eventPhase: 2, …}

Okay then this is not the issue, the element is indeed getting created asynchronously. This might also be inside another load event listener, which is just getting added after yours; in this case, waiting one tick might be enough:

window.addEventListener('load', () => setTimeout(() => {
  document.querySelector('#edit-actions').scrollIntoView()
}))
1 Like

That’s the first time I find a setTimeout without declaring the time, like 1 for one millisecond, which is the best minimum at least cognitivally for myself :slight_smile:

Yeah it just schedules the function execution to the end of the current task queue… so here “a” would get logged after “b”, but without further delay:

setTimeout(() => {
  console.log('a')
})

console.log('b')

Check out the above link for details, or this visual explanation. :-)

2 Likes

That’s neat and great :+1:

Thanks a lot.

1 Like

@m3g4p0p please just one more thing.

The first anonymous procedure doesn’t have {} here:

window.addEventListener('load', () => setTimeout(() => {
  document.querySelector('#edit-actions').scrollIntoView()
}))

Is that sugar syntax or is there a logical problem in adding the {} for it?

() => something;

is a shortcut for

() => {
    return something;
}

The something can only be a single statement. If you need multiple statements in your function then you need to use the brackets.

1 Like

If you know the id of the webpage’s desired location
have you not considered just using a # at the end of
the webage’s address to go there?

Here is an example link…

https://webaim.org/articles#popular

1 Like

I guess that you meant a heading textContent, not the CSS ID but I had to select a CSS selector in that case.

No, I am referring to an HTML element’s id
which may be used by CSS.

On the link which I provided this was the
element scrolled to on load…

<h2 id="popular">Popular Resources</h2>

I never navigated to a part of a webpage by a CSS ID.
Some web browsers may allow it but anyway an automation script would indeed require selection with something like document.querySelector().

In your original post you have this…

document.querySelector('#edit-actions').scrollIntoView();

Correct me if I am mistaken but isn’t #edit-actions a reference
to an element’s CSS ID ? :wonky:

My original post deals with selection of an element by CSS ID with JavaScript, not by manually navigating to that element from a URL bar with a CSS ID, if that’s what you meant.

Let’s say, for example that your webpage has an address like this…

https://www.mywebpage.com/mypage.html

…and it contains an HTML element like this…

<div id="edit-actions">some action required</div>

…then this…

https://www.mywebpage.com/mypage.html#edit-actions

…will take you or your visitors directly to it.

4 Likes

for the record, it’s not… a “CSS” ID. It’s an HTML attribute. CSS uses a selector FOR that ID, which mimics the browser’s hash usage (now. It used to require anchor tags and… thats a history lesson for another day). CSS has selectors for many things. Javascript uses the ID too. Doesnt make it a Javascript ID either :wink:

4 Likes