Skip to content

Commit 5f87a8d

Browse files
authored
Add files via upload
1 parent e93b090 commit 5f87a8d

3 files changed

Lines changed: 53 additions & 31 deletions

File tree

frontend/js/favorites.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,14 +420,15 @@ export function renderFavoritesList(filterText) {
420420
const builtin = _getBuiltinTags();
421421

422422
listEl.innerHTML = favorites.map((f, i) => {
423-
// 仅前 12 项应用 staggered 渐入,避免长列表动画开销
423+
// 仅前 12 项应用 staggered 渐入,后续项禁用动画,避免长列表合成层开销
424424
const delay = i < 12 ? ` style="animation-delay:${(i * 24).toFixed(0)}ms"` : '';
425+
const animClass = i < 12 ? '' : ' fav-item-no-anim';
425426
if (f.system) {
426427
const sysTags = Array.isArray(f.tags) && f.tags.length
427428
? `<div class="fav-sys-tags">${f.tags.slice(0, 4).map(t => `<span class="fav-tag-ro">#${escapeHtml(t)}</span>`).join('')}</div>`
428429
: '';
429430
return `
430-
<div class="fav-item fav-system" data-index="${i}"${delay}>
431+
<div class="fav-item fav-system${animClass}" data-index="${i}"${delay}>
431432
<div class="fav-item-main">
432433
<div class="fav-sys-head">
433434
<span class="fav-sys-name">${escapeHtml(f.name || '未命名规则')}</span>
@@ -442,7 +443,7 @@ export function renderFavoritesList(filterText) {
442443
</div>`;
443444
}
444445
return `
445-
<div class="fav-item" data-index="${i}"${delay}>
446+
<div class="fav-item${animClass}" data-index="${i}"${delay}>
446447
<div class="fav-item-main">
447448
<div class="fav-name-row">
448449
<span class="fav-name" data-name-index="${i}" title="点击编辑别名">${escapeHtml(f.name || f.baseQuery)}</span>

frontend/js/main.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,29 +1005,53 @@ document.addEventListener('DOMContentLoaded', async () => {
10051005
const tableWrapper = document.getElementById('tableWrapper');
10061006
const scrollShadow = document.getElementById('tableScrollShadow');
10071007
if (tableContainer && scrollShadow) {
1008+
let tableScrollWidth = 0;
1009+
let tableClientWidth = 0;
1010+
let scrollShadowFrame = null;
1011+
1012+
const refreshScrollShadowMetrics = () => {
1013+
tableScrollWidth = tableContainer.scrollWidth;
1014+
tableClientWidth = tableContainer.clientWidth;
1015+
};
1016+
10081017
const updateScrollShadow = () => {
10091018
// 仅在表格可见时检测
10101019
if (tableWrapper && tableWrapper.style.display === 'none') {
10111020
scrollShadow.classList.remove('visible');
10121021
return;
10131022
}
1014-
// 检测是否有横向溢出且未滚动到最右侧
1015-
const hasOverflow = tableContainer.scrollWidth > tableContainer.clientWidth + 1;
1016-
const isAtEnd = tableContainer.scrollLeft + tableContainer.clientWidth >= tableContainer.scrollWidth - 4;
1023+
// scroll 期间只读 scrollLeft,宽度指标由内容变化/窗口变化时刷新,避免强制同步布局
1024+
const hasOverflow = tableScrollWidth > tableClientWidth + 1;
1025+
const isAtEnd = tableContainer.scrollLeft + tableClientWidth >= tableScrollWidth - 4;
10171026
if (hasOverflow && !isAtEnd) {
10181027
scrollShadow.classList.add('visible');
10191028
} else {
10201029
scrollShadow.classList.remove('visible');
10211030
}
10221031
};
1023-
tableContainer.addEventListener('scroll', updateScrollShadow, { passive: true });
1032+
1033+
const scheduleScrollShadowUpdate = () => {
1034+
if (scrollShadowFrame !== null) return;
1035+
scrollShadowFrame = requestAnimationFrame(() => {
1036+
scrollShadowFrame = null;
1037+
updateScrollShadow();
1038+
});
1039+
};
1040+
1041+
const refreshAndScheduleScrollShadowUpdate = () => {
1042+
refreshScrollShadowMetrics();
1043+
scheduleScrollShadowUpdate();
1044+
};
1045+
1046+
refreshAndScheduleScrollShadowUpdate();
1047+
tableContainer.addEventListener('scroll', scheduleScrollShadowUpdate, { passive: true });
10241048
// 使用 MutationObserver 监听表格内容变化
10251049
const observer = new MutationObserver(() => {
1026-
setTimeout(updateScrollShadow, 150);
1050+
setTimeout(refreshAndScheduleScrollShadowUpdate, 150);
10271051
});
10281052
observer.observe(tableContainer, { childList: true, subtree: true, characterData: true });
10291053
// 窗口大小变化时重新检测
1030-
window.addEventListener('resize', updateScrollShadow, { passive: true });
1054+
window.addEventListener('resize', refreshAndScheduleScrollShadowUpdate, { passive: true });
10311055
}
10321056

10331057
// 点击外部关闭建议

frontend/js/results.js

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,59 +17,56 @@ export function setFetchResults(fn) {
1717
let resizing = null;
1818
let startX = 0;
1919
let startWidth = 0;
20+
let resizeCells = [];
2021

2122
function initColumnResize() {
22-
const table = document.querySelector('table');
23-
if (!table) return;
24-
25-
// 移除旧的事件监听器
26-
document.removeEventListener('mousemove', handleResize);
27-
document.removeEventListener('mouseup', stopResize);
28-
29-
// 添加新的事件监听器
30-
document.addEventListener('mousemove', handleResize);
31-
document.addEventListener('mouseup', stopResize);
23+
// 列宽拖动由 inline onmousedown 触发,mousemove/mouseup 仅在拖动期间绑定。
3224
}
3325

3426
function startResize(e, th) {
3527
e.preventDefault();
3628
e.stopPropagation();
37-
29+
3830
resizing = th;
3931
startX = e.clientX;
4032
startWidth = th.offsetWidth;
41-
33+
34+
const thIndex = Array.from(th.parentElement.children).indexOf(th);
35+
const table = th.closest('table');
36+
resizeCells = table ? Array.from(table.querySelectorAll(`tbody tr td:nth-child(${thIndex + 1})`)) : [];
37+
4238
th.querySelector('.resize-handle')?.classList.add('active');
4339
document.body.style.cursor = 'col-resize';
4440
document.body.style.userSelect = 'none';
41+
42+
document.addEventListener('mousemove', handleResize);
43+
document.addEventListener('mouseup', stopResize);
4544
}
4645

4746
function handleResize(e) {
4847
if (!resizing) return;
49-
48+
5049
const diff = e.clientX - startX;
5150
const newWidth = Math.max(80, startWidth + diff);
5251
resizing.style.width = `${newWidth}px`;
5352
resizing.style.minWidth = `${newWidth}px`;
5453
resizing.style.maxWidth = `${newWidth}px`;
55-
56-
// 同步调整对应列的 td 宽度
57-
const thIndex = Array.from(resizing.parentElement.children).indexOf(resizing);
58-
const table = resizing.closest('table');
59-
if (table) {
60-
table.querySelectorAll(`tbody tr td:nth-child(${thIndex + 1})`).forEach(td => {
61-
td.style.maxWidth = `${newWidth}px`;
62-
});
63-
}
54+
55+
resizeCells.forEach(td => {
56+
td.style.maxWidth = `${newWidth}px`;
57+
});
6458
}
6559

6660
function stopResize() {
6761
if (resizing) {
6862
resizing.querySelector('.resize-handle')?.classList.remove('active');
6963
resizing = null;
7064
}
65+
resizeCells = [];
7166
document.body.style.cursor = '';
7267
document.body.style.userSelect = '';
68+
document.removeEventListener('mousemove', handleResize);
69+
document.removeEventListener('mouseup', stopResize);
7370
}
7471

7572
// ==================== IPv6 地址检测 ====================

0 commit comments

Comments
 (0)