2

I am complete beginner in JavaScript.

At the moment, I am creating a JS snippet for a bookmarklet in Chrome (103.0.5060.114) on Windows 10 Pro. This bookmarklet should open to the bottom of the webpage at an arbitrary URL.

Problems

While my bookmarklet does open the given page, it wrongly remains at the top of the page.

Furthermore, while it opens from any webpage (like https://www.google.com) to which I navigate, it fails to open from a newly created tab. A new tab initially displays my default homepage, which is Google, but the URL (https://www.google.com) is notably absent from its slot:

4

Code

Here are my two custom functions, which figure into the full snippet below.

Function window_scroll_to_bottom()

function window_scroll_to_bottom() {
    // Save the existing scroll settings.
    save_scroll_restoration = history.scrollRestoration;
    
    // Override any autoscroll in Chrome.
    history.scrollRestoration = "manual";
    
    // Scroll to the bottom of the current page, per https://stackoverflow.com/a/29971996.
    window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
    
    // Restore scroll settings.
    history.scrollRestoration = save_scroll_restoration;
}

Function window_open_to_bottom()

function window_open_to_bottom(...args) {
    // Save existing settings on load.
    save_on_load = window.onload;
    
    // Scroll to bottom on load.
    window.onload = window_scroll_to_bottom;
    
    // Open the window, according to the given arguments.
    window.open(...args);
    
    // Restore settings on load.
    window.onload = save_on_load;
}

Full Snippet

Here is my readable .js snippet

javascript:
url = "https://stackoverflow.com/q/73326280";
function window_scroll_to_bottom() {
    save_scroll_restoration = history.scrollRestoration;
    history.scrollRestoration = "manual";
    window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
    history.scrollRestoration = save_scroll_restoration;
};
function window_open_to_bottom(...args) {
    save_on_load = window.onload;
    window.onload = window_scroll_to_bottom;
    window.open(...args);
    window.onload = save_on_load;
};
window_open_to_bottom(url, "_self");

which I condense into a single line

javascript: url = "https://stackoverflow.com/q/73326280"; function window_scroll_to_bottom() {save_scroll_restoration = history.scrollRestoration; history.scrollRestoration = "manual"; window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight); history.scrollRestoration = save_scroll_restoration}; function window_open_to_bottom(...args) {save_on_load = window.onload; window.onload = window_scroll_to_bottom; window.open(...args); window.onload = save_on_load}; window_open_to_bottom(url, "_self");

and then paste into the URL field in Chrome's bookmark editor:

6


Background

My company has some dashboards hosted by a third party ("Dashboard Service"), each of which is located at a unique URL. For example, the 2nd dashboard is found at https://mycompany.dashboardservice.com/Dashboard/Index/2.

These dashboards are large and render their widgets piecemeal, from top to bottom. If one scrolls immediately to the bottommost widget, then everything above it will render too. Otherwise, when one wishes to scroll downward, one must wait for every subsequent widget to render.

This rendering takes forever and bogs down our meetings. Management needs a stopgap solution, while we await a more permanent solution by Dashboard Service.

Goal

I wish to create a bookmark(let) in Chrome that targets the bottom of each dashboard. Left-clicking this bookmark(let) should open it in the current window; but right-clicking it should offer the option of opening in a new tab or window.

7

Challenge

There exists no HTML anchor like id="dashboard-bottom" at the bottom of the page. Worse yet, the widgets (and other regions) are also unanchored by anything like id="widget-5". Finally, there is no universal anchor like #bottom that automatically targets the bottom of any page.

Thus, I cannot simply bookmark the following URLs for (say) the 2nd dashboard which has 5 widgets:

  • The dynamic https://mycompany.dashboardservice.com/Dashboard/Index/2#dashboard-bottom.
  • The static https://mycompany.dashboardservice.com/Dashboard/Index/2#widget-5.
  • The universal https://mycompany.dashboardservice.com/Dashboard/Index/2#bottom.

Idea

In response to the #bottom problem, this suggestion

In my opinion, it's better to implement this in JavaScript and definitely jump to the bottom of the page, instead of relying that the CSS styling on a link makes it always appear at the bottom of the page.

This JavaScript snippet will scroll to the bottom of the document:

document.body.scrollIntoView(false);

led me to this Javascript solution

Below should be the cross browser solution. It has been tested on Chrome, Firefox, Safari and IE11

window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);

which uses window.scrollTo() to scroll to the bottom of the current page. This approach is supplemented by these considerations

Browsers such as Chrome have a built-in preset to remember where you were on the page, after refreshing. Just a window.onload doesn't work because your browser will automatically scroll you back to where you were before refreshing, AFTER you call a line such as:

window.scrollTo(0, document.body.scrollHeight);

That's why we need to add:

history.scrollRestoration = "manual";

before the window.onload to disable that built-in feature first.

for history.scrollRestoration with window.onload:

Code:

<script>
    function scrollToBottom() {
        window.scrollTo(0, document.body.scrollHeight);
    }
    history.scrollRestoration = "manual";
    window.onload = scrollToBottom;
</script>

All this inspired me to investigate bookmarklets, which can function like bookmarks for lay users. If I can use the scrolling solution in tandem with a solution like this

At the moment (Chrome 39) I use this code to open a new tab:

window.open('http://www.stackoverflow.com', '_blank', 'toolbar=yes, location=yes, status=yes, menubar=yes, scrollbars=yes');

which opens the page in the first place, then my goal should be attainable.

Summary

I wish to write a concise snippet (and ideally canonical) that should define a Chrome bookmarklet that

  1. opens in Chrome
  2. just like a normal bookmark (with the option of a new tab or window)
  3. to the webpage at an arbitrary URL
  4. starting from any window or tab (including the "blank" homepage) in Chrome; then
  5. scrolls reliably to the bottom of that page, and
  6. remains at the bottom without "jumping" back to the top; but
  7. permits the user afterward to manually scroll from there.

Browser agnostic solutions are also welcome, so long as they satisfy the other requirements above.


Update

After learning here that window.location.href = ... is preferred to window.open(...), I realized that setting

history.scrollRestoration = save_scroll_restoration;

might actively trigger an event: returning to the position dictated by Chrome's autoscroll.

After removing save_scroll_restoration from window_scroll_to_bottom()

function window_scroll_to_bottom() {
    history.scrollRestoration = "manual";
    window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
}

and replacing window_open() with window.location.href in the .js snippet

javascript: url = "https://stackoverflow.com/q/73326280"; function window_scroll_to_bottom() {history.scrollRestoration = "manual"; window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight)}; window.location.href = url; window_scroll_to_bottom();

I see the webpage open and "flicker" to the bottom before "jumping" back to the top. This seems to show progress, but I still can't get the webpage to "stay" at the bottom.

As before, the webpage will not open from a new tab.

halfer
  • 19,824
  • 17
  • 99
  • 186
Greg
  • 3,054
  • 6
  • 27
  • 1
    Based on the principle that questions need to make sense forever here, I have tried to reorder the sections of it. Plenty of effort has clearly gone into it, but the pieces appear to have come out in a stream-of-consciousness order, and thus updates and additions have been made at the top, pushing the introductory material to the end. This makes it rather confusing for new readers, who have to read it (at best) in reverse order. I wonder if the Background and Goal sections need to be moved up? – halfer Aug 28 '22 at 20:47
  • 1
    If you can add some clarifying edits here, I think that would be generally useful, especially if you are still seeking answers. There is probably too much to wade through in the question. (I removed a reference to the bounty, as that doesn't make much sense once the bounty has gone). – halfer Aug 28 '22 at 20:49
  • 1
    @halfer I'm a bit busy at the moment, but I'll try to get around to it. – Greg Aug 28 '22 at 20:49

1 Answers1

1

If there is any (unique) text at the bottom of the dashboard, you could use Chrome's "link to highlight" feature.

Here is a link that scrolls to the bottom of this StackOverflow question:

https://stackoverflow.com/questions/73326280/chrome-bookmarklet-that-opens-window-and-scrolls-to-bottom#:~:text=Site%20design%20/%20logo-,%C2%A9%202022%20Stack%20Exchange%20Inc,-%3B%20user%20contributions%20licensed

You can create such a link by selecting text on the page, then right-clicking. There is a "Copy Link to Highlight" context menu item.

This is a regular link, so you can bookmark it, as well.

Leftium
  • 16,497
  • 6
  • 64
  • 99
  • Hi Leftium, and thanks for the suggestion! Unfortunately, there is no selectable text on the screen, so I'll have to hack the `:~:text=` parameter by hand. I might create some `function`s along the lines of `function make_uri_to_highlight(uri, highlight) {return uri + "#" + ":~:" + "text=" + encodeURIComponent(highlight);}` and `function open_window_to_highlight(uri, highlight, ...args) {uri_highlight = make_uri_to_highlight(); window.open(uri_highlight, ...args);}`. – Greg Aug 16 '22 at 14:31
  • Then it should be a simple matter of creating a `.js` snippet: `javascript: (() => {url = "https://stackoverflow.com/q/73326280"; last_widget_title = "user contributions licensed under CC BY-SA"; function make_uri_to_highlight(uri, highlight) {...}; function open_window_to_highlight(uri, highlight) {...}; open_window_to_highlight(url, last_widget_title)})()` – Greg Aug 16 '22 at 14:36
  • So anyway, have an upvote! I appreciate this stopgap solution. In the meantime, however, I will keep seeking a fully extensible `.js` solution. The dashboards do not require that widgets be titled, or that those titles be unique; and widgets may be appended to the bottom at a later time. I want this solution to work 100% of the time, so long as the `url` is known. – Greg Aug 16 '22 at 14:38
  • P.S. I have discovered one challenge: when there is a `-` in the text, the `encodeURIComponent()` method fails to properly encode the parametric value. Since `-` is a valid URL character on its own, one must replace it by hand with the escape sequence `%2D`. When authoring the `.js` snippet, one must further escape the `%` in `"%2D"` to successfully perform `.replace(/-/, "%252D")`. It seems that when typing the `.js` code in the bookmarklet field, the `.js` code itself gets encoded as a URL, so the code for escaping the `-` must *itself* be escaped! – Greg Aug 16 '22 at 16:28