上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖
楼主: 木羊羽 - 

求助油猴脚本如何哔哩哔哩自动点击宽屏按钮

[复制链接]
  • TA的每日心情
    开心
    2022-11-5 13:01
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    11

    主题

    31

    回帖

    55

    积分

    荣誉开发者

    积分
    55

    荣誉开发者

    发表于 2021-2-17 14:55:19 | 显示全部楼层 | 阅读模式
    本帖最后由 木羊羽 于 2021-2-17 14:58 编辑

    我想写一个在哔哩哔哩网页自动点击宽屏按钮的油猴脚本,可是失败了,怎么才能在网页加载完毕后使用脚本,我用了window.onload好像也不行,使用while循环直接卡死,求大佬啊


    ```
    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://www.bilibili.com/video/*
    // @grant        none
    // ==/UserScript==
    window.onload = function() {
            console.log('脚本开始运行')
            while (1){
                console.log('进入循环')
                if (document.readyState === "complete") {
                    console.log('判断网页加载完成')
                    let widescreen = document.querySelector("#bilibiliPlayer > div.bilibili-player-area.video-state-blackside.video-state-pause.progress-shadow-show > div.bilibili-player-video-wrap > div.bilibili-player-video-control-wrap > div.bilibili-player-video-control > div.bilibili-player-video-control-bottom > div.bilibili-player-video-control-bottom-right > div.bilibili-player-video-btn.bilibili-player-video-btn-widescreen")
                    let widescreen_closed = document.querySelector("#bilibiliPlayer > div.bilibili-player-area.video-state-blackside.video-state-pause.progress-shadow-show > div.bilibili-player-video-wrap > div.bilibili-player-video-control-wrap > div.bilibili-player-video-control > div.bilibili-player-video-control-bottom > div.bilibili-player-video-control-bottom-right > div.bilibili-player-video-btn.bilibili-player-video-btn-widescreen.closed")
                    if (widescreen_closed==null) {
                        widescreen.click()
                    } else {
                        break
                    }
                }
            }
    };
    ```
    Snipaste_2021-02-17_14-57-46.png
  • TA的每日心情

    2025-8-16 01:57
  • 签到天数: 196 天

    [LV.7]常住居民III

    770

    主题

    6816

    回帖

    7469

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    7469

    荣誉开发者油中2周年生态建设者

    发表于 2021-2-17 15:37:46 | 显示全部楼层

    我们大概定位到元素

    图片.png

    这里可以看到存在两个button

    一个是宽屏模式,一个是退出宽屏

    切换一下可以看到是通过class样式控制哪个button显示的

    显示宽屏模式是bilibili-player-video-btn bilibili-player-video-btn-widescreen

    退出宽屏模式是bilibili-player-video-btn bilibili-player-video-btn-widescreen closed

    区别主要是closed

    所以使用clsdiv.className.indexOf('closed')==-1来进行区分(获取class名字,判断是否存在closed)

    因为window.onload是不好使的,播放器在网页加载之后才进行了某些操作

    所以说这时候一般两种方法

    1.监控dom插入

    2.定时器永远滴神

    这里为了比较方便我直接上定时器了

    源码可以参考

    https://bbs.tampermonkey.net.cn/thread-322-1-1.html

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.com/a/lihengdao666
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-11-5 13:01
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    11

    主题

    31

    回帖

    55

    积分

    荣誉开发者

    积分
    55

    荣誉开发者

    发表于 2021-2-17 18:00:10 | 显示全部楼层
    李恒道 发表于 2021-2-17 15:37
    [md]我们大概定位到元素

    ![图片.png](data/attachment/forum/202102/17/152912ipplhqgxsgy5gddy.png?image ...

    感谢大佬 成功解决 嘿嘿
    回复

    使用道具 举报

  • TA的每日心情

    2025-8-16 01:57
  • 签到天数: 196 天

    [LV.7]常住居民III

    770

    主题

    6816

    回帖

    7469

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    7469

    荣誉开发者油中2周年生态建设者

    发表于 2021-2-17 18:52:07 | 显示全部楼层
    木羊羽 发表于 2021-2-17 18:00
    感谢大佬 成功解决 嘿嘿

    小问题,哥哥有不会可以再提问,另外有小作品可以论坛发一下哦
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.com/a/lihengdao666
    回复

    使用道具 举报

    该用户从未签到

    0

    主题

    2

    回帖

    3

    积分

    助理工程师

    积分
    3
    发表于 2021-2-18 09:49:21 | 显示全部楼层
    监控dom插入这个怎么操作呢
    回复

    使用道具 举报

  • TA的每日心情

    2025-8-16 01:57
  • 签到天数: 196 天

    [LV.7]常住居民III

    770

    主题

    6816

    回帖

    7469

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    7469

    荣誉开发者油中2周年生态建设者

    发表于 2021-2-18 23:47:48 | 显示全部楼层
    神仙不在 发表于 2021-2-18 09:49
    监控dom插入这个怎么操作呢

    插入节点

      插入节点时涉及到DOMNodeInserted事件、DOMNodeInsertedIntoDocument事件及DOMSubtreeModified事件,下面将详细介绍

    DOMNodeInserted

      在使用appendChild()、replaceChild()或insertBefore()向DOM中插入节点时,首先触发DOMNodeInserted事件

      这个事件的目标是被插入的节点,而event.relatedNode属性中包含一个对父节点的引用

      在这个事件触发时,节点已经被插入到了新的父节点中。这个事件是冒泡的,因此可以在DOM的各个层次上处理它
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.com/a/lihengdao666
    回复

    使用道具 举报

  • TA的每日心情

    2025-8-16 01:57
  • 签到天数: 196 天

    [LV.7]常住居民III

    770

    主题

    6816

    回帖

    7469

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    7469

    荣誉开发者油中2周年生态建设者

    发表于 2021-2-18 23:48:09 | 显示全部楼层
    神仙不在 发表于 2021-2-18 09:49
    监控dom插入这个怎么操作呢

    ```
    <div id="box" style="height: 30px;width: 100px;">
    </div>
    <button id="btn">插入节点</button>
    <script>
    box.addEventListener('DOMNodeInserted',function(e){
        e = e || event;
        e.relatedNode.style.background = 'lightblue';
    });
    btn.onclick = function(){
        document.body.appendChild(box);
    }
    </script>
    ```
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.com/a/lihengdao666
    回复

    使用道具 举报

  • TA的每日心情

    2025-8-16 01:57
  • 签到天数: 196 天

    [LV.7]常住居民III

    770

    主题

    6816

    回帖

    7469

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    7469

    荣誉开发者油中2周年生态建设者

    发表于 2021-2-18 23:48:59 | 显示全部楼层
    神仙不在 发表于 2021-2-18 09:49
    监控dom插入这个怎么操作呢

    这个在bilibili的按钮插入里我记得也用过
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.com/a/lihengdao666
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-27 11:40
  • 签到天数: 1 天

    [LV.1]初来乍到

    8

    主题

    34

    回帖

    61

    积分

    初级工程师

    积分
    61
    发表于 2026-6-27 20:52:24 | 显示全部楼层

    从油猴教程传送过来的.哈哈哈. 之前也研究过一段时间的宽频方案. 撸了一个通用方案 . 可以参考一下

        fullscreen: /*#__PURE__*/ (() => {
            const ATTR = "data-web-fullscreen";
            incss(`[${ATTR}]{ 
                inset:0!important;
                margin:0!important;
                padding:0!important;
                position:fixed!important;
                z-index:1234567890!important;
    
                width:100dvw!important;
                height:100dvh!important;
                min-width:0!important;
                min-height:0!important;
                max-width:100dvw!important;
                max-height:100dvh!important;
    
                background:#000!important;
                transform:none!important;
                object-fit:contain!important;
            }`);
            const VIDEO_CONTAINERS = [".xgplayer", ".dplayer", ".art-video-player", ".plyr", ".jwplayer", "#video_container"].join(","); // closest 底层c++, 放心追加, 避免dom.scrollHeight 触发重绘重排
            const findContainer = (el) => {
                if (!el?.tagName || el.tagName === "IFRAME" || el.controls) return el;
                const customContainer = el.closest(VIDEO_CONTAINERS);
                if (customContainer) return customContainer;
                let parent = el.parentElement;
                const height = el.scrollHeight;
                for (let n = 2; n-- > 0 && parent && parent !== document.body && Math.abs(height - parent.scrollHeight) < 1; ) parent = parent.parentElement;
                console.log("[ parent - 考虑优化: ]", parent);
                return parent;
            };
            let parents = null; // 缓存祖先链,避免清空时重复dom查找
            const toggle = (el) => {
                if (parents) return (parents.forEach((e) => e.removeAttribute(ATTR)), (parents = null));
                for (el = findContainer(el); el?.tagName && el !== document.body; el = el.parentElement) ((parents ||= []).push(el), el.setAttribute(ATTR, ""));
            };
            const relay = () => imsg.toParent(ATTR, location.pathname + location.search);
            const isTop = window.top === window;
            imsg.on(ATTR, isTop ? (src) => toggle(document.querySelector(`iframe[src$="${src}"], iframe[src*="m3u8"]`)) : relay);
            return {
                web: (el = videoController.player) => (toggle(el), isTop || relay()),
                full: (el = videoController.player) => (document.fullscreenElement ? document.exitFullscreen() : el.parentElement.requestFullscreen()),
            };
        })(),
    
    export const imsg = /*#__PURE__*/ (() => {
        const send = (target, channel, data) => target?.postMessage && target.postMessage({ __iframeMsg__: true, channel, data }, "*");
        return {
            send,
            toParent(channel, data = {}) {
                send(window.parent, channel, data);
            },
            toTop(channel, data = {}) {
                send(window.top, channel, data);
            },
            reply(event, channel, data = {}) {
                event.source && send(event.source, channel, data);
            },
            on(channel, callback) {
                const handler = (e) => {
                    const m = e.data;
                    if (m?.__iframeMsg__ && m.channel === channel) callback(m.data, e);
                };
                window.addEventListener("message", handler);
                return () => window.removeEventListener("message", handler);
            },
        };
    })();
    
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-27 11:40
  • 签到天数: 1 天

    [LV.1]初来乍到

    8

    主题

    34

    回帖

    61

    积分

    初级工程师

    积分
    61
    发表于 2026-6-27 20:56:53 | 显示全部楼层
    然后这个el 我监听的是video 的play  document.addEventListener("play", (e) => e.target.tagName === "VIDEO" && initVideo(e.target), true); 至于为什么要用attr 不用class。.因为b站会覆盖class . 导致某些元素会失效. 导致导航栏遮挡问题, 写属性. 就可以避免这个问题
    回复

    使用道具 举报

    发表回复

    本版积分规则