0

A lot of websites have the concept of pagination. I'd like to be able to go to the next/previous page by hitting the right/left key, respectively. I've figured this out for one site, but it's kind of inconvenient to write a general purpose solution to this problem when every site has a different html structure.

// ==UserScript==
// @name         Previous/Next button keyboard shortcuts
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://example.com/*
// @grant        none
// @run-at document-idle
// ==/UserScript==

(($) => {
    if ($('.page-numbers').length) {
        $("body").keydown(function(e) {
            console.log(e.which)
            // left arrow
            if ((e.keyCode || e.which) == 37)
            {
                document.querySelector(".pagination.prev").click();
            }
            // right arrow
            if ((e.keyCode || e.which) == 39)
            {
                document.querySelector(".pagination.next").click();
            }
        });

    }
})($);

$.noConflict();

What I usually do is copy/paste this into a new script, modify the @match, and then modify the body of the if statements. This is a huge DRY violation. I could click on a link with the text, "Next"/"Prev" to make things general purpose, but some sites may use "Previous" instead of "Prev", "Back", etc.

I suppose, alternatively, I could make this script match every site, and only do something if the address bar matches a subset of sites in a map of <SiteName, {leftSelector: string; rightSelector: string;}>.

What's the idiomatic way of solving this problem in a UserScript?

I am using tampermonkey on Firefox.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
  • Would it not be easier to just: 1) get all url search params 2) if there is exactly one value that is a positive integer, then increase it. 3) navigate to the next url constructed by the new query params. No DOM involved. but sadly it would not be working for the starting url. – Endless Dec 13 '22 at 00:57
  • @Endless some sites (I know this is a bad practice) don't put the page in the url. – Daniel Kaplan Dec 13 '22 at 04:54

1 Answers1

0

I'm not sure if this is a good solution, but it is a solution: https://github.com/greasemonkey/greasemonkey/issues/2446#issuecomment-259580642

// ==UserScript==
// @name        Test call 1
// @namespace   https://github.com/tiansh/
// @include     http://example.com/
// @version     1
// @grant       unsafeWindow
// ==/UserScript==

unsafeWindow.x = function (str, callback) {
  console.log('%o.x: %o', this, arguments);
  alert('x says: ' + str);
  callback(str + 'from x');
};
// ==UserScript==
// @name        Test call 2
// @namespace   https://github.com/tiansh/
// @include     http://example.com/
// @version     1
// @grant       unsafeWindow
// ==/UserScript==

setTimeout(function () {

unsafeWindow.x('hello', function (nstr) {
  console.log('%o.y: %o', this, arguments);
  alert('y says: ' + nstr);
});

}, 0);

So long as the @include/@matches are in sync, this is a way to share code between scripts. The first script defines a function in unsafeWindow. The other scripts call it.

This'll allow you to reuse code from one script in another.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356