AI表格用来做任务管理还不错,还可以直接在大屏上展示,让大家都知道任务完成情况,但一旦任务多了,就展示不全了,需要滚动展示。
一开始的想法是直接用浏览器插件实现,但测试发现对AI表格是无效的,自动滚动插件是对整个页面进行自动滚动,而AI表格中的一条条数据是在一个框架内的,测试了多个插件都无效,那只能通过其他方式来实现了。
首先想到的就是油猴脚本了,毕竟AI时代,直接找AI写了,经历了多轮测试后,最终的脚本如下,对部分代码不清楚的或者油猴是什么怎么装的直接扔AI里解释。
// ==UserScript==
// @name 钉钉表格自动滚动(可调时间版)
// @namespace http://tampermonkey.net/
// @version 1.0
// @description 可调整查找容器的时间
// @author User
// @match https://alidocs.dingtalk.com/aitable/share/view/*
// @match https://alidocs.dingtalk.com/*
// @grant none
// @run-at document-idle
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const CONFIG = {
scrollDelta: 200,
interval: 1000,
triggerTimes: 5,
backToTopDelay: 3000,
// ==================== 查找时间配置 ====================
pageLoadWait: 1000, // 页面已加载时的初始等待(毫秒)
containerFindWait: 5000, // 查找容器的等待时间(毫秒)
autoStartDelay: 2000, // 自动启动延迟(毫秒)
// ====================================================
};
let isRunning = false;
let scrollTimer = null;
let container = null;
let isBackToTop = false;
function log(msg) {
console.log(`[钉钉滚动版] ${msg}`);
}
// 查找容器
function findContainer() {
var el = document.querySelector('.sc-1eczdly-0.bJJkUQ.GridViewAdapter.readonly');
if (!el) {
var allDivs = Array.prototype.slice.call(document.querySelectorAll('div'));
var tallContainers = allDivs.filter(function(div) {
return div.scrollHeight > div.clientHeight + 1000;
});
if (tallContainers.length > 0) el = tallContainers[0];
}
return el;
}
// 修复容器
function fixContainer(container) {
if (!container) return false;
log('容器: ' + container.className);
log('原始: ' + container.scrollHeight + '/' + container.clientHeight);
container.style.cssText += `
overflow-y: auto !important;
overflow-x: hidden !important;
position: relative !important;
z-index: 9999 !important;
height: 800px !important;
max-height: 800px !important;
`;
container.offsetHeight;
log('修复: ' + container.scrollHeight + '/' + container.clientHeight);
return container.scrollHeight > container.clientHeight;
}
// 模拟滚轮
function simulateWheel(element, deltaY) {
const rect = element.getBoundingClientRect();
const event = new WheelEvent('wheel', {
deltaY: deltaY,
bubbles: true,
cancelable: true,
view: window,
clientX: rect.left + 100,
clientY: rect.top + 100
});
element.dispatchEvent(event);
if (element.parentElement) {
element.parentElement.dispatchEvent(event);
}
}
// 刷新页面
function refreshPage(reason) {
log('🔄 ' + reason + ',准备刷新页面...');
log('3秒后刷新...');
setTimeout(function() {
log('正在刷新页面...');
location.reload();
}, 3000);
}
// 智能回到顶部
function smartBackToTop() {
return new Promise(function(resolve) {
isBackToTop = true;
log('🔄 开始回到顶部...');
let attempts = 0;
const maxAttempts = 30;
const checkInterval = 100;
const backTimer = setInterval(function() {
attempts++;
container.scrollTop = 0;
simulateWheel(container, -CONFIG.backToTopSpeed);
if (attempts % 3 === 0) {
simulateWheel(container, -CONFIG.backToTopSpeed * 2);
}
if (container.scrollTop <= 5) {
clearInterval(backTimer);
container.scrollTop = 0;
isBackToTop = false;
log('✅ 回到顶部完成');
resolve();
} else if (attempts >= maxAttempts) {
clearInterval(backTimer);
container.scrollTop = 0;
isBackToTop = false;
log('⚠️ 强制回到顶部');
resolve();
} else if (attempts % 5 === 0) {
log('回到顶部中... ' + container.scrollTop);
}
}, checkInterval);
});
}
// 主滚动循环
function mainScrollLoop() {
if (!isRunning || isBackToTop) return;
scrollTimer = setInterval(function() {
if (!isRunning || isBackToTop) {
clearInterval(scrollTimer);
return;
}
simulateWheel(container, CONFIG.scrollDelta);
// 到达底部检测 -直接刷新
if (container.scrollTop + container.clientHeight >= container.scrollHeight - 10) {
clearInterval(scrollTimer);
refreshPage('到达底部');
return;
}
// 进度提示
if (Math.random() < 0.1) {
var progress = ((container.scrollTop / container.scrollHeight) * 100).toFixed(1);
log('滚动中... 进度: ' + progress + '%');
}
}, CONFIG.interval);
}
// 启动滚动
function startScrolling() {
if (isRunning || isBackToTop) {
log('⚠️ 滚动已在运行或正在回到顶部');
return;
}
isRunning = true;
log('🚀 开始滚动 | 高度: ' + container.scrollHeight + '/' + container.clientHeight);
let count = 0;
let lastHeight = container.scrollHeight;
// 第一阶段:触发加载
const loadInterval = setInterval(function() {
if (!isRunning || isBackToTop) {
clearInterval(loadInterval);
return;
}
simulateWheel(container, CONFIG.scrollDelta);
count++;
if (container.scrollHeight > lastHeight) {
lastHeight = container.scrollHeight;
log('✓ 数据加载中... 高度: ' + lastHeight);
}
if (count >= CONFIG.triggerTimes) {
clearInterval(loadInterval);
log('✓ 加载完成,开始正式滚动');
mainScrollLoop();
} else if (count % 2 === 0) {
log('触发加载中... ' + count + '/' + CONFIG.triggerTimes);
}
}, 600);
}
// 切换滚动状态
function toggleScroll() {
if (!container) {
log('❌ 容器未准备好');
return;
}
if (isBackToTop) {
log('⚠️ 正在回到顶部,请稍候');
return;
}
if (isRunning) {
isRunning = false;
if (scrollTimer) {
clearInterval(scrollTimer);
scrollTimer = null;
}
log('⏸️ 滚动已停止,按S键继续');
} else {
log('▶️ 开始滚动');
startScrolling();
}
}
// 主函数
function main() {
log('脚本启动 - 可调时间版');
log('查找时间配置:');
log(' - 页面已加载等待: ' + CONFIG.pageLoadWait + 'ms');
log(' - 容器查找等待: ' + CONFIG.containerFindWait + 'ms');
log(' - 自动启动延迟: ' + CONFIG.autoStartDelay + 'ms');
log('操作:S键控制启停,到达底部刷新');
setTimeout(function() {
container = findContainer();
if (!container) {
log('❌ 未找到容器');
refreshPage('找不到容器');
return;
}
if (fixContainer(container)) {
log('✅ 容器准备就绪');
// 自动启动
setTimeout(function() {
if (!isRunning) {
log('▶️ 自动启动滚动');
startScrolling();
}
}, CONFIG.autoStartDelay);
} else {
log('❌ 容器无法滚动');
refreshPage('容器无法滚动');
}
}, CONFIG.containerFindWait);
}
// S键监听
document.addEventListener('keydown', function(e) {
if (e.key.toLowerCase() === 's') {
e.preventDefault();
toggleScroll();
}
});
// 页面加载后执行
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', main);
} else {
setTimeout(main, CONFIG.pageLoadWait);
}
})();
以上可实现,打开AI表格自动执行脚本,5秒后开始滚动,并可以设置滚动速度,滚动到底后自动刷新重新执行。