元素拾取支持钻入子元素: PageDown 沿锁定元素向下进入卡片内部子节点
- 悬停时记录光标下最深元素, 锁定时把锁定元素到最深元素的子级路径并入调整链 - 场景: 淘宝搜索结果整卡为链接, 标题/价格是链接子元素, 此前只能沿祖先向上调层级选不到
这个提交包含在:
1 父节点
91d998b2ea
当前提交
150d7ce9c9
1 个文件已更改
+19
-3
+19
-3
@@ -1255,6 +1255,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => {
|
|||||||
let box = null;
|
let box = null;
|
||||||
let badge = null;
|
let badge = null;
|
||||||
let target = null;
|
let target = null;
|
||||||
|
let deepTarget = null;
|
||||||
let locked = false;
|
let locked = false;
|
||||||
let chain = [];
|
let chain = [];
|
||||||
let chainIndex = 0;
|
let chainIndex = 0;
|
||||||
@@ -1338,7 +1339,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => {
|
|||||||
const tag = node.tagName.toLowerCase();
|
const tag = node.tagName.toLowerCase();
|
||||||
const name = nodeName(node);
|
const name = nodeName(node);
|
||||||
if (locked) {
|
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 {
|
} else {
|
||||||
badge.textContent = '拾取 · ' + tag + (name ? ' · ' + name.slice(0, 42) : '') + ' · [空格]锁定 [Esc]取消 · 可直接翻页后继续拾取';
|
badge.textContent = '拾取 · ' + tag + (name ? ' · ' + name.slice(0, 42) : '') + ' · [空格]锁定 [Esc]取消 · 可直接翻页后继续拾取';
|
||||||
}
|
}
|
||||||
@@ -1362,7 +1363,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => {
|
|||||||
}
|
}
|
||||||
return start;
|
return start;
|
||||||
};
|
};
|
||||||
const firstElement = (event) => {
|
const deepestOf = (event) => {
|
||||||
let deepest = null;
|
let deepest = null;
|
||||||
for (const item of event.composedPath()) {
|
for (const item of event.composedPath()) {
|
||||||
if (item instanceof Element) {
|
if (item instanceof Element) {
|
||||||
@@ -1371,7 +1372,10 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!deepest && event.target instanceof Element) deepest = event.target;
|
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 buildChain = (node) => {
|
||||||
const result = [];
|
const result = [];
|
||||||
@@ -1388,6 +1392,17 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => {
|
|||||||
locked = true;
|
locked = true;
|
||||||
chain = buildChain(target);
|
chain = buildChain(target);
|
||||||
chainIndex = Math.max(0, chain.length - 1);
|
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;
|
selected = chain[chainIndex] || target;
|
||||||
updateBox();
|
updateBox();
|
||||||
};
|
};
|
||||||
@@ -1405,6 +1420,7 @@ const PICKER_BOOTSTRAP_SOURCE = `(() => {
|
|||||||
};
|
};
|
||||||
const move = (event) => {
|
const move = (event) => {
|
||||||
if (finished || locked) return;
|
if (finished || locked) return;
|
||||||
|
deepTarget = deepestOf(event);
|
||||||
target = firstElement(event);
|
target = firstElement(event);
|
||||||
updateBox();
|
updateBox();
|
||||||
};
|
};
|
||||||
|
|||||||
在新工单中引用
屏蔽一个用户