「Feedly」Less Items

Feedly 分次标记已读

当前为 2022-10-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name 「Feedly」Less Items
  3. // @namespace https://www.wdssmq.com/
  4. // @version 0.2
  5. // @author 沉冰浮水
  6. // @description Feedly 分次标记已读
  7. // @license MIT
  8. // @null ----------------------------
  9. // @contributionURL https://github.com/wdssmq#%E4%BA%8C%E7%BB%B4%E7%A0%81
  10. // @contributionAmount 5.93
  11. // @null ----------------------------
  12. // @link https://github.com/wdssmq/userscript
  13. // @link https://afdian.net/@wdssmq
  14. // @link https://gf.qytechs.cn/zh-CN/users/6865-wdssmq
  15. // @null ----------------------------
  16. // @noframes
  17. // @run-at document-end
  18. // @match https://feedly.com/i/subscription/feed%2Fhttps%3A%2F%2F*
  19. // @match https://feedly.com/i/my
  20. // @match https://feedly.com/i/saved
  21. // @grant none
  22. // ==/UserScript==
  23.  
  24. /* jshint esversion: 6 */
  25. /* eslint-disable */
  26.  
  27. (function () {
  28. 'use strict';
  29.  
  30. const gm_name = "LessItems";
  31.  
  32. const curDate = new Date();
  33.  
  34. // -------------------------------------
  35.  
  36. const _curUrl = () => { return window.location.href };
  37. const _sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
  38.  
  39. // -------------------------------------
  40.  
  41. const _log = (...args) => console.log(`[${gm_name}]\n`, ...args);
  42.  
  43. // -------------------------------------
  44.  
  45. // const $ = window.$ || unsafeWindow.$;
  46. function $n(e) {
  47. return document.querySelector(e);
  48. }
  49. function $na(e) {
  50. return document.querySelectorAll(e);
  51. }
  52.  
  53. // -------------------------------------
  54.  
  55. // 添加内容到指定元素后面
  56. function fnAfter($ne, e) {
  57. const $e = typeof e === "string" ? $n(e) : e;
  58. $e.parentNode.insertBefore($ne, $e.nextSibling);
  59. }
  60.  
  61. const objDataSet = {
  62. getDataSet(el, key, def) {
  63. return el.dataset[key] || def;
  64. },
  65. setDataSet(el, key, val) {
  66. el.dataset[key] = val;
  67. },
  68. };
  69.  
  70. const gob = {
  71. intBlocks: 0,
  72. maxBlocks: 4,
  73. bolStopScroll: false,
  74. curTimeMS: curDate.getTime(),
  75. stopScroll(preCaB = () => { }) {
  76. if (!gob.bolStopScroll) {
  77. preCaB();
  78. gob.bolStopScroll = true;
  79. gob.setDataSet();
  80. }
  81. },
  82. reset() {
  83. gob.intBlocks = 0;
  84. gob.bolStopScroll = false;
  85. },
  86. setDataSet() {
  87. objDataSet.setDataSet($n("#header-title"), "stopScroll", "true");
  88. },
  89. getDataSet() {
  90. return objDataSet.getDataSet($n("#header-title"), "stopScroll", "false");
  91. },
  92. };
  93.  
  94. function fnGetItems($baseEL = "body") {
  95. let $items = $na(".list-entries article");
  96. if ($baseEL !== "body") {
  97. $items = $baseEL.querySelectorAll("article");
  98. }
  99. return $items;
  100. }
  101.  
  102. async function fnAutoScroll($items, $blocks) {
  103. const $h2End = $n(".list-entries > h2");
  104. const $endItem = $items[$items.length - 1];
  105.  
  106. // // 阻止向下滚动
  107. // if (gob.intAutoScroll > 4 && !$h2End) {
  108. // $blocks[$blocks.length - 1].scrollIntoView();
  109. // }
  110.  
  111. if (!gob.bolStopScroll && $h2End) {
  112. $h2End.scrollIntoView();
  113. }
  114. if (gob.intBlocks > gob.maxBlocks || $h2End || !$endItem) {
  115. gob.stopScroll(
  116. () => {
  117. _log("fnAutoScroll", "自动滚动停止");
  118. _log("fnAutoScroll", gob);
  119. },
  120. );
  121. return;
  122. }
  123. // dateset 不存在时,执行
  124. if ($endItem.dataset.scrollIntoView !== "done") {
  125. $endItem.scrollIntoView();
  126. gob.intBlocks = $blocks.length;
  127. $endItem.dataset.scrollIntoView = "done";
  128. }
  129. await _sleep(1000);
  130.  
  131. // // 隐藏最新的四个区块
  132. // if (gob.intBlocks <= gob.maxBlocks && !$h2End) {
  133. // [].forEach.call($blocks, ($e, i) => {
  134. // // 隐藏
  135. // // $e.remove();
  136. // $e.style.display = "none";
  137. // $e.classList.add("hidden");
  138. // });
  139. // }
  140.  
  141. fnLessItems();
  142. }
  143.  
  144. // 构建侧边栏
  145. function fnBuildSideBar($block) {
  146. let $el = $n(".list.list-feed");
  147. if (!$el) {
  148. const $cols = $na(".row > div");
  149. [].forEach.call($cols, ($e, i) => {
  150. // 获取 $e 的类名
  151. $e.className;
  152. const text = $e.innerText;
  153. if (text === "") {
  154. $e.innerHTML = "<div><div class=\"list list-feed\"></div>";
  155. $el = $n(".list.list-feed");
  156. }
  157. });
  158. }
  159. // 设置 fixed 定位
  160. $el.parentNode.style.position = "fixed";
  161. // 获取 $block 类名
  162. const strClassBlock = $block.className.replace("EntryList__chunk", "").trim();
  163. const strClassBtn = "btn-" + strClassBlock;
  164. // _log(strClassBlock, `.${strClassBtn}`);
  165. // _log("fnBuildSideBar", $n(`.${strClassBtn}`));
  166. // 判断是否隐藏
  167. const isHidden = $block.classList.contains("hidden");
  168. if (!isHidden && !$n(`.${strClassBtn}`) && $na(".btn-LessItem").length < 4) {
  169. // 追加元素 a
  170. const $a = document.createElement("a");
  171. $a.href = "javascript:void(0);";
  172. $a.className = strClassBtn;
  173. $a.classList.add("btn-LessItem");
  174. $a.innerHTML = strClassBlock;
  175. $a.style.display = "block";
  176. // 边框和内边距
  177. $a.style.border = "1px solid rgba(0,0,0,0.15)";
  178. $a.style.padding = "3px 10px";
  179. // 圆角和外边距
  180. $a.style.borderRadius = "3px";
  181. $a.style.margin = "3px 0";
  182. // 点击事件
  183. $a.addEventListener("click", function () {
  184. const $items = fnGetItems($block);
  185. const intPer = Math.floor($items.length / 4);
  186. const intClick = parseInt($block.dataset.click) || 0;
  187. const curOffset = intClick * intPer;
  188. // _log({
  189. // intPer,
  190. // intClick,
  191. // curOffset,
  192. // });
  193. $items[curOffset].scrollIntoView();
  194. const $btnList = [];
  195. let strAlert = "";
  196. for (let i = 0; i < intPer; i++) {
  197. const element = $items[i + curOffset];
  198. if (!element) {
  199. continue;
  200. }
  201. element.style.marginBottom = "11px";
  202. element.style.padding = "5px";
  203. const $btn = element.querySelector(
  204. ".EntryMarkAsReadButton",
  205. );
  206. $btnList.push($btn);
  207. const $a = element.querySelector(".content > a");
  208. strAlert += $a.textContent + "\n\n";
  209. }
  210. $block.dataset.click = intClick + 1;
  211. setTimeout(() => {
  212. // 确认对话框
  213. // if (confirm(strAlert)) {
  214. $btnList.forEach(($btn) => {
  215. $btn.click();
  216. });
  217. if (curOffset + intPer >= $items.length) {
  218. $a.style.display = "none";
  219. return;
  220. }
  221. // }
  222. }, 1000);
  223. // alert(strAlert);
  224. // _log("fnBuildSideBar", $items);
  225. // _log("fnBuildSideBar", $btnList);
  226. });
  227. // 添加到 $el 后边
  228. fnAfter($a, $el);
  229. }
  230. }
  231.  
  232. function fnLessItems() {
  233. // 判断页面地址
  234. if (_curUrl().indexOf("subscription/") === -1) {
  235. return;
  236. }
  237. if (gob.bolStopScroll) {
  238. if (gob.getDataSet() == "false") {
  239. gob.reset();
  240. } else {
  241. return;
  242. }
  243. }
  244. const $items = fnGetItems();
  245. const $blocks = $na(".list-entries .EntryList__chunk");
  246. fnAutoScroll($items, $blocks);
  247. [].forEach.call($blocks, function ($e, i) {
  248. // 设置下边框
  249. $e.style.borderBottom = "13px solid #444";
  250. // 设置下边距
  251. $e.style.marginBottom = "13px";
  252. // 分配一个不重复的 class
  253. $e.classList.add("LessItem" + i);
  254. // $e.classList.add("LessItem");
  255. fnBuildSideBar($e);
  256. });
  257. }
  258.  
  259. // 加载完成后执行
  260. window.onload = function () {
  261. fnOnLoad();
  262. };
  263.  
  264. async function fnOnLoad() {
  265. await _sleep(1000);
  266.  
  267. // 判断加载完成
  268. if (!$n("#feedlyFrame")) {
  269. fnOnLoad();
  270. _log("fnOnLoad", "页面加载中");
  271. return;
  272. }
  273.  
  274. // 滚动条滚动时触发
  275. if ($n("#feedlyFrame") && $n("#feedlyFrame").dataset.LessItem !== "done") {
  276. $n("#feedlyFrame").dataset.LessItem = "done";
  277. // $n("#feedlyFrame").addEventListener("mouseover", fnLessItems);
  278. $n("#feedlyFrame").addEventListener("scroll", fnLessItems);
  279. _log("fnOnLoad", "列表滚动监听");
  280. }
  281. }
  282.  
  283. })();

QingJ © 2025

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