微信读书笔记列表跟随当前章节滚动

笔记列表跟随当前章节滚动

Versión del día 28/08/2023. Echa un vistazo a la versión más reciente.

// ==UserScript==
// @name         微信读书笔记列表跟随当前章节滚动
// @namespace    http://tampermonkey.net/
// @version      0.4.6
// @description  笔记列表跟随当前章节滚动
// @author       XQH
// @match        https://weread.qq.com/web/reader/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=qq.com
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';
    let noteListCssSelector = 'readerNoteList'
    let noteItemClz = 'sectionListItem_title'
    // 保存点击的上一个笔记
    let lastNote = null;
    // 笔记面板
    let notePanel = document.getElementsByClassName("readerNotePanel")[0];

    // 等待页面加载完毕
    setTimeout(function () {
        // 获取网页标题 css:.readerTopBar_title_chapter
        let title = document.querySelector(".readerTopBar_title_chapter");

        function jumpNote() {
            // 获取title文字,查找noteList中div(class:noteItemClz)子标签文字对应标签
            let titleText = title.innerText;
            let noteList = document.getElementsByClassName(noteListCssSelector)[0];
            let noteItems = noteList.getElementsByClassName(noteItemClz);
            for (let i = 0; i < noteItems.length; i++) {
                if (noteItems[i].innerText == titleText) {
                    noteList.scrollTop = noteItems[i].offsetTop - 100;
                    break;
                }
            }
            // 如果保存了上一个笔记
            if (lastNote) {
                // 滚动到笔记位置
                noteList.scrollTop = lastNote.offsetTop - 100;
            }

        }
        // 定时隐藏推广按钮
        setInterval(function () {
            // 隐藏推广按钮
            let appDownloadBtn = document.querySelector(".readerControls_item.download");
            if (appDownloadBtn) {
                appDownloadBtn.style.display = "none";
            }
            // 移动端UA下会显示打开app阅读
            let toAppBtn = document.querySelector(".readerFooter_button.blue");
            if (toAppBtn) {
                // 直接删除该元素
                toAppBtn.parentNode.removeChild(toAppBtn);
            }    
        }, 900)



        // 获取button.rbb_item
        let invoke = document.querySelector(".readerBottomBar.showShadow");



        // 为笔记列表添加点击事件



        // 为所有(sectionListItem_content noteItem_content clickable)设置点击隐藏notePanel
        let noteItems = document.getElementsByClassName("sectionListItem_content noteItem_content clickable");
        for (let i = 0; i < noteItems.length; i++) {
            noteItems[i].addEventListener("click", function () {
                // 保存到上一个笔记
                lastNote = noteItems[i];
                notePanel.style.display = "none";
                setTimeout(function () {
                    // 获取当前.app_content(div)  离顶部的距离
                    let appContent = document.querySelector(".app_content");
                    let appContentTop = Math.round(appContent.getBoundingClientRect().top);
                    // 如果top 为-75(PC) -11(MOBILE),这个高度可能受屏幕高度影响(?),需检测是否有上一页,可能需要调用翻页并重新调用跳转笔记
                    console.log("appContentTop:" + appContentTop);
                    // TODO 考虑重构代码理清逻辑
                    if (appContentTop == -75 || appContentTop == -11 || appContentTop == -12) {
                        //    则判断为上一页,调用翻页并重新调用跳转笔记
                        console.log("start to judge if it is prev page");
                        // 可以考虑每个笔记跳转时都直接切换章节再跳转避免触发翻页bug
                        setTimeout(function () {
                            // 高度无变化,判断为需要切换上一页
                            if (appContentTop == -75 || appContentTop == -11 || appContentTop == -12) {
                                // 获取 ul(clz:readerCatalog_list),
                                // 下的div(chapterItem_link chapterItem_level1)比较div中span文字
                                // 选择不与当前标题相同的item调用点击事件,再重新调用切换笔记
                                let catalogList = document.querySelector(".readerCatalog_list");
                                let catalogItems = catalogList.getElementsByClassName("chapterItem_link chapterItem_level1");
                                let titleText = title.innerText;
                                for (let i = 0; i < catalogItems.length; i++) {
                                    if (catalogItems[i].querySelector("span").innerText != titleText) {
                                        console.log("jump another chapter");
                                        catalogItems[i].dispatchEvent(
                                            new MouseEvent("click", {
                                                clientX: 1,
                                                clientY: 1,
                                            })
                                        );
                                        break;
                                    }
                                }

                                setTimeout(function () {
                                    lastNote.dispatchEvent(
                                        new MouseEvent("click", {
                                            clientX: 1,
                                            clientY: 1,
                                        })
                                    );
                                    // 跳转到上一个笔记位置
                                    setTimeout(function () {
                                        jumpNote();

                                    }, 100);
                                }, 600);
                                // console.log("start to jumpNote");
                                // localStorage.setItem("lastNotePos", i);
                                // localStorage.setItem("need_jump", true);

                            }
                        }, 1600);
                    }
                }, 100);
            });


        }

        // 如果localStorage中保存了上一个笔记
        // if (localStorage.getItem("lastNotePos")) {
        //     // 获取上一个笔记
        //     let lastPos = localStorage.getItem("lastNotePos");
        //     if (lastPos) {
        //         lastNote = noteItems[lastPos];
        //         // 获取是否需要跳转
        //         let need_jump = localStorage.getItem("need_jump");
        //         if (need_jump == "true") {
        //             lastNote.dispatchEvent(
        //                 new MouseEvent("click", {
        //                   clientX: 1,
        //                   clientY: 1,
        //                 })
        //               );
        //             // 跳转到上一个笔记位置
        //             setTimeout(function () {
        //                 jumpNote();
        //                 // 清除localStorage
        //                 localStorage.removeItem("lastNotePos");
        //                 localStorage.removeItem("need_jump");
        //             }, 100);
        //         }
        //     }

        // }

        // 底部添加笔记按钮

        if (invoke) {
            // 获取笔记图标
            let noteIcon = document.querySelector('.readerControls_item.note').querySelector('.icon');
            let backgroundImg = getComputedStyle(noteIcon).getPropertyValue("background-image");

            // 在readerBottomBar 的 rbb_item.setting(bar内第三个button) 后添加一个button
            let newInvoke = document.createElement("button");
            newInvoke.className = "rbb_item note";
            newInvoke.title = "笔记";
            newInvoke.innerHTML = '<span class="icon""></span><span class="txt">笔记</span>';

            invoke.insertBefore(newInvoke, invoke.children[3]);
            newInvoke.querySelector('.icon').style.backgroundImage = backgroundImg;
            // 设置点击事件为切换readerNotePanel的display
            newInvoke.addEventListener("click", function () {
                // 不隐藏readerBottomBar, 为readerBottomBar添加active class
                setTimeout(function () {
                    invoke.classList.add("active");

                }, 100);
                let notePanel = document.getElementsByClassName("readerNotePanel")[0];
                if (notePanel.style.display == "none") {
                    notePanel.style.display = "";
                } else {
                    notePanel.style.display = "none";
                }
                // 延迟100ms
                setTimeout(function () {
                    jumpNote();
                }, 100);
            });
        }
        // 监听点击事件(readerControls_item note)
        document.querySelector(".readerControls_item.note").addEventListener("click", function () {
            jumpNote();
        });


    }, 1500);
})();