Greasy Fork is available in English.

Diskusie » Vývoj

Scrolling page by class?

§
Pridaný: 29.08.2018

Scrolling page by class?

Let's say we have this Reuters' webpage. And the headlines there have this class, FeedItemHeadline_headline.

Now, is it possible somehow to make a userscript for navigation from headline to headline? Like, a user presses j, and the next headline is scrolled up to the top of the window, may be? Or highlighted?

Have you seen any examples like this, may be?

Thanks!

woxxomZablokovaný
§
Pridaný: 29.08.2018
// ==UserScript==
// @name          J/K between H2
// @match         https://www.reuters.com/*
// ==/UserScript==

addEventListener('keypress', e => {
  if (e.ctrlKey ||
      e.altKey ||
      e.metaKey ||
      e.shiftKey ||
      (e.key !== 'k' && e.key !== 'j')) {
    return;
  }
  e.preventDefault();

  const MARGIN_TOP = 50;

  const direction = e.key === 'j' ? 1 : -1;
  const elements = Array.from(document.getElementsByTagName('h2'));
  const len = elements.length;

  const offsets = new Array(len).fill(0);
  const getOffset = i => offsets[i] || ((offsets[i] = elements[i].getBoundingClientRect().top));

  let a = 0, b = len - 1;
  while (a < b - 1) {
    const c = (a + b) / 2 | 0;
    if (getOffset(c) < 0) {
      a = c;
    } else {
      b = c;
    }
  }

  while (a < len && getOffset(a) < direction) {
    a++;
  }
  a = Math.max(0, Math.min(a + direction, len));
  scrollTo({
    top: scrollY + getOffset(a) - MARGIN_TOP,
    behavior: 'smooth',
  });
});
§
Pridaný: 29.08.2018

Wow, thanks a lot, @wOxxOm!

For some strange reason, the script seems like not working for me in Chrome with Tampermonkey or Violentmonkey but it does work perfectly in Firefox with Greasemonkey (both browsers are rather old, though). Even tried it in Incognito window with Tampermonkey being the only extension enabled - and with no success, too :(

By any chance, do you know what can be the reason?

And sure thanks again for the script!

§
Pridaný: 29.08.2018

I'm not a programmer so may be I'll be saying something stupid :) but this test code

scrollTo({top: 50, behavior: 'smooth'});

works nicely in Firefox but fails in my Chrome with this errror:

VM602:2 Uncaught TypeError: Failed to execute 'scrollTo' on 'Window': 2 arguments required, but only 1 present.
    at TypeError (native)
    at <anonymous>:2:1
    at Object.InjectedScript._evaluateOn (<anonymous>:878:140)
    at Object.InjectedScript._evaluateAndWrap (<anonymous>:811:34)
    at Object.InjectedScript.evaluate (<anonymous>:667:21)
§
Pridaný: 29.08.2018
Upravený: 29.08.2018

And something seems to be wrong with the addEventListener itself :(.

§
Pridaný: 29.08.2018
Upravený: 29.08.2018

It seems like it doesn't recognize the keys for some reason (again, in Firefox everything works fine).

This code:

addEventListener('keypress', e => {
    if (e.ctrlKey ||
        e.altKey ||
        e.metaKey ||
        e.shiftKey ||
        (e.key !== 'k' && e.key !== 'j')) {
        alert("NO");
        return;
    }

    alert("YES");

});

triggers "NO" no matter what key I press, be it Space, j, k or, let's say,l.

woxxomZablokovaný
§
Pridaný: 29.08.2018
Upravený: 29.08.2018

I see now that you're using an ancient version of Chrome so you should expect all kinds of problems. It's possible to tweak the script so it'll work there but you could have said you're using a dinosaur fossil browser beforehand...

§
Pridaný: 29.08.2018
Upravený: 29.08.2018

@wOxxOm Sorry :) I could never thought some basic JS wasn't supported by Chrome back then...

So, yes, it was was my old Chrome's fault: https://stackoverflow.com/questions/52072024/addeventlistener-not-handling-keys-right-in-old-chrome-version

woxxomZablokovaný
§
Pridaný: 29.08.2018

Here's a version for ancient browsers:

// ==UserScript==
// @name          J/K between H2
// @match         https://www.reuters.com/*
// ==/UserScript==

addEventListener('keyup', function(e) {
  if (e.ctrlKey ||
      e.altKey ||
      e.metaKey ||
      e.shiftKey ||
      (e.which !== 74 /*j*/ && e.which !== 75 /*k*/)) {
    return;
  }
  e.preventDefault();

  var MARGIN_TOP = 50;

  var direction = e.which === 74 ? 1 : -1;
  var elements = document.getElementsByTagName('h2');
  var len = elements.length;

  var offsets = [];
  var getOffset = function (i) {
    return offsets[i] || ((offsets[i] = elements[i].getBoundingClientRect().top));
  };

  var a = 0, b = len - 1;
  while (a < b - 1) {
    var c = (a + b) / 2 | 0;
    if (getOffset(c) < 0) {
      a = c;
    } else {
      b = c;
    }
  }

  while (a < len && getOffset(a) < direction) {
    a++;
  }
  a = Math.max(0, Math.min(a + direction, len));
  (function () {
    try {
      scrollTo({
        top: scrollY + getOffset(a) - MARGIN_TOP,
        behavior: 'smooth',
      });
    } catch (_) {
      scrollTo(scrollX, scrollY + getOffset(a) - MARGIN_TOP);
    }
  })();
});
§
Pridaný: 29.08.2018
Upravený: 29.08.2018

Brilliant, @wOxxOm , love you :)

Pridať odpoveď

Aby ste mohli pridať odpoveď, prihláste sa.