pagination-manager

infinite scroll

  1. // ==UserScript==
  2. // @name pagination-manager
  3. // @description infinite scroll
  4. // @namespace Violentmonkey Scripts
  5. // @author smartacephale
  6. // @license MIT
  7. // @version 1.42
  8. // @match *://*/*
  9. // @grant unsafeWindow
  10. // ==/UserScript==
  11.  
  12. class PaginationManager {
  13. /**
  14. * @param {Vue.reactive} state
  15. * @param {Vue.reactive} stateLocale
  16. * @param {Rules} rules - WEBSITE_RULES class with methods:
  17. * - URL_DATA { iteratable_url, offset },
  18. * - PAGINATION_LAST
  19. * @param {Function} handleHtmlCallback
  20. * @param {number} delay - milliseconds
  21. * @param {Function} [alternativeGenerator] - Optional custom generator function
  22. */
  23. constructor(state, stateLocale, rules, handleHtmlCallback, delay, alternativeGenerator) {
  24. const { offset, iteratable_url } = rules.URL_DATA();
  25. Object.assign(this, { state, stateLocale, rules, handleHtmlCallback, delay });
  26. Object.assign(this.stateLocale, { pagIndexLast: rules.PAGINATION_LAST, pagIndexCur: offset });
  27.  
  28. this.paginationGenerator = alternativeGenerator?.() ??
  29. PaginationManager.createPaginationGenerator(offset, rules.PAGINATION_LAST, iteratable_url);
  30.  
  31. this.createPaginationObserver();
  32. }
  33.  
  34. createPaginationObserver() {
  35. const observable = this.rules.INTERSECTION_OBSERVABLE || this.rules.PAGINATION;
  36. unsafeWindow.bhutils.Observer.observeWhile(observable, this.generatorConsumer, this.delay);
  37. }
  38.  
  39. generatorConsumer = async () => {
  40. if (!this.state.infiniteScrollEnabled) return;
  41. const { value: { url, offset } = {}, done } = await this.paginationGenerator.next();
  42. if (!done) {
  43. console.log(url);
  44. const nextPageHTML = await unsafeWindow.bhutils.fetchHtml(url);
  45. const prevScrollPos = document.documentElement.scrollTop;
  46. this.handleHtmlCallback(nextPageHTML);
  47. this.stateLocale.pagIndexCur = offset;
  48. window.scrollTo(0, prevScrollPos);
  49. }
  50. return !done;
  51. }
  52.  
  53. static * createPaginationGenerator(currentPage, totalPages, generateURL) {
  54. for (let p = currentPage + 1; p <= totalPages; p++) {
  55. const url = generateURL(p);
  56. yield { url, offset: p };
  57. }
  58. }
  59. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址