fix(messages): stop skeleton sticking after full content replace

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-27 22:24:35 +08:00
1 parent 5febdb35c8
commit d71528f500
2 files changed
+13 -14

No files matched your search

+7 -14
View File
@@ -121,19 +121,10 @@
if (settings.append && state.paginateType === 'ajax_lists') {
firstAdded = appendMessagePage(result.data.content);
} else {
// 替换时保留骨架容器(参考主题 success 后只 hide() 不删除),
// 让后续翻页复用同一节点而不是回到无骨架状态。
var keep = content.querySelector('.post_ajax_loader');
// 整块替换:服务端每个 .messages-list 都自带收起态骨架,无需搬运旧节点。
// 旧节点此刻带着 .is-loading,搬进空列表 / 详情页会脱离
// `.messages-list >` 选择器,finally 摘不掉类,骨架会常驻。
content.innerHTML = result.data.content;
var nextSkeleton = content.querySelector('.post_ajax_loader');
if (keep && !nextSkeleton) {
var list = content.querySelector('.messages-list');
if (list) {
list.appendChild(keep);
} else {
content.appendChild(keep);
}
}
}
updateHeaderBadge(result.data.unread);
@@ -153,8 +144,10 @@
}).finally(function () {
root.classList.remove('is-loading');
content.removeAttribute('aria-busy');
var loader = content.querySelector('.messages-list > .post_ajax_loader');
if (loader) loader.classList.remove('is-loading');
// 收起所有残留的骨架(不限于 .messages-list 直接子节点),保证任何分支都不会卡在加载态。
content.querySelectorAll('.post_ajax_loader.is-loading').forEach(function (loader) {
loader.classList.remove('is-loading');
});
});
}
@@ -89,6 +89,12 @@ test('message centre shows a skeleton during the AJAX load-more cycle', () => {
assert.match(script, /content\.querySelector\('\.messages-list > \.post_ajax_loader'\)/);
assert.match(script, /skeleton\.classList\.add\('is-loading'\)/);
assert.match(script, /loader\.classList\.remove\('is-loading'\)/);
// Teardown must sweep every loader, not just `.messages-list >` children:
// a loader stranded outside a list (empty view / detail) would stay open.
assert.match(script, /content\.querySelectorAll\('\.post_ajax_loader\.is-loading'\)/);
// Full replacement must not carry the old (still is-loading) node across.
assert.doesNotMatch(script, /list\.appendChild\(keep\)/);
assert.doesNotMatch(script, /content\.appendChild\(keep\)/);
// Appended rows land before the skeleton so it stays flush under the list.
assert.match(script, /currentList\.insertBefore\(item, skeleton\)/);