如何在GitHub上正确模拟点击「Show more workflows...」按钮?
问题
我尝试在Firefox中使用Tampermonkey用户脚本,点击GitHub仓库(如https://github.com/opentofu/opentofu/actions)中的「Show more workflows...」按钮。但使用以下代码时:
// ==UserScript== // @name GH show all workflows // @namespace http://tampermonkey.net/ // @version 2024-10-28 // @description try to take over the world! // @author You // @match https://github.com/*/*/actions // @match https://github.com/*/*/actions/* // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com // @grant none // ==/UserScript== (function() { 'use strict'; setTimeout(function () { console.log('DEBUG1'); document.querySelector('div.ActionListItem')?.click(); console.log('DEBUG2'); }, 2000); })();
出现如下错误,无法显示剩余工作流:
Uncaught (in promise) TypeError: t.target.closest(...) is null showMore nav_list_group_element.js:74 l bind.js:73 window["__f__m2u8mn6l.cv"]/<</< GH-show-all-workflows.user.js:21 setTimeout handler*window["__f__m2u8mn6l.cv"]/<</< GH-show-all-workflows.user.js:16 window["__f__m2u8mn6l.cv"]/< GH-show-all-workflows.user.js:24 Pt actions:10 window["__f__m2u8mn6l.cv"]/< GH-show-all-workflows.user.js:1 "__f__m2u8mn6l.cv" GH-show-all-workflows.user.js:1 Pt actions:10 r actions:85 <anonymous> actions:88 _ actions:22 nav_list_group_element.js:74:32 showMore nav_list_group_element.js:74 InterpretGeneratorResume self-hosted:1420 AsyncFunctionNext self-hosted:807 (Async: async) l bind.js:73 window["__f__m2u8mn6l.cv"]/<</< GH-show-all-workflows.user.js:21 (Async: setTimeout handler) window["__f__m2u8mn6l.cv"]/<</< GH-show-all-workflows.user.js:16 window["__f__m2u8mn6l.cv"]/< GH-show-all-workflows.user.js:24 Pt actions:10 window["__f__m2u8mn6l.cv"]/< GH-show-all-workflows.user.js:1 "__f__m2u8mn6l.cv" GH-show-all-workflows.user.js:1 Pt actions:10 r actions:85 <anonymous> actions:88 _ actions:22 Pt content.js:9 h content.js:64 d content.js:67 send content.js:67 Tn content.js:16 send content.js:67 y content.js:62 is content.js:63 fo content.js:22 (Async: setTimeout handler) fo content.js:22 n content.js:2 Tn content.js:16 n content.js:1 fo content.js:22 is content.js:63 n content.js:62 InterpretGeneratorResume self-hosted:1420 next self-hosted:1341 Pt content.js:9 t content.js:10 e content.js:1 i content.js:1 n content.js:1 n content.js:1 Pt content.js:9 t content.js:1 rs content.js:62 forEach self-hosted:160 Pt content.js:9 t content.js:10 rs content.js:58 Ms content.js:77 ys content.js:77 Tn content.js:16 forEach self-hosted:160 Pt content.js:9 t content.js:10 Tn content.js:16 o content.js:72
手动点击该div可正常工作,请问如何正确模拟点击事件以实现和鼠标点击相同的效果?
解决方案
直接调用元素的click()方法缺少完整的事件上下文,导致GitHub内部代码无法找到事件目标的关联父元素。需要模拟真实的鼠标点击事件并派发,同时替换固定延时为更可靠的元素等待逻辑。
修改后的脚本代码:
// ==UserScript== // @name GH show all workflows // @namespace http://tampermonkey.net/ // @version 2024-10-28 // @description Show all workflows on GitHub Actions page // @author You // @match https://github.com/*/*/actions // @match https://github.com/*/*/actions/* // @icon https://www.google.com/s2/favicons?sz=64&domain=github.com // @grant none // ==/UserScript== (function() { 'use strict'; // 等待目标元素加载完成的工具函数 function waitForElement(selector, timeout = 5000) { return new Promise((resolve, reject) => { const checkInterval = setInterval(() => { const target = document.querySelector(selector); if (target) { clearInterval(checkInterval); resolve(target); } }, 100); setTimeout(() => { clearInterval(checkInterval); reject(new Error(`元素 ${selector} 超时未加载`)); }, timeout); }); } waitForElement('div.ActionListItem') .then(button => { // 创建符合真实用户点击的鼠标事件 const realClickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, view: window }); button.dispatchEvent(realClickEvent); console.log('已成功触发显示更多工作流'); }) .catch(err => { console.error('操作失败:', err); }); })();
核心改进点:
- 用
waitForElement替代固定setTimeout,确保元素真正渲染完成后再执行操作,避免页面加载慢导致的元素未找到问题 - 创建完整的
MouseEvent并通过dispatchEvent派发,模拟真实用户点击的事件上下文,让GitHub的内部逻辑能正常识别事件关联元素
内容的提问来源于stack exchange,提问作者piotrekkr
相关产品推荐
相关产品推荐

