b站笔记

此脚本是用于b站看视频同时在视频全屏页面记录笔记

目前为 2023-10-26 提交的版本。查看 最新版本

// ==UserScript==
// @name         b站笔记
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  此脚本是用于b站看视频同时在视频全屏页面记录笔记
// @author       tsdzs
// @match        https://www.bilibili.com/video/*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';
    let ckbtn;//查看我的笔记按钮
    let edt;//笔记文本编辑框
    let toBottomBtn
    let toTopBtn
    // let toolbar;//笔记面板里面的工具栏
    let jbj_btn;//记笔记按钮
    let isbtn = false //笔记跳转按钮是否已经添加
    let isnote = false //笔记面板是否已经打开
    // let bar

    // 将记笔记按钮转移到视频播放页面清晰度按钮左边,并绑定记笔记按钮的点击事件
    function set_jbj_btn(){
        jbj_btn = document.querySelector('#arc_toolbar_report > div.video-toolbar-right > div.video-note.video-toolbar-right-item.toolbar-right-note > div.video-note-inner')
        // 获取视频页面的清晰度按钮
        let qxd_btn = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-control-wrap > div.bpx-player-control-entity > div.bpx-player-control-bottom > div.bpx-player-control-bottom-right > div.bpx-player-ctrl-btn.bpx-player-ctrl-quality')
        jbj_btn.style.marginRight = '25px';//设置按钮右边距为25像素
        jbj_btn.style.cursor = 'pointer';//设置按钮光标为小手标识
        // jbj_btn.childNodes.style.color = '#9c75d9'
        // 为按钮子节点设置颜色
        for (let i = 0; i < jbj_btn.childNodes.length; i++) {
            let childNode = jbj_btn.childNodes[i];
            if (childNode.nodeType === Node.ELEMENT_NODE) {
                childNode.style.color = 'white';
            }
        }
        qxd_btn.parentNode.insertBefore(jbj_btn, qxd_btn)
        // 点击记笔记按钮获取查看我的笔记按钮

        jbj_btn.addEventListener("click", function () {

            setTimeout(get_ckbtn, 100);
            setTimeout(set_note_panel, 100);

            // 放置重复创建视频播放页右边小弧条
            let bar1 = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div:nth-child(2)')
            if (bar1) {
                bar1.style.display = 'block'
            }else{getbar()}


        });

    };

    //等视频首页页面加载出现jbj_btn时,才能获取到记笔记jbj-btn并设置jbj-btn相关属性和事件
    setTimeout(set_jbj_btn, 7000);

    //  创建视频播放页右边小弧形并绑定相关事件
    function getbar(){
        let bfy = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch');
        let bar = document.createElement('div');
        bar.style.cursor = 'pointer';
        bar.style.borderRadius = "100% 0 0 100%";
        bar.style.width = '60px';
        bar.style.height = '100%';
        bar.style.background = "rgba(33, 55, 61, 0.1)";
        bar.style.position = 'absolute';
        bar.style.right = '0';
        bar.style.top = '0';
        bar.addEventListener('click', (e) => {
            e.preventDefault();
            bar.style.display = "none";
            e.stopPropagation();
        });

        // 设置弧条被点击的监听事件,当点击小弧条时将小弧条关闭
        bar.addEventListener('mouseenter',()=>{
            if(!isnote){jbj_btn.click();bar.title = '点击后关闭';isnote = true;}

            //  因为鼠标移到小弧条时会打开note,此时需要设置note面板里面关闭按钮监听事件,当点击note里面的关闭按钮时设置标记,避免再次移到小弧条时,无法显示note,或重复显示
            let ckcloseBtn = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div.resizable-component.note-pc > div.note-container > div.note-header.drag-el > div.close-note')
            ckcloseBtn.addEventListener("click", ()=> {
                isnote = false
                isbtn = false
            }
                                       )
        }
                            )

        bfy.appendChild(bar);
    }


    //获取查看我的笔记按钮,绑定查看我的笔记按钮的点击事件
    function get_ckbtn() {
        ckbtn = document.querySelector('body > div.resizable-component.note-pc > div.note-container > div.note-content > div > div.list-note-operation');
        // 判断按钮是否已经添加到笔记工具栏,如果没有再添加按钮
        ckbtn.addEventListener("click", function () {
            if (!isbtn) {
                setTimeout(setBtn, 2);
                isbtn = true
            }else{toBottomBtn.style.display = "block";toTopBtn.style.display = "block"}


            let ckcloseBtn = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div.resizable-component.note-pc > div.note-container > div.note-header.drag-el > div.close-note')
            ckcloseBtn.addEventListener("click", ()=> {isnote = false;isbtn = false})

            let backBtn = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div.resizable-component.note-pc > div.note-container > div.note-header.drag-el > div.back-note-list')
            backBtn.addEventListener("click", ()=> {isbtn = false})

        })


    }
    // 将笔记面板放置在播放页面里面中心位置并绑定相关事件
    function set_note_panel(){
        let bfy = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch');
        let note = document.querySelector('body > div.resizable-component.note-pc');
        note.style.minWidth = '514px'
        note.style.width = "840px"
        note.style.height = "500px"
        note.style.zIndex = "99999"
        note.style.background = "rgba(0, 0, 100, 0.1)";
        let bfyRect = bfy.getBoundingClientRect();
        let noteRect = note.getBoundingClientRect();

        let bfyCenterX = bfyRect.left + bfyRect.width / 2;
        let bfyCenterY = bfyRect.top + bfyRect.height / 2;

        let noteWidth = noteRect.width;
        let noteHeight = noteRect.height;

        let noteLeft = bfyCenterX - noteWidth / 2;
        let noteTop = bfyCenterY - noteHeight / 2;

        note.style.left = noteLeft + 'px';
        note.style.top = noteTop + 'px';
        bfy.appendChild(note)
        note.addEventListener('click', function(event) {
            event.preventDefault();
            event.stopPropagation();

        })
        //  鼠标移到note里面设置监听事件阻止滚轮事件冒泡,防止鼠标滚轮影响视频的音量
        note.addEventListener('mouseenter', () => {note.addEventListener('wheel', (e) => {e.stopPropagation();})})

        // 检查note里面的关闭按钮的监听事件,监听关闭按钮是否被点击,如果关闭按钮被点击设置笔记存在为假,避免鼠标移到视频右边小黑狐时note无法显示在视频页,或重复显示
        let ckcloseBtn = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div.resizable-component.note-pc > div.note-container > div.note-header.drag-el > div.close-note')
        ckcloseBtn.addEventListener("click", ()=> {
            isnote = false
            isbtn = false
        }
                                   )

        if(note){isnote = true;}
    };

    // 创建两个按钮到笔记面板里面工具栏(toolbar)上面,并绑定相关事件
    function setBtn(){
        // 创建到底部按钮

        let time_flage = document.querySelector('#web-toolbar > div > span.ql-tag-btn.ql-bar-btn');
        toBottomBtn = document.createElement("button");
        // 鼠标移到按钮上时添会出现这个提示
        toBottomBtn.title = "滚动到笔记底部的文本处";
        toBottomBtn.innerHTML = '到底部';


        // 创建到顶部按钮
        toTopBtn = document.createElement("button");
        toTopBtn.title = "滚动到笔记顶部的文本处"
        toTopBtn.innerHTML = "到顶部";


        // 共享的样式设置,用于设置两个按钮的
        const sharedStyles = {
            marginLeft: "5px",
            width: "50px",
            backgroundColor: "rgb(73,148,196)",
            color: "white",
            borderRadius: "8px",
            cursor: "pointer",
            border: "none",
            boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)"
        };

        // 设置到底部按钮样式
        Object.assign(toBottomBtn.style, sharedStyles);
        // 设置到顶部按钮样式
        Object.assign(toTopBtn.style, sharedStyles);
        // 将按钮添加到对应的节点里
        time_flage.parentNode.appendChild(toBottomBtn);
        toBottomBtn.parentNode.appendChild(toTopBtn);

        let edt = document.querySelector('#bilibili-player > div > div > div.bpx-player-primary-area > div.bpx-player-video-area > div.bpx-player-video-perch > div.resizable-component.note-pc > div.note-container > div.note-content > div.note-editor > div.editor-innter.ql-container.ql-snow > div.ql-editor')
        edt.addEventListener('click',(e)=>{
            e.preventDefault()
            e.stopPropagation()

        })

        toBottomBtn.addEventListener("click",(e)=>{
            edt.scrollTo(0, edt.scrollHeight);
            e.stopPropagation();
        })

        toTopBtn.addEventListener("click",(e)=>{
            edt.scrollTo(0, 0);
            e.stopPropagation();
        })

    };
    // Your code here...
})();