From 150d7ce9c9dcb2af1aa98c8fd0e201af8373b5c5 Mon Sep 17 00:00:00 2001 From: yu <1919727607@qq.com> Date: Thu, 5 Nov 2026 10:57:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=83=E7=B4=A0=E6=8B=BE=E5=8F=96=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=92=BB=E5=85=A5=E5=AD=90=E5=85=83=E7=B4=A0:=20PageD?= =?UTF-8?q?own=20=E6=B2=BF=E9=94=81=E5=AE=9A=E5=85=83=E7=B4=A0=E5=90=91?= =?UTF-8?q?=E4=B8=8B=E8=BF=9B=E5=85=A5=E5=8D=A1=E7=89=87=E5=86=85=E9=83=A8?= =?UTF-8?q?=E5=AD=90=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 悬停时记录光标下最深元素, 锁定时把锁定元素到最深元素的子级路径并入调整链 - 场景: 淘宝搜索结果整卡为链接, 标题/价格是链接子元素, 此前只能沿祖先向上调层级选不到 --- src/main/browser/session.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/browser/session.ts b/src/main/browser/session.ts index 55b50e2..bbbf71f 100644 --- a/src/main/browser/session.ts +++ b/src/main/browser/session.ts @@ -1255,6 +1255,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => { let box = null; let badge = null; let target = null; + let deepTarget = null; let locked = false; let chain = []; let chainIndex = 0; @@ -1338,7 +1339,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => { const tag = node.tagName.toLowerCase(); const name = nodeName(node); if (locked) { - badge.textContent = '已锁定 ' + (chainIndex + 1) + '/' + chain.length + ' · ' + tag + (name ? ' · ' + name.slice(0, 42) : '') + ' · [PageUp/PageDown]调层级 [空格]确认 [Esc]取消'; + badge.textContent = '已锁定 ' + (chainIndex + 1) + '/' + chain.length + ' · ' + tag + (name ? ' · ' + name.slice(0, 42) : '') + ' · [PageUp]升 [PageDown]钻入子元素 [空格]确认 [Esc]取消'; } else { badge.textContent = '拾取 · ' + tag + (name ? ' · ' + name.slice(0, 42) : '') + ' · [空格]锁定 [Esc]取消 · 可直接翻页后继续拾取'; } @@ -1362,7 +1363,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => { } return start; }; - const firstElement = (event) => { + const deepestOf = (event) => { let deepest = null; for (const item of event.composedPath()) { if (item instanceof Element) { @@ -1371,7 +1372,10 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => { } } if (!deepest && event.target instanceof Element) deepest = event.target; - return closestInteractive(deepest); + return deepest; + }; + const firstElement = (event) => { + return closestInteractive(deepestOf(event)); }; const buildChain = (node) => { const result = []; @@ -1388,6 +1392,17 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => { locked = true; chain = buildChain(target); chainIndex = Math.max(0, chain.length - 1); + // 把光标下最深处元素到锁定元素之间的子级路径并入链,PageDown 可钻入卡片内部的标题/价格等子元素 + if (deepTarget && target !== deepTarget && target.contains(deepTarget)) { + const below = []; + let current = deepTarget; + while (current && current !== target && target.contains(current)) { + below.unshift(current); + const root = current.getRootNode(); + current = root instanceof ShadowRoot ? root.host : current.parentElement; + } + chain = chain.concat(below); + } selected = chain[chainIndex] || target; updateBox(); }; @@ -1405,6 +1420,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => { }; const move = (event) => { if (finished || locked) return; + deepTarget = deepestOf(event); target = firstElement(event); updateBox(); };