PO18 Filter

Hide books in index search results based on specified keywords, authors, and tags.

  1. // ==UserScript==
  2. // @name PO18 Filter
  3. // @description Hide books in index search results based on specified keywords, authors, and tags.
  4. // @version 1.0
  5. // @author null
  6. // @match https://www.po18.tw/findbooks/*
  7. // @grant none
  8. // @license MIT
  9. // @namespace https://greasyfork.org/users/1272411
  10. // ==/UserScript==
  11.  
  12. (function () {
  13. "use strict";
  14.  
  15. const KEYWORDS = [
  16. /标题关键词1/i,
  17. /标题关键词2/i,
  18. /标题关键词3/i,
  19. ];
  20. const AUTHORS = [
  21. /作者关键词1/i,
  22. /作者关键词2/i,
  23. /作者关键词3/i,
  24. ];
  25. const TAGS = [
  26. /标签关键词1/i,
  27. /标签关键词2/i,
  28. /标签关键词3/i,
  29. ];
  30.  
  31. function hideRowsByCriteria() {
  32. const rows = document.querySelectorAll(".row");
  33. rows.forEach((row) => {
  34. const textContent = row.textContent || row.innerText;
  35. const shouldHide =
  36. KEYWORDS.some((keyword) => keyword.test(textContent)) ||
  37. AUTHORS.some((author) => author.test(textContent)) ||
  38. TAGS.some((tag) => tag.test(textContent));
  39.  
  40. if (shouldHide) {
  41. row.style.display = "none";
  42. }
  43. });
  44. }
  45.  
  46. function observeDOMChanges() {
  47. const observer = new MutationObserver((mutations) => {
  48. mutations.forEach((mutation) => {
  49. if (mutation.addedNodes.length || mutation.removedNodes.length) {
  50. hideRowsByCriteria();
  51. }
  52. });
  53. });
  54.  
  55. const config = { childList: true, subtree: true };
  56. const targetNode = document.querySelector("body");
  57. if (targetNode) {
  58. observer.observe(targetNode, config);
  59. } else {
  60. console.error("Failed to find the target node.");
  61. }
  62. }
  63.  
  64. window.addEventListener("load", () => {
  65. hideRowsByCriteria();
  66. observeDOMChanges();
  67. });
  68. })();