Files
workspace/code/g3soft-libs/docs/.vitepress/.tmp-model.cjs
T
2026-10-09 17:32:14 +08:00

100 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 判断当前侧栏的滚动模型:
* - 滚动条覆盖整条(含上下留白)?还是只在内容区?
* - 滚到底时,顶部留白是否跟着消失?
*/
const { spawn } = require('node:child_process')
const http = require('node:http')
const CHROME = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
const PORT = 9390
const URL = 'http://localhost:3100/ui/general/button'
function get(p) {
return new Promise((res, rej) => {
http.get({ host: '127.0.0.1', port: PORT, path: p }, (r) => {
let d = ''
r.on('data', (c) => (d += c))
r.on('end', () => res(JSON.parse(d)))
}).on('error', rej)
})
}
;(async () => {
const chrome = spawn(CHROME, [
'--headless=new', '--disable-gpu',
`--remote-debugging-port=${PORT}`,
'--user-data-dir=' + require('node:os').tmpdir() + '\\dsh-model',
'--no-first-run', '--window-size=1440,900', URL,
], { stdio: 'ignore' })
let target = null
for (let i = 0; i < 60; i++) {
try {
const l = await get('/json/list')
target = l.find((t) => t.type === 'page' && t.webSocketDebuggerUrl)
if (target) break
} catch (e) { /* retry */ }
await new Promise((r) => setTimeout(r, 500))
}
if (!target) { console.log('NO TARGET'); chrome.kill(); process.exit(1) }
const ws = new WebSocket(target.webSocketDebuggerUrl)
let id = 0
const pend = new Map()
ws.addEventListener('message', (e) => {
const m = JSON.parse(e.data)
if (m.id && pend.has(m.id)) { pend.get(m.id)(m); pend.delete(m.id) }
})
const send = (method, params = {}) => new Promise((res) => {
const i = ++id
pend.set(i, res)
ws.send(JSON.stringify({ id: i, method, params }))
})
await new Promise((r) => ws.addEventListener('open', r))
await send('Page.enable'); await send('Runtime.enable')
await new Promise((r) => setTimeout(r, 9000))
const snap = `(() => {
const sb = document.querySelector('.VPSidebar');
const nav = sb.querySelector('.nav');
const firstLink = sb.querySelector('.g3-nav-link');
const links = sb.querySelectorAll('.g3-nav-link');
const last = links[links.length - 1];
const sr = sb.getBoundingClientRect();
const c = getComputedStyle(sb);
const navR = nav.getBoundingClientRect();
return JSON.stringify({
scrollTop: Math.round(sb.scrollTop),
sidebarRect: { top: Math.round(sr.top), bottom: Math.round(sr.bottom), h: Math.round(sr.height) },
scrollbarTrack: '容器整高 ' + Math.round(sr.height) + 'px',
paddingTop: c.paddingTop,
paddingBottom: c.paddingBottom,
navTop: Math.round(navR.top),
firstLinkTop: Math.round(firstLink.getBoundingClientRect().top),
lastLinkBottom: Math.round(last.getBoundingClientRect().bottom),
// 关键:内容区相对可视区的可见范围
firstLinkVisible: firstLink.getBoundingClientRect().top >= sr.top,
}, null, 2);
})()`
console.log('=== 初始(scrollTop=0)===')
console.log((await send('Runtime.evaluate', { expression: snap, returnByValue: true })).result?.result?.value)
await send('Runtime.evaluate', {
expression: `const sb=document.querySelector('.VPSidebar'); sb.scrollTop = 200;`,
})
await new Promise((r) => setTimeout(r, 700))
console.log('\n=== scrollTop=200(看首行是否上移出顶部留白区)===')
console.log((await send('Runtime.evaluate', { expression: snap, returnByValue: true })).result?.result?.value)
await send('Runtime.evaluate', {
expression: `const sb=document.querySelector('.VPSidebar'); sb.scrollTop = sb.scrollHeight;`,
})
await new Promise((r) => setTimeout(r, 700))
console.log('\n=== 滚到底 ===')
console.log((await send('Runtime.evaluate', { expression: snap, returnByValue: true })).result?.result?.value)
ws.close(); chrome.kill(); process.exit(0)
})()